Vendor import of OpenSSH 7.2p1.
This commit is contained in:
parent
4cb2962809
commit
ff4b04e0d6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor-crypto/openssh/dist/; revision=296619 svn path=/vendor-crypto/openssh/7.2p1/; revision=296620; tag=vendor/openssh/7.2p1
72
Makefile.in
72
Makefile.in
@ -91,11 +91,11 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
|
||||
sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \
|
||||
kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
|
||||
kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \
|
||||
kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o
|
||||
kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \
|
||||
platform-pledge.o
|
||||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
|
||||
sshconnect.o sshconnect1.o sshconnect2.o mux.o \
|
||||
roaming_common.o roaming_client.o
|
||||
sshconnect.o sshconnect1.o sshconnect2.o mux.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 \
|
||||
@ -108,9 +108,9 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
|
||||
auth2-gss.o gss-serv.o gss-serv-krb5.o \
|
||||
loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
|
||||
sftp-server.o sftp-common.o \
|
||||
roaming_common.o roaming_serv.o \
|
||||
sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
|
||||
sandbox-seccomp-filter.o sandbox-capsicum.o
|
||||
sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \
|
||||
sandbox-solaris.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-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
|
||||
MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
|
||||
@ -178,14 +178,14 @@ ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o
|
||||
ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
|
||||
$(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o
|
||||
$(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o
|
||||
$(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o
|
||||
$(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
|
||||
$(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
|
||||
$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
|
||||
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o
|
||||
$(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
@ -327,10 +327,6 @@ install-files:
|
||||
$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
|
||||
$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
|
||||
$(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
|
||||
-rm -f $(DESTDIR)$(bindir)/slogin
|
||||
ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
|
||||
ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
|
||||
|
||||
install-sysconf:
|
||||
if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \
|
||||
@ -359,41 +355,19 @@ install-sysconf:
|
||||
|
||||
host-key: ssh-keygen$(EXEEXT)
|
||||
@if [ -z "$(DESTDIR)" ] ; then \
|
||||
if [ -f "$(sysconfdir)/ssh_host_key" ] ; then \
|
||||
echo "$(sysconfdir)/ssh_host_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t rsa1 -f $(sysconfdir)/ssh_host_key -N "" ; \
|
||||
fi ; \
|
||||
if [ -f $(sysconfdir)/ssh_host_dsa_key ] ; then \
|
||||
echo "$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t dsa -f $(sysconfdir)/ssh_host_dsa_key -N "" ; \
|
||||
fi ; \
|
||||
if [ -f $(sysconfdir)/ssh_host_rsa_key ] ; then \
|
||||
echo "$(sysconfdir)/ssh_host_rsa_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t rsa -f $(sysconfdir)/ssh_host_rsa_key -N "" ; \
|
||||
fi ; \
|
||||
if [ -f $(sysconfdir)/ssh_host_ed25519_key ] ; then \
|
||||
echo "$(sysconfdir)/ssh_host_ed25519_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t ed25519 -f $(sysconfdir)/ssh_host_ed25519_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 ;
|
||||
./ssh-keygen -A; \
|
||||
fi
|
||||
|
||||
host-key-force: ssh-keygen$(EXEEXT)
|
||||
./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N ""
|
||||
host-key-force: ssh-keygen$(EXEEXT) ssh$(EXEEXT)
|
||||
if ./ssh -Q protocol-version | grep '^1$$' >/dev/null; then \
|
||||
./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N ""; \
|
||||
fi
|
||||
./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N ""
|
||||
./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N ""
|
||||
./ssh-keygen -t ed25519 -f $(DESTDIR)$(sysconfdir)/ssh_host_ed25519_key -N ""
|
||||
test -z "@COMMENT_OUT_ECC@" && ./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N ""
|
||||
if ./ssh -Q key | grep ecdsa >/dev/null ; then \
|
||||
./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N ""; \
|
||||
fi
|
||||
|
||||
uninstallall: uninstall
|
||||
-rm -f $(DESTDIR)$(sysconfdir)/ssh_config
|
||||
@ -407,7 +381,6 @@ uninstallall: uninstall
|
||||
-rmdir $(DESTDIR)$(libexecdir)
|
||||
|
||||
uninstall:
|
||||
-rm -f $(DESTDIR)$(bindir)/slogin
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT)
|
||||
@ -430,7 +403,6 @@ uninstall:
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
|
||||
|
||||
regress-prep:
|
||||
[ -d `pwd`/regress ] || mkdir -p `pwd`/regress
|
||||
@ -462,6 +434,10 @@ regress/netcat$(EXEEXT): $(srcdir)/regress/netcat.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \
|
||||
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
regress/check-perm$(EXEEXT): $(srcdir)/regress/check-perm.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \
|
||||
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
UNITTESTS_TEST_HELPER_OBJS=\
|
||||
regress/unittests/test_helper/test_helper.o \
|
||||
regress/unittests/test_helper/fuzz.o
|
||||
@ -510,8 +486,7 @@ regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \
|
||||
|
||||
UNITTESTS_TEST_KEX_OBJS=\
|
||||
regress/unittests/kex/tests.o \
|
||||
regress/unittests/kex/test_kex.o \
|
||||
roaming_dummy.o
|
||||
regress/unittests/kex/test_kex.o
|
||||
|
||||
regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
@ -534,6 +509,7 @@ REGRESS_BINARIES=\
|
||||
regress/modpipe$(EXEEXT) \
|
||||
regress/setuid-allowed$(EXEEXT) \
|
||||
regress/netcat$(EXEEXT) \
|
||||
regress/check-perm$(EXEEXT) \
|
||||
regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \
|
||||
regress/unittests/sshkey/test_sshkey$(EXEEXT) \
|
||||
regress/unittests/bitmap/test_bitmap$(EXEEXT) \
|
||||
|
2
README
2
README
@ -1,4 +1,4 @@
|
||||
See http://www.openssh.com/txt/release-7.1p2 for the release notes.
|
||||
See http://www.openssh.com/txt/release-7.2p1 for the release notes.
|
||||
|
||||
Please read http://www.openssh.com/report.html for bug reporting
|
||||
instructions and note that we do not use Github for bug reporting or
|
||||
|
@ -36,6 +36,9 @@ loginrestrictions() function, in particular that the user has the
|
||||
"rlogin" attribute set. This check is not done for the root account,
|
||||
instead the PermitRootLogin setting in sshd_config is used.
|
||||
|
||||
If you are using the IBM compiler you probably want to use CC=xlc rather
|
||||
than the default of cc.
|
||||
|
||||
|
||||
Cygwin
|
||||
------
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth-bsdauth.c,v 1.13 2014/06/24 01:13:21 djm Exp $ */
|
||||
/* $OpenBSD: auth-bsdauth.c,v 1.14 2015/10/20 23:24:25 mmcc Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -103,7 +103,7 @@ bsdauth_respond(void *ctx, u_int numresponses, char **responses)
|
||||
if (!authctxt->valid)
|
||||
return -1;
|
||||
|
||||
if (authctxt->as == 0)
|
||||
if (authctxt->as == NULL)
|
||||
error("bsdauth_respond: no bsd auth session");
|
||||
|
||||
if (numresponses != 1)
|
||||
|
@ -1,8 +1,8 @@
|
||||
/* $OpenBSD: auth-krb5.c,v 1.20 2013/07/20 01:55:13 djm Exp $ */
|
||||
/* $OpenBSD: auth-krb5.c,v 1.21 2016/01/27 06:44:58 djm Exp $ */
|
||||
/*
|
||||
* Kerberos v5 authentication and ticket-passing routines.
|
||||
*
|
||||
* $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $
|
||||
* From: FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2002 Daniel Kouril. All rights reserved.
|
||||
|
117
auth-options.c
117
auth-options.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth-options.c,v 1.68 2015/07/03 03:43:18 djm Exp $ */
|
||||
/* $OpenBSD: auth-options.c,v 1.70 2015/12/10 17:08:40 mmcc Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -75,18 +75,44 @@ auth_clear_options(void)
|
||||
free(ce->s);
|
||||
free(ce);
|
||||
}
|
||||
if (forced_command) {
|
||||
free(forced_command);
|
||||
forced_command = NULL;
|
||||
}
|
||||
if (authorized_principals) {
|
||||
free(authorized_principals);
|
||||
authorized_principals = NULL;
|
||||
}
|
||||
free(forced_command);
|
||||
forced_command = NULL;
|
||||
free(authorized_principals);
|
||||
authorized_principals = NULL;
|
||||
forced_tun_device = -1;
|
||||
channel_clear_permitted_opens();
|
||||
}
|
||||
|
||||
/*
|
||||
* Match flag 'opt' in *optsp, and if allow_negate is set then also match
|
||||
* 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0
|
||||
* if negated option matches.
|
||||
* If the option or negated option matches, then *optsp is updated to
|
||||
* point to the first character after the option and, if 'msg' is not NULL
|
||||
* then a message based on it added via auth_debug_add().
|
||||
*/
|
||||
static int
|
||||
match_flag(const char *opt, int allow_negate, char **optsp, const char *msg)
|
||||
{
|
||||
size_t opt_len = strlen(opt);
|
||||
char *opts = *optsp;
|
||||
int negate = 0;
|
||||
|
||||
if (allow_negate && strncasecmp(opts, "no-", 3) == 0) {
|
||||
opts += 3;
|
||||
negate = 1;
|
||||
}
|
||||
if (strncasecmp(opts, opt, opt_len) == 0) {
|
||||
*optsp = opts + opt_len;
|
||||
if (msg != NULL) {
|
||||
auth_debug_add("%s %s.", msg,
|
||||
negate ? "disabled" : "enabled");
|
||||
}
|
||||
return negate ? 0 : 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* return 1 if access is granted, 0 if not.
|
||||
* side effect: sets key option flags
|
||||
@ -95,7 +121,7 @@ int
|
||||
auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
{
|
||||
const char *cp;
|
||||
int i;
|
||||
int i, r;
|
||||
|
||||
/* reset options */
|
||||
auth_clear_options();
|
||||
@ -104,52 +130,48 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
return 1;
|
||||
|
||||
while (*opts && *opts != ' ' && *opts != '\t') {
|
||||
cp = "cert-authority";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
key_is_cert_authority = 1;
|
||||
opts += strlen(cp);
|
||||
if ((r = match_flag("cert-authority", 0, &opts, NULL)) != -1) {
|
||||
key_is_cert_authority = r;
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-port-forwarding";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
auth_debug_add("Port forwarding disabled.");
|
||||
if ((r = match_flag("restrict", 0, &opts, NULL)) != -1) {
|
||||
auth_debug_add("Key is restricted.");
|
||||
no_port_forwarding_flag = 1;
|
||||
opts += strlen(cp);
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-agent-forwarding";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
auth_debug_add("Agent forwarding disabled.");
|
||||
no_agent_forwarding_flag = 1;
|
||||
opts += strlen(cp);
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-X11-forwarding";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
auth_debug_add("X11 forwarding disabled.");
|
||||
no_x11_forwarding_flag = 1;
|
||||
opts += strlen(cp);
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-pty";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
auth_debug_add("Pty allocation disabled.");
|
||||
no_pty_flag = 1;
|
||||
opts += strlen(cp);
|
||||
no_user_rc = 1;
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-user-rc";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
auth_debug_add("User rc file execution disabled.");
|
||||
no_user_rc = 1;
|
||||
opts += strlen(cp);
|
||||
if ((r = match_flag("port-forwarding", 1, &opts,
|
||||
"Port forwarding")) != -1) {
|
||||
no_port_forwarding_flag = r != 1;
|
||||
goto next_option;
|
||||
}
|
||||
if ((r = match_flag("agent-forwarding", 1, &opts,
|
||||
"Agent forwarding")) != -1) {
|
||||
no_agent_forwarding_flag = r != 1;
|
||||
goto next_option;
|
||||
}
|
||||
if ((r = match_flag("x11-forwarding", 1, &opts,
|
||||
"X11 forwarding")) != -1) {
|
||||
no_x11_forwarding_flag = r != 1;
|
||||
goto next_option;
|
||||
}
|
||||
if ((r = match_flag("pty", 1, &opts,
|
||||
"PTY allocation")) != -1) {
|
||||
no_pty_flag = r != 1;
|
||||
goto next_option;
|
||||
}
|
||||
if ((r = match_flag("user-rc", 1, &opts,
|
||||
"User rc execution")) != -1) {
|
||||
no_user_rc = r != 1;
|
||||
goto next_option;
|
||||
}
|
||||
cp = "command=\"";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
opts += strlen(cp);
|
||||
if (forced_command != NULL)
|
||||
free(forced_command);
|
||||
free(forced_command);
|
||||
forced_command = xmalloc(strlen(opts) + 1);
|
||||
i = 0;
|
||||
while (*opts) {
|
||||
@ -179,8 +201,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
cp = "principals=\"";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
opts += strlen(cp);
|
||||
if (authorized_principals != NULL)
|
||||
free(authorized_principals);
|
||||
free(authorized_principals);
|
||||
authorized_principals = xmalloc(strlen(opts) + 1);
|
||||
i = 0;
|
||||
while (*opts) {
|
||||
@ -566,8 +587,7 @@ parse_option_list(struct sshbuf *oblob, struct passwd *pw,
|
||||
free(*cert_forced_command);
|
||||
*cert_forced_command = NULL;
|
||||
}
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
free(name);
|
||||
sshbuf_free(data);
|
||||
sshbuf_free(c);
|
||||
return ret;
|
||||
@ -611,8 +631,7 @@ auth_cert_options(struct sshkey *k, struct passwd *pw)
|
||||
no_user_rc |= cert_no_user_rc;
|
||||
/* CA-specified forced command supersedes key option */
|
||||
if (cert_forced_command != NULL) {
|
||||
if (forced_command != NULL)
|
||||
free(forced_command);
|
||||
free(forced_command);
|
||||
forced_command = cert_forced_command;
|
||||
}
|
||||
return 0;
|
||||
|
@ -45,7 +45,8 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
|
||||
/* Based on FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
4
auth.h
4
auth.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth.h,v 1.84 2015/05/08 06:41:56 djm Exp $ */
|
||||
/* $OpenBSD: auth.h,v 1.86 2015/12/04 16:41:28 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -209,7 +209,7 @@ Key *get_hostkey_private_by_type(int, int, struct ssh *);
|
||||
int get_hostkey_index(Key *, int, struct ssh *);
|
||||
int ssh1_session_key(BIGNUM *);
|
||||
int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *,
|
||||
const u_char *, size_t, u_int);
|
||||
const u_char *, size_t, const char *, u_int);
|
||||
|
||||
/* debug messages during authentication */
|
||||
void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.53 2015/06/15 18:44:22 jsing Exp $ */
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.55 2016/01/27 00:53:12 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -79,19 +79,19 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
{
|
||||
Buffer b;
|
||||
Key *key = NULL;
|
||||
char *pkalg, *userstyle;
|
||||
char *pkalg, *userstyle, *fp = NULL;
|
||||
u_char *pkblob, *sig;
|
||||
u_int alen, blen, slen;
|
||||
int have_sig, pktype;
|
||||
int authenticated = 0;
|
||||
|
||||
if (!authctxt->valid) {
|
||||
debug2("userauth_pubkey: disabled because of invalid user");
|
||||
debug2("%s: disabled because of invalid user", __func__);
|
||||
return 0;
|
||||
}
|
||||
have_sig = packet_get_char();
|
||||
if (datafellows & SSH_BUG_PKAUTH) {
|
||||
debug2("userauth_pubkey: SSH_BUG_PKAUTH");
|
||||
debug2("%s: SSH_BUG_PKAUTH", __func__);
|
||||
/* no explicit pkalg given */
|
||||
pkblob = packet_get_string(&blen);
|
||||
buffer_init(&b);
|
||||
@ -106,18 +106,18 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
pktype = key_type_from_name(pkalg);
|
||||
if (pktype == KEY_UNSPEC) {
|
||||
/* this is perfectly legal */
|
||||
logit("userauth_pubkey: unsupported public key algorithm: %s",
|
||||
pkalg);
|
||||
logit("%s: unsupported public key algorithm: %s",
|
||||
__func__, pkalg);
|
||||
goto done;
|
||||
}
|
||||
key = key_from_blob(pkblob, blen);
|
||||
if (key == NULL) {
|
||||
error("userauth_pubkey: cannot decode key: %s", pkalg);
|
||||
error("%s: cannot decode key: %s", __func__, pkalg);
|
||||
goto done;
|
||||
}
|
||||
if (key->type != pktype) {
|
||||
error("userauth_pubkey: type mismatch for decoded key "
|
||||
"(received %d, expected %d)", key->type, pktype);
|
||||
error("%s: type mismatch for decoded key "
|
||||
"(received %d, expected %d)", __func__, key->type, pktype);
|
||||
goto done;
|
||||
}
|
||||
if (key_type_plain(key->type) == KEY_RSA &&
|
||||
@ -126,6 +126,7 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
"signature scheme");
|
||||
goto done;
|
||||
}
|
||||
fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);
|
||||
if (auth2_userkey_already_used(authctxt, key)) {
|
||||
logit("refusing previously-used %s key", key_type(key));
|
||||
goto done;
|
||||
@ -138,6 +139,8 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
}
|
||||
|
||||
if (have_sig) {
|
||||
debug3("%s: have signature for %s %s",
|
||||
__func__, sshkey_type(key), fp);
|
||||
sig = packet_get_string(&slen);
|
||||
packet_check_eom();
|
||||
buffer_init(&b);
|
||||
@ -183,7 +186,8 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
buffer_free(&b);
|
||||
free(sig);
|
||||
} else {
|
||||
debug("test whether pkalg/pkblob are acceptable");
|
||||
debug("%s: test whether pkalg/pkblob are acceptable for %s %s",
|
||||
__func__, sshkey_type(key), fp);
|
||||
packet_check_eom();
|
||||
|
||||
/* XXX fake reply and always send PK_OK ? */
|
||||
@ -206,11 +210,12 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
if (authenticated != 1)
|
||||
auth_clear_options();
|
||||
done:
|
||||
debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
|
||||
debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg);
|
||||
if (key != NULL)
|
||||
key_free(key);
|
||||
free(pkalg);
|
||||
free(pkblob);
|
||||
free(fp);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
@ -796,8 +801,9 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
|
||||
free(fp);
|
||||
continue;
|
||||
}
|
||||
verbose("Accepted certificate ID \"%s\" "
|
||||
verbose("Accepted certificate ID \"%s\" (serial %llu) "
|
||||
"signed by %s CA %s via %s", key->cert->key_id,
|
||||
(unsigned long long)key->cert->serial,
|
||||
key_type(found), fp, file);
|
||||
free(fp);
|
||||
found_key = 1;
|
||||
@ -875,8 +881,10 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
|
||||
if (auth_cert_options(key, pw) != 0)
|
||||
goto out;
|
||||
|
||||
verbose("Accepted certificate ID \"%s\" signed by %s CA %s via %s",
|
||||
key->cert->key_id, key_type(key->cert->signature_key), ca_fp,
|
||||
verbose("Accepted certificate ID \"%s\" (serial %llu) signed by "
|
||||
"%s CA %s via %s", key->cert->key_id,
|
||||
(unsigned long long)key->cert->serial,
|
||||
key_type(key->cert->signature_key), ca_fp,
|
||||
options.trusted_user_ca_keys);
|
||||
ret = 1;
|
||||
|
||||
|
20
authfd.c
20
authfd.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfd.c,v 1.98 2015/07/03 03:43:18 djm Exp $ */
|
||||
/* $OpenBSD: authfd.c,v 1.100 2015/12/04 16:41:28 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -426,11 +426,24 @@ ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* encode signature algoritm in flag bits, so we can keep the msg format */
|
||||
static u_int
|
||||
agent_encode_alg(struct sshkey *key, const char *alg)
|
||||
{
|
||||
if (alg != NULL && key->type == KEY_RSA) {
|
||||
if (strcmp(alg, "rsa-sha2-256") == 0)
|
||||
return SSH_AGENT_RSA_SHA2_256;
|
||||
else if (strcmp(alg, "rsa-sha2-512") == 0)
|
||||
return SSH_AGENT_RSA_SHA2_512;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ask agent to sign data, returns err.h code on error, 0 on success */
|
||||
int
|
||||
ssh_agent_sign(int sock, struct sshkey *key,
|
||||
u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, u_int compat)
|
||||
const u_char *data, size_t datalen, const char *alg, u_int compat)
|
||||
{
|
||||
struct sshbuf *msg;
|
||||
u_char *blob = NULL, type;
|
||||
@ -449,12 +462,13 @@ ssh_agent_sign(int sock, struct sshkey *key,
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
|
||||
goto out;
|
||||
flags |= agent_encode_alg(key, alg);
|
||||
if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
|
||||
(r = sshbuf_put_string(msg, blob, blen)) != 0 ||
|
||||
(r = sshbuf_put_string(msg, data, datalen)) != 0 ||
|
||||
(r = sshbuf_put_u32(msg, flags)) != 0)
|
||||
goto out;
|
||||
if ((r = ssh_request_reply(sock, msg, msg) != 0))
|
||||
if ((r = ssh_request_reply(sock, msg, msg)) != 0)
|
||||
goto out;
|
||||
if ((r = sshbuf_get_u8(msg, &type)) != 0)
|
||||
goto out;
|
||||
|
6
authfd.h
6
authfd.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfd.h,v 1.38 2015/01/14 20:05:27 djm Exp $ */
|
||||
/* $OpenBSD: authfd.h,v 1.39 2015/12/04 16:41:28 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -41,7 +41,7 @@ int ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
|
||||
u_char session_id[16], u_char response[16]);
|
||||
int ssh_agent_sign(int sock, struct sshkey *key,
|
||||
u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, u_int compat);
|
||||
const u_char *data, size_t datalen, const char *alg, u_int compat);
|
||||
|
||||
/* Messages for the authentication agent connection. */
|
||||
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
||||
@ -86,5 +86,7 @@ int ssh_agent_sign(int sock, struct sshkey *key,
|
||||
#define SSH_COM_AGENT2_FAILURE 102
|
||||
|
||||
#define SSH_AGENT_OLD_SIGNATURE 0x01
|
||||
#define SSH_AGENT_RSA_SHA2_256 0x02
|
||||
#define SSH_AGENT_RSA_SHA2_512 0x04
|
||||
|
||||
#endif /* AUTHFD_H */
|
||||
|
27
authfile.c
27
authfile.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfile.c,v 1.116 2015/07/09 09:49:46 markus Exp $ */
|
||||
/* $OpenBSD: authfile.c,v 1.120 2015/12/11 04:21:11 mmcc Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -243,8 +243,7 @@ sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
if (buffer != NULL)
|
||||
sshbuf_free(buffer);
|
||||
sshbuf_free(buffer);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -272,14 +271,13 @@ sshkey_load_private(const char *filename, const char *passphrase,
|
||||
goto out;
|
||||
}
|
||||
if ((r = sshkey_load_file(fd, buffer)) != 0 ||
|
||||
(r = sshkey_parse_private_fileblob(buffer, passphrase, filename,
|
||||
keyp, commentp)) != 0)
|
||||
(r = sshkey_parse_private_fileblob(buffer, passphrase, keyp,
|
||||
commentp)) != 0)
|
||||
goto out;
|
||||
r = 0;
|
||||
out:
|
||||
close(fd);
|
||||
if (buffer != NULL)
|
||||
sshbuf_free(buffer);
|
||||
sshbuf_free(buffer);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -426,10 +424,8 @@ sshkey_load_cert(const char *filename, struct sshkey **keyp)
|
||||
r = 0;
|
||||
|
||||
out:
|
||||
if (file != NULL)
|
||||
free(file);
|
||||
if (pub != NULL)
|
||||
sshkey_free(pub);
|
||||
free(file);
|
||||
sshkey_free(pub);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -474,10 +470,8 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
|
||||
*keyp = key;
|
||||
key = NULL;
|
||||
out:
|
||||
if (key != NULL)
|
||||
sshkey_free(key);
|
||||
if (cert != NULL)
|
||||
sshkey_free(cert);
|
||||
sshkey_free(key);
|
||||
sshkey_free(cert);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -538,8 +532,7 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type,
|
||||
}
|
||||
r = SSH_ERR_KEY_NOT_FOUND;
|
||||
out:
|
||||
if (pub != NULL)
|
||||
sshkey_free(pub);
|
||||
sshkey_free(pub);
|
||||
fclose(f);
|
||||
return r;
|
||||
}
|
||||
|
16
channels.c
16
channels.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: channels.c,v 1.347 2015/07/01 02:26:31 djm Exp $ */
|
||||
/* $OpenBSD: channels.c,v 1.349 2016/02/05 13:28:19 naddy Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -662,7 +662,7 @@ channel_open_message(void)
|
||||
case SSH_CHANNEL_INPUT_DRAINING:
|
||||
case SSH_CHANNEL_OUTPUT_DRAINING:
|
||||
snprintf(buf, sizeof buf,
|
||||
" #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cc %d)\r\n",
|
||||
" #%d %.300s (t%d r%d i%u/%d o%u/%d fd %d/%d cc %d)\r\n",
|
||||
c->self, c->remote_name,
|
||||
c->type, c->remote_id,
|
||||
c->istate, buffer_len(&c->input),
|
||||
@ -1896,13 +1896,13 @@ read_mux(Channel *c, u_int need)
|
||||
if (buffer_len(&c->input) < need) {
|
||||
rlen = need - buffer_len(&c->input);
|
||||
len = read(c->rfd, buf, MIN(rlen, CHAN_RBUF));
|
||||
if (len < 0 && (errno == EINTR || errno == EAGAIN))
|
||||
return buffer_len(&c->input);
|
||||
if (len <= 0) {
|
||||
if (errno != EINTR && errno != EAGAIN) {
|
||||
debug2("channel %d: ctl read<=0 rfd %d len %d",
|
||||
c->self, c->rfd, len);
|
||||
chan_read_failed(c);
|
||||
return 0;
|
||||
}
|
||||
debug2("channel %d: ctl read<=0 rfd %d len %d",
|
||||
c->self, c->rfd, len);
|
||||
chan_read_failed(c);
|
||||
return 0;
|
||||
} else
|
||||
buffer_append(&c->input, buf, len);
|
||||
}
|
||||
|
5
cipher.c
5
cipher.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cipher.c,v 1.100 2015/01/14 10:29:45 djm Exp $ */
|
||||
/* $OpenBSD: cipher.c,v 1.101 2015/12/10 17:08:40 mmcc Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -353,8 +353,7 @@ cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
|
||||
if (cipher->discard_len > 0) {
|
||||
if ((junk = malloc(cipher->discard_len)) == NULL ||
|
||||
(discard = malloc(cipher->discard_len)) == NULL) {
|
||||
if (junk != NULL)
|
||||
free(junk);
|
||||
free(junk);
|
||||
ret = SSH_ERR_ALLOC_FAIL;
|
||||
goto bad;
|
||||
}
|
||||
|
195
clientloop.c
195
clientloop.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: clientloop.c,v 1.275 2015/07/10 06:21:53 markus Exp $ */
|
||||
/* $OpenBSD: clientloop.c,v 1.284 2016/02/08 10:57:07 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -111,7 +111,6 @@
|
||||
#include "sshpty.h"
|
||||
#include "match.h"
|
||||
#include "msg.h"
|
||||
#include "roaming.h"
|
||||
#include "ssherr.h"
|
||||
#include "hostfile.h"
|
||||
|
||||
@ -169,8 +168,6 @@ static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
|
||||
static void client_init_dispatch(void);
|
||||
int session_ident = -1;
|
||||
|
||||
int session_resumed = 0;
|
||||
|
||||
/* Track escape per proto2 channel */
|
||||
struct escape_filter_ctx {
|
||||
int escape_pending;
|
||||
@ -288,6 +285,9 @@ client_x11_display_valid(const char *display)
|
||||
{
|
||||
size_t i, dlen;
|
||||
|
||||
if (display == NULL)
|
||||
return 0;
|
||||
|
||||
dlen = strlen(display);
|
||||
for (i = 0; i < dlen; i++) {
|
||||
if (!isalnum((u_char)display[i]) &&
|
||||
@ -301,35 +301,34 @@ client_x11_display_valid(const char *display)
|
||||
|
||||
#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
|
||||
#define X11_TIMEOUT_SLACK 60
|
||||
void
|
||||
int
|
||||
client_x11_get_proto(const char *display, const char *xauth_path,
|
||||
u_int trusted, u_int timeout, char **_proto, char **_data)
|
||||
{
|
||||
char cmd[1024];
|
||||
char line[512];
|
||||
char xdisplay[512];
|
||||
char cmd[1024], line[512], xdisplay[512];
|
||||
char xauthfile[PATH_MAX], xauthdir[PATH_MAX];
|
||||
static char proto[512], data[512];
|
||||
FILE *f;
|
||||
int got_data = 0, generated = 0, do_unlink = 0, i;
|
||||
char *xauthdir, *xauthfile;
|
||||
int got_data = 0, generated = 0, do_unlink = 0, i, r;
|
||||
struct stat st;
|
||||
u_int now, x11_timeout_real;
|
||||
|
||||
xauthdir = xauthfile = NULL;
|
||||
*_proto = proto;
|
||||
*_data = data;
|
||||
proto[0] = data[0] = '\0';
|
||||
proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0';
|
||||
|
||||
if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) {
|
||||
if (!client_x11_display_valid(display)) {
|
||||
if (display != NULL)
|
||||
logit("DISPLAY \"%s\" invalid; disabling X11 forwarding",
|
||||
display);
|
||||
return -1;
|
||||
}
|
||||
if (xauth_path != NULL && stat(xauth_path, &st) == -1) {
|
||||
debug("No xauth program.");
|
||||
} else if (!client_x11_display_valid(display)) {
|
||||
logit("DISPLAY '%s' invalid, falling back to fake xauth data",
|
||||
display);
|
||||
} else {
|
||||
if (display == NULL) {
|
||||
debug("x11_get_proto: DISPLAY not set");
|
||||
return;
|
||||
}
|
||||
xauth_path = NULL;
|
||||
}
|
||||
|
||||
if (xauth_path != NULL) {
|
||||
/*
|
||||
* Handle FamilyLocal case where $DISPLAY does
|
||||
* not match an authorization entry. For this we
|
||||
@ -338,45 +337,60 @@ client_x11_get_proto(const char *display, const char *xauth_path,
|
||||
* is not perfect.
|
||||
*/
|
||||
if (strncmp(display, "localhost:", 10) == 0) {
|
||||
snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
|
||||
display + 10);
|
||||
if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
|
||||
display + 10)) < 0 ||
|
||||
(size_t)r >= sizeof(xdisplay)) {
|
||||
error("%s: display name too long", __func__);
|
||||
return -1;
|
||||
}
|
||||
display = xdisplay;
|
||||
}
|
||||
if (trusted == 0) {
|
||||
xauthdir = xmalloc(PATH_MAX);
|
||||
xauthfile = xmalloc(PATH_MAX);
|
||||
mktemp_proto(xauthdir, PATH_MAX);
|
||||
/*
|
||||
* Generate an untrusted X11 auth cookie.
|
||||
*
|
||||
* The authentication cookie should briefly outlive
|
||||
* ssh's willingness to forward X11 connections to
|
||||
* avoid nasty fail-open behaviour in the X server.
|
||||
*/
|
||||
mktemp_proto(xauthdir, sizeof(xauthdir));
|
||||
if (mkdtemp(xauthdir) == NULL) {
|
||||
error("%s: mkdtemp: %s",
|
||||
__func__, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
do_unlink = 1;
|
||||
if ((r = snprintf(xauthfile, sizeof(xauthfile),
|
||||
"%s/xauthfile", xauthdir)) < 0 ||
|
||||
(size_t)r >= sizeof(xauthfile)) {
|
||||
error("%s: xauthfile path too long", __func__);
|
||||
unlink(xauthfile);
|
||||
rmdir(xauthdir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK)
|
||||
x11_timeout_real = UINT_MAX;
|
||||
else
|
||||
x11_timeout_real = timeout + X11_TIMEOUT_SLACK;
|
||||
if (mkdtemp(xauthdir) != NULL) {
|
||||
do_unlink = 1;
|
||||
snprintf(xauthfile, PATH_MAX, "%s/xauthfile",
|
||||
xauthdir);
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
"%s -f %s generate %s " SSH_X11_PROTO
|
||||
" untrusted timeout %u 2>" _PATH_DEVNULL,
|
||||
xauth_path, xauthfile, display,
|
||||
x11_timeout_real);
|
||||
debug2("x11_get_proto: %s", cmd);
|
||||
if (x11_refuse_time == 0) {
|
||||
now = monotime() + 1;
|
||||
if (UINT_MAX - timeout < now)
|
||||
x11_refuse_time = UINT_MAX;
|
||||
else
|
||||
x11_refuse_time = now + timeout;
|
||||
channel_set_x11_refuse_time(
|
||||
x11_refuse_time);
|
||||
}
|
||||
if (system(cmd) == 0)
|
||||
generated = 1;
|
||||
if ((r = snprintf(cmd, sizeof(cmd),
|
||||
"%s -f %s generate %s " SSH_X11_PROTO
|
||||
" untrusted timeout %u 2>" _PATH_DEVNULL,
|
||||
xauth_path, xauthfile, display,
|
||||
x11_timeout_real)) < 0 ||
|
||||
(size_t)r >= sizeof(cmd))
|
||||
fatal("%s: cmd too long", __func__);
|
||||
debug2("%s: %s", __func__, cmd);
|
||||
if (x11_refuse_time == 0) {
|
||||
now = monotime() + 1;
|
||||
if (UINT_MAX - timeout < now)
|
||||
x11_refuse_time = UINT_MAX;
|
||||
else
|
||||
x11_refuse_time = now + timeout;
|
||||
channel_set_x11_refuse_time(x11_refuse_time);
|
||||
}
|
||||
if (system(cmd) == 0)
|
||||
generated = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -398,17 +412,20 @@ client_x11_get_proto(const char *display, const char *xauth_path,
|
||||
got_data = 1;
|
||||
if (f)
|
||||
pclose(f);
|
||||
} else
|
||||
error("Warning: untrusted X11 forwarding setup failed: "
|
||||
"xauth key data not generated");
|
||||
}
|
||||
}
|
||||
|
||||
if (do_unlink) {
|
||||
unlink(xauthfile);
|
||||
rmdir(xauthdir);
|
||||
}
|
||||
free(xauthdir);
|
||||
free(xauthfile);
|
||||
|
||||
/* Don't fall back to fake X11 data for untrusted forwarding */
|
||||
if (!trusted && !got_data) {
|
||||
error("Warning: untrusted X11 forwarding setup failed: "
|
||||
"xauth key data not generated");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we didn't get authentication data, just make up some
|
||||
@ -432,6 +449,8 @@ client_x11_get_proto(const char *display, const char *xauth_path,
|
||||
rnd >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -735,7 +754,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
|
||||
static void
|
||||
client_process_net_input(fd_set *readset)
|
||||
{
|
||||
int len, cont = 0;
|
||||
int len;
|
||||
char buf[SSH_IOBUFSZ];
|
||||
|
||||
/*
|
||||
@ -744,8 +763,8 @@ client_process_net_input(fd_set *readset)
|
||||
*/
|
||||
if (FD_ISSET(connection_in, readset)) {
|
||||
/* Read as much as possible. */
|
||||
len = roaming_read(connection_in, buf, sizeof(buf), &cont);
|
||||
if (len == 0 && cont == 0) {
|
||||
len = read(connection_in, buf, sizeof(buf));
|
||||
if (len == 0) {
|
||||
/*
|
||||
* Received EOF. The remote host has closed the
|
||||
* connection.
|
||||
@ -1483,13 +1502,43 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
||||
{
|
||||
fd_set *readset = NULL, *writeset = NULL;
|
||||
double start_time, total_time;
|
||||
int r, max_fd = 0, max_fd2 = 0, len, rekeying = 0;
|
||||
int r, max_fd = 0, max_fd2 = 0, len;
|
||||
u_int64_t ibytes, obytes;
|
||||
u_int nalloc = 0;
|
||||
char buf[100];
|
||||
|
||||
debug("Entering interactive session.");
|
||||
|
||||
if (options.control_master &&
|
||||
! option_clear_or_none(options.control_path)) {
|
||||
debug("pledge: id");
|
||||
if (pledge("stdio rpath wpath cpath unix inet dns proc exec id tty",
|
||||
NULL) == -1)
|
||||
fatal("%s pledge(): %s", __func__, strerror(errno));
|
||||
|
||||
} else if (options.forward_x11 || options.permit_local_command) {
|
||||
debug("pledge: exec");
|
||||
if (pledge("stdio rpath wpath cpath unix inet dns proc exec tty",
|
||||
NULL) == -1)
|
||||
fatal("%s pledge(): %s", __func__, strerror(errno));
|
||||
|
||||
} else if (options.update_hostkeys) {
|
||||
debug("pledge: filesystem full");
|
||||
if (pledge("stdio rpath wpath cpath unix inet dns proc tty",
|
||||
NULL) == -1)
|
||||
fatal("%s pledge(): %s", __func__, strerror(errno));
|
||||
|
||||
} else if (! option_clear_or_none(options.proxy_command)) {
|
||||
debug("pledge: proc");
|
||||
if (pledge("stdio cpath unix inet dns proc tty", NULL) == -1)
|
||||
fatal("%s pledge(): %s", __func__, strerror(errno));
|
||||
|
||||
} else {
|
||||
debug("pledge: network");
|
||||
if (pledge("stdio unix inet dns tty", NULL) == -1)
|
||||
fatal("%s pledge(): %s", __func__, strerror(errno));
|
||||
}
|
||||
|
||||
start_time = get_current_time();
|
||||
|
||||
/* Initialize variables. */
|
||||
@ -1568,10 +1617,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
||||
if (compat20 && session_closed && !channel_still_open())
|
||||
break;
|
||||
|
||||
rekeying = (active_state->kex != NULL && !active_state->kex->done);
|
||||
|
||||
if (rekeying) {
|
||||
if (ssh_packet_is_rekeying(active_state)) {
|
||||
debug("rekeying in progress");
|
||||
} else if (need_rekeying) {
|
||||
/* manual rekey request */
|
||||
debug("need rekeying");
|
||||
if ((r = kex_start_rekex(active_state)) != 0)
|
||||
fatal("%s: kex_start_rekex: %s", __func__,
|
||||
ssh_err(r));
|
||||
need_rekeying = 0;
|
||||
} else {
|
||||
/*
|
||||
* Make packets of buffered stdin data, and buffer
|
||||
@ -1602,23 +1656,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
||||
*/
|
||||
max_fd2 = max_fd;
|
||||
client_wait_until_can_do_something(&readset, &writeset,
|
||||
&max_fd2, &nalloc, rekeying);
|
||||
&max_fd2, &nalloc, ssh_packet_is_rekeying(active_state));
|
||||
|
||||
if (quit_pending)
|
||||
break;
|
||||
|
||||
/* Do channel operations unless rekeying in progress. */
|
||||
if (!rekeying) {
|
||||
if (!ssh_packet_is_rekeying(active_state))
|
||||
channel_after_select(readset, writeset);
|
||||
if (need_rekeying || packet_need_rekeying()) {
|
||||
debug("need rekeying");
|
||||
active_state->kex->done = 0;
|
||||
if ((r = kex_send_kexinit(active_state)) != 0)
|
||||
fatal("%s: kex_send_kexinit: %s",
|
||||
__func__, ssh_err(r));
|
||||
need_rekeying = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Buffer input from the connection. */
|
||||
client_process_net_input(readset);
|
||||
@ -1636,14 +1681,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
||||
client_process_output(writeset);
|
||||
}
|
||||
|
||||
if (session_resumed) {
|
||||
connection_in = packet_get_connection_in();
|
||||
connection_out = packet_get_connection_out();
|
||||
max_fd = MAX(max_fd, connection_out);
|
||||
max_fd = MAX(max_fd, connection_in);
|
||||
session_resumed = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send as much buffered packet data as possible to the
|
||||
* sender.
|
||||
@ -1737,7 +1774,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
||||
}
|
||||
|
||||
/* Clear and free any buffers. */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
buffer_free(&stdin_buffer);
|
||||
buffer_free(&stdout_buffer);
|
||||
buffer_free(&stderr_buffer);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: clientloop.h,v 1.31 2013/06/02 23:36:29 dtucker Exp $ */
|
||||
/* $OpenBSD: clientloop.h,v 1.32 2016/01/13 23:04:47 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
/* Client side main loop for the interactive session. */
|
||||
int client_loop(int, int, int);
|
||||
void client_x11_get_proto(const char *, const char *, u_int, u_int,
|
||||
int client_x11_get_proto(const char *, const char *, u_int, u_int,
|
||||
char **, char **);
|
||||
void client_global_request_reply_fwd(int, u_int32_t, void *);
|
||||
void client_session2_setup(int, int, int, const char *, struct termios *,
|
||||
|
27
config.h.in
27
config.h.in
@ -694,9 +694,6 @@
|
||||
/* Define to 1 if you have the `network' library (-lnetwork). */
|
||||
#undef HAVE_LIBNETWORK
|
||||
|
||||
/* Define to 1 if you have the `nsl' library (-lnsl). */
|
||||
#undef HAVE_LIBNSL
|
||||
|
||||
/* Define to 1 if you have the `pam' library (-lpam). */
|
||||
#undef HAVE_LIBPAM
|
||||
|
||||
@ -845,6 +842,9 @@
|
||||
/* define if you have pid_t data type */
|
||||
#undef HAVE_PID_T
|
||||
|
||||
/* Define to 1 if you have the `pledge' function. */
|
||||
#undef HAVE_PLEDGE
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
@ -854,6 +854,12 @@
|
||||
/* Define to 1 if you have the `prctl' function. */
|
||||
#undef HAVE_PRCTL
|
||||
|
||||
/* Define to 1 if you have the `priv_basicset' function. */
|
||||
#undef HAVE_PRIV_BASICSET
|
||||
|
||||
/* Define to 1 if you have the <priv.h> header file. */
|
||||
#undef HAVE_PRIV_H
|
||||
|
||||
/* Define if you have /proc/$pid/fd */
|
||||
#undef HAVE_PROC_PID
|
||||
|
||||
@ -956,6 +962,9 @@
|
||||
/* Define to 1 if you have the `setpcred' function. */
|
||||
#undef HAVE_SETPCRED
|
||||
|
||||
/* Define to 1 if you have the `setppriv' function. */
|
||||
#undef HAVE_SETPPRIV
|
||||
|
||||
/* Define to 1 if you have the `setproctitle' function. */
|
||||
#undef HAVE_SETPROCTITLE
|
||||
|
||||
@ -1444,6 +1453,9 @@
|
||||
/* Define if you don't want to use lastlog in session.c */
|
||||
#undef NO_SSH_LASTLOG
|
||||
|
||||
/* Define to disable UID restoration test */
|
||||
#undef NO_UID_RESTORATION_TEST
|
||||
|
||||
/* Define if X11 doesn't support AF_UNIX sockets on that system */
|
||||
#undef NO_X11_UNIX_SOCKETS
|
||||
|
||||
@ -1520,6 +1532,9 @@
|
||||
/* no privsep sandboxing */
|
||||
#undef SANDBOX_NULL
|
||||
|
||||
/* Sandbox using pledge(2) */
|
||||
#undef SANDBOX_PLEDGE
|
||||
|
||||
/* Sandbox using setrlimit(2) */
|
||||
#undef SANDBOX_RLIMIT
|
||||
|
||||
@ -1532,6 +1547,9 @@
|
||||
/* define if setrlimit RLIMIT_NOFILE breaks things */
|
||||
#undef SANDBOX_SKIP_RLIMIT_NOFILE
|
||||
|
||||
/* Sandbox using Solaris/Illumos privileges */
|
||||
#undef SANDBOX_SOLARIS
|
||||
|
||||
/* Sandbox using systrace(4) */
|
||||
#undef SANDBOX_SYSTRACE
|
||||
|
||||
@ -1638,6 +1656,9 @@
|
||||
/* Use PIPES instead of a socketpair() */
|
||||
#undef USE_PIPES
|
||||
|
||||
/* Define if you have Solaris privileges */
|
||||
#undef USE_SOLARIS_PRIVS
|
||||
|
||||
/* Define if you have Solaris process contracts */
|
||||
#undef USE_SOLARIS_PROCESS_CONTRACTS
|
||||
|
||||
|
735
configure
vendored
735
configure
vendored
@ -1320,7 +1320,7 @@ Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
||||
--without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL**
|
||||
--without-ssh1 Enable support for SSH protocol 1
|
||||
--with-ssh1 Enable support for SSH protocol 1
|
||||
--without-stackprotect Don't use compiler's stack protection
|
||||
--without-hardening Don't use toolchain hardening flags
|
||||
--without-rpath Disable auto-added -R linker paths
|
||||
@ -1331,6 +1331,7 @@ Optional Packages:
|
||||
--with-Werror Build main code with -Werror
|
||||
--with-solaris-contracts Enable Solaris process contracts (experimental)
|
||||
--with-solaris-projects Enable Solaris projects (experimental)
|
||||
--with-solaris-privs Enable Solaris/Illumos privileges (experimental)
|
||||
--with-osfsia Enable Digital Unix SIA
|
||||
--with-zlib=PATH Use zlib in PATH
|
||||
--without-zlib-version-check Disable zlib version check
|
||||
@ -1346,7 +1347,7 @@ Optional Packages:
|
||||
--with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)
|
||||
--with-pam Enable PAM support
|
||||
--with-privsep-user=user Specify non-privileged user for privilege separation
|
||||
--with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, capsicum)
|
||||
--with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge)
|
||||
--with-selinux Enable SELinux support
|
||||
--with-kerberos5=PATH Enable Kerberos 5 support
|
||||
--with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)
|
||||
@ -7972,6 +7973,11 @@ done
|
||||
SIA_MSG="no"
|
||||
SPC_MSG="no"
|
||||
SP_MSG="no"
|
||||
SPP_MSG="no"
|
||||
|
||||
# Support for Solaris/Illumos privileges (this test is used by both
|
||||
# the --with-solaris-privs option and --with-sandbox=solaris).
|
||||
SOLARIS_PRIVS="no"
|
||||
|
||||
# Check for some target-specific stuff
|
||||
case "$host" in
|
||||
@ -8959,6 +8965,11 @@ cat >>confdefs.h <<\_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define NO_UID_RESTORATION_TEST 1
|
||||
_ACEOF
|
||||
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define DISABLE_SHADOW 1
|
||||
_ACEOF
|
||||
@ -9491,6 +9502,73 @@ fi
|
||||
|
||||
done
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for sandbox_apply in -lsandbox" >&5
|
||||
echo $ECHO_N "checking for sandbox_apply in -lsandbox... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_lib_sandbox_sandbox_apply+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lsandbox $LIBS"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char sandbox_apply ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return sandbox_apply ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
ac_cv_lib_sandbox_sandbox_apply=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_lib_sandbox_sandbox_apply=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_lib_sandbox_sandbox_apply" >&5
|
||||
echo "${ECHO_T}$ac_cv_lib_sandbox_sandbox_apply" >&6; }
|
||||
if test $ac_cv_lib_sandbox_sandbox_apply = yes; then
|
||||
|
||||
SSHDLIBS="$SSHDLIBS -lsandbox"
|
||||
|
||||
fi
|
||||
|
||||
;;
|
||||
*-*-dragonfly*)
|
||||
SSHDLIBS="$SSHDLIBS -lcrypt"
|
||||
@ -10789,6 +10867,339 @@ _ACEOF
|
||||
echo "${ECHO_T}no" >&6; }
|
||||
fi
|
||||
|
||||
for ac_func in setppriv
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define $ac_func innocuous_$ac_func
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef $ac_func
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char $ac_func ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_$ac_func || defined __stub___$ac_func
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return $ac_func ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
eval "$as_ac_var=yes"
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
eval "$as_ac_var=no"
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_var'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
if test `eval echo '${'$as_ac_var'}'` = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
for ac_func in priv_basicset
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define $ac_func innocuous_$ac_func
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef $ac_func
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char $ac_func ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_$ac_func || defined __stub___$ac_func
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return $ac_func ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
eval "$as_ac_var=yes"
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
eval "$as_ac_var=no"
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_var'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
if test `eval echo '${'$as_ac_var'}'` = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
for ac_header in priv.h
|
||||
do
|
||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
|
||||
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_Header'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
else
|
||||
# Is the header compilable?
|
||||
{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
|
||||
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
#include <$ac_header>
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (ac_try="$ac_compile"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_compile") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest.$ac_objext; then
|
||||
ac_header_compiler=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_header_compiler=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
|
||||
echo "${ECHO_T}$ac_header_compiler" >&6; }
|
||||
|
||||
# Is the header present?
|
||||
{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
|
||||
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <$ac_header>
|
||||
_ACEOF
|
||||
if { (ac_try="$ac_cpp conftest.$ac_ext"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } >/dev/null && {
|
||||
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
}; then
|
||||
ac_header_preproc=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_header_preproc=no
|
||||
fi
|
||||
|
||||
rm -f conftest.err conftest.$ac_ext
|
||||
{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
|
||||
echo "${ECHO_T}$ac_header_preproc" >&6; }
|
||||
|
||||
# So? What about this header?
|
||||
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
|
||||
yes:no: )
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
|
||||
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
|
||||
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
|
||||
ac_header_preproc=yes
|
||||
;;
|
||||
no:yes:* )
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
|
||||
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
|
||||
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
|
||||
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
|
||||
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
|
||||
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
|
||||
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
|
||||
( cat <<\_ASBOX
|
||||
## ------------------------------------------- ##
|
||||
## Report this to openssh-unix-dev@mindrot.org ##
|
||||
## ------------------------------------------- ##
|
||||
_ASBOX
|
||||
) | sed "s/^/$as_me: WARNING: /" >&2
|
||||
;;
|
||||
esac
|
||||
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
|
||||
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
eval "$as_ac_Header=\$ac_header_preproc"
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_Header'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
|
||||
fi
|
||||
if test `eval echo '${'$as_ac_Header'}'` = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
# Check whether --with-solaris-contracts was given.
|
||||
if test "${with_solaris_contracts+set}" = set; then
|
||||
withval=$with_solaris_contracts;
|
||||
@ -10859,7 +11270,7 @@ cat >>confdefs.h <<\_ACEOF
|
||||
#define USE_SOLARIS_PROCESS_CONTRACTS 1
|
||||
_ACEOF
|
||||
|
||||
SSHDLIBS="$SSHDLIBS -lcontract"
|
||||
LIBS="$LIBS -lcontract"
|
||||
SPC_MSG="yes"
|
||||
fi
|
||||
|
||||
@ -10937,11 +11348,43 @@ cat >>confdefs.h <<\_ACEOF
|
||||
#define USE_SOLARIS_PROJECTS 1
|
||||
_ACEOF
|
||||
|
||||
SSHDLIBS="$SSHDLIBS -lproject"
|
||||
LIBS="$LIBS -lproject"
|
||||
SP_MSG="yes"
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --with-solaris-privs was given.
|
||||
if test "${with_solaris_privs+set}" = set; then
|
||||
withval=$with_solaris_privs;
|
||||
{ echo "$as_me:$LINENO: checking for Solaris/Illumos privilege support" >&5
|
||||
echo $ECHO_N "checking for Solaris/Illumos privilege support... $ECHO_C" >&6; }
|
||||
if test "x$ac_cv_func_setppriv" = "xyes" -a \
|
||||
"x$ac_cv_header_priv_h" = "xyes" ; then
|
||||
SOLARIS_PRIVS=yes
|
||||
{ echo "$as_me:$LINENO: result: found" >&5
|
||||
echo "${ECHO_T}found" >&6; }
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define NO_UID_RESTORATION_TEST 1
|
||||
_ACEOF
|
||||
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define USE_SOLARIS_PRIVS 1
|
||||
_ACEOF
|
||||
|
||||
SPP_MSG="yes"
|
||||
else
|
||||
{ echo "$as_me:$LINENO: result: not found" >&5
|
||||
echo "${ECHO_T}not found" >&6; }
|
||||
{ { echo "$as_me:$LINENO: error: *** must have support for Solaris privileges to use --with-solaris-privs" >&5
|
||||
echo "$as_me: error: *** must have support for Solaris privileges to use --with-solaris-privs" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
TEST_SHELL=$SHELL # let configure find us a capable shell
|
||||
@ -11942,163 +12385,6 @@ fi
|
||||
|
||||
|
||||
# Checks for libraries.
|
||||
{ echo "$as_me:$LINENO: checking for yp_match" >&5
|
||||
echo $ECHO_N "checking for yp_match... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_func_yp_match+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
/* Define yp_match to an innocuous variant, in case <limits.h> declares yp_match.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define yp_match innocuous_yp_match
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char yp_match (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef yp_match
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char yp_match ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_yp_match || defined __stub___yp_match
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return yp_match ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
ac_cv_func_yp_match=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_func_yp_match=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_func_yp_match" >&5
|
||||
echo "${ECHO_T}$ac_cv_func_yp_match" >&6; }
|
||||
if test $ac_cv_func_yp_match = yes; then
|
||||
:
|
||||
else
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for yp_match in -lnsl" >&5
|
||||
echo $ECHO_N "checking for yp_match in -lnsl... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_lib_nsl_yp_match+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lnsl $LIBS"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char yp_match ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return yp_match ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
ac_cv_lib_nsl_yp_match=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_lib_nsl_yp_match=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_yp_match" >&5
|
||||
echo "${ECHO_T}$ac_cv_lib_nsl_yp_match" >&6; }
|
||||
if test $ac_cv_lib_nsl_yp_match = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBNSL 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-lnsl $LIBS"
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for setsockopt" >&5
|
||||
echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_func_setsockopt+set}" = set; then
|
||||
@ -14599,7 +14885,8 @@ fi
|
||||
done
|
||||
|
||||
|
||||
# On some platforms, inet_ntop may be found in libresolv or libnsl.
|
||||
# On some platforms, inet_ntop and gethostbyname may be found in libresolv
|
||||
# or libnsl.
|
||||
{ echo "$as_me:$LINENO: checking for library containing inet_ntop" >&5
|
||||
echo $ECHO_N "checking for library containing inet_ntop... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_search_inet_ntop+set}" = set; then
|
||||
@ -14683,6 +14970,89 @@ if test "$ac_res" != no; then
|
||||
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for library containing gethostbyname" >&5
|
||||
echo $ECHO_N "checking for library containing gethostbyname... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_search_gethostbyname+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char gethostbyname ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return gethostbyname ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' resolv nsl; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
ac_cv_search_gethostbyname=$ac_res
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext
|
||||
if test "${ac_cv_search_gethostbyname+set}" = set; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test "${ac_cv_search_gethostbyname+set}" = set; then
|
||||
:
|
||||
else
|
||||
ac_cv_search_gethostbyname=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_search_gethostbyname" >&5
|
||||
echo "${ECHO_T}$ac_cv_search_gethostbyname" >&6; }
|
||||
ac_res=$ac_cv_search_gethostbyname
|
||||
if test "$ac_res" != no; then
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
for ac_func in strftime
|
||||
@ -16522,6 +16892,7 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for ac_func in \
|
||||
@ -16579,6 +16950,7 @@ for ac_func in \
|
||||
nsleep \
|
||||
ogetaddrinfo \
|
||||
openlog_r \
|
||||
pledge \
|
||||
poll \
|
||||
prctl \
|
||||
pstat \
|
||||
@ -20707,12 +21079,12 @@ openssl_engine=no
|
||||
# Check whether --with-ssl-engine was given.
|
||||
if test "${with_ssl_engine+set}" = set; then
|
||||
withval=$with_ssl_engine;
|
||||
if test "x$openssl" = "xno" ; then
|
||||
{ { echo "$as_me:$LINENO: error: cannot use --with-ssl-engine when OpenSSL disabled" >&5
|
||||
if test "x$withval" != "xno" ; then
|
||||
if test "x$openssl" = "xno" ; then
|
||||
{ { echo "$as_me:$LINENO: error: cannot use --with-ssl-engine when OpenSSL disabled" >&5
|
||||
echo "$as_me: error: cannot use --with-ssl-engine when OpenSSL disabled" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
if test "x$withval" != "xno" ; then
|
||||
fi
|
||||
openssl_engine=yes
|
||||
fi
|
||||
|
||||
@ -20999,6 +21371,7 @@ cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <openssl/opensslv.h>
|
||||
@ -21015,7 +21388,8 @@ main ()
|
||||
if(fd == NULL)
|
||||
exit(1);
|
||||
|
||||
if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0)
|
||||
if ((rc = fprintf(fd ,"%08lx (%s)\n",
|
||||
(unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0)
|
||||
exit(1);
|
||||
|
||||
exit(0);
|
||||
@ -21184,6 +21558,7 @@ cat >>conftest.$ac_ext <<_ACEOF
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
@ -24145,7 +24520,19 @@ fi
|
||||
|
||||
|
||||
|
||||
if test "x$sandbox_arg" = "xsystrace" || \
|
||||
if test "x$sandbox_arg" = "xpledge" || \
|
||||
( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then
|
||||
test "x$ac_cv_func_pledge" != "xyes" && \
|
||||
{ { echo "$as_me:$LINENO: error: pledge sandbox requires pledge(2) support" >&5
|
||||
echo "$as_me: error: pledge sandbox requires pledge(2) support" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
SANDBOX_STYLE="pledge"
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define SANDBOX_PLEDGE 1
|
||||
_ACEOF
|
||||
|
||||
elif test "x$sandbox_arg" = "xsystrace" || \
|
||||
( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then
|
||||
test "x$have_systr_policy_kill" != "x1" && \
|
||||
{ { echo "$as_me:$LINENO: error: systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" >&5
|
||||
@ -24238,6 +24625,14 @@ cat >>confdefs.h <<\_ACEOF
|
||||
#define SANDBOX_RLIMIT 1
|
||||
_ACEOF
|
||||
|
||||
elif test "x$sandbox_arg" = "xsolaris" || \
|
||||
( test -z "$sandbox_arg" && test "x$SOLARIS_PRIVS" = "xyes" ) ; then
|
||||
SANDBOX_STYLE="solaris"
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define SANDBOX_SOLARIS 1
|
||||
_ACEOF
|
||||
|
||||
elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \
|
||||
test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then
|
||||
SANDBOX_STYLE="none"
|
||||
@ -31719,6 +32114,9 @@ int
|
||||
main ()
|
||||
{
|
||||
|
||||
struct __res_state *volatile p = &_res; /* force resolution of _res */
|
||||
return 0;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
@ -36811,6 +37209,7 @@ 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 " Solaris privilege support: $SPP_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"
|
||||
|
75
configure.ac
75
configure.ac
@ -140,7 +140,7 @@ else
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([ssh1],
|
||||
[ --without-ssh1 Enable support for SSH protocol 1],
|
||||
[ --with-ssh1 Enable support for SSH protocol 1],
|
||||
[
|
||||
if test "x$withval" = "xyes" ; then
|
||||
if test "x$openssl" = "xno" ; then
|
||||
@ -469,6 +469,11 @@ AC_CHECK_HEADERS([sys/un.h], [], [], [
|
||||
SIA_MSG="no"
|
||||
SPC_MSG="no"
|
||||
SP_MSG="no"
|
||||
SPP_MSG="no"
|
||||
|
||||
# Support for Solaris/Illumos privileges (this test is used by both
|
||||
# the --with-solaris-privs option and --with-sandbox=solaris).
|
||||
SOLARIS_PRIVS="no"
|
||||
|
||||
# Check for some target-specific stuff
|
||||
case "$host" in
|
||||
@ -575,6 +580,8 @@ case "$host" in
|
||||
LIBS="$LIBS /usr/lib/textreadmode.o"
|
||||
AC_DEFINE([HAVE_CYGWIN], [1], [Define if you are on Cygwin])
|
||||
AC_DEFINE([USE_PIPES], [1], [Use PIPES instead of a socketpair()])
|
||||
AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
|
||||
[Define to disable UID restoration test])
|
||||
AC_DEFINE([DISABLE_SHADOW], [1],
|
||||
[Define if you want to disable shadow passwords])
|
||||
AC_DEFINE([NO_X11_UNIX_SOCKETS], [1],
|
||||
@ -637,6 +644,9 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
|
||||
supported by bsd-setproctitle.c])
|
||||
AC_CHECK_FUNCS([sandbox_init])
|
||||
AC_CHECK_HEADERS([sandbox.h])
|
||||
AC_CHECK_LIB([sandbox], [sandbox_apply], [
|
||||
SSHDLIBS="$SSHDLIBS -lsandbox"
|
||||
])
|
||||
;;
|
||||
*-*-dragonfly*)
|
||||
SSHDLIBS="$SSHDLIBS -lcrypt"
|
||||
@ -889,13 +899,16 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_CHECK_FUNCS([setppriv])
|
||||
AC_CHECK_FUNCS([priv_basicset])
|
||||
AC_CHECK_HEADERS([priv.h])
|
||||
AC_ARG_WITH([solaris-contracts],
|
||||
[ --with-solaris-contracts Enable Solaris process contracts (experimental)],
|
||||
[
|
||||
AC_CHECK_LIB([contract], [ct_tmpl_activate],
|
||||
[ AC_DEFINE([USE_SOLARIS_PROCESS_CONTRACTS], [1],
|
||||
[Define if you have Solaris process contracts])
|
||||
SSHDLIBS="$SSHDLIBS -lcontract"
|
||||
LIBS="$LIBS -lcontract"
|
||||
SPC_MSG="yes" ], )
|
||||
],
|
||||
)
|
||||
@ -905,10 +918,29 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
AC_CHECK_LIB([project], [setproject],
|
||||
[ AC_DEFINE([USE_SOLARIS_PROJECTS], [1],
|
||||
[Define if you have Solaris projects])
|
||||
SSHDLIBS="$SSHDLIBS -lproject"
|
||||
LIBS="$LIBS -lproject"
|
||||
SP_MSG="yes" ], )
|
||||
],
|
||||
)
|
||||
AC_ARG_WITH([solaris-privs],
|
||||
[ --with-solaris-privs Enable Solaris/Illumos privileges (experimental)],
|
||||
[
|
||||
AC_MSG_CHECKING([for Solaris/Illumos privilege support])
|
||||
if test "x$ac_cv_func_setppriv" = "xyes" -a \
|
||||
"x$ac_cv_header_priv_h" = "xyes" ; then
|
||||
SOLARIS_PRIVS=yes
|
||||
AC_MSG_RESULT([found])
|
||||
AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
|
||||
[Define to disable UID restoration test])
|
||||
AC_DEFINE([USE_SOLARIS_PRIVS], [1],
|
||||
[Define if you have Solaris privileges])
|
||||
SPP_MSG="yes"
|
||||
else
|
||||
AC_MSG_RESULT([not found])
|
||||
AC_MSG_ERROR([*** must have support for Solaris privileges to use --with-solaris-privs])
|
||||
fi
|
||||
],
|
||||
)
|
||||
TEST_SHELL=$SHELL # let configure find us a capable shell
|
||||
;;
|
||||
*-*-sunos4*)
|
||||
@ -1122,7 +1154,6 @@ AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]], [[ exit(0); ]])],
|
||||
|
||||
dnl Checks for header files.
|
||||
# Checks for libraries.
|
||||
AC_CHECK_FUNC([yp_match], , [AC_CHECK_LIB([nsl], [yp_match])])
|
||||
AC_CHECK_FUNC([setsockopt], , [AC_CHECK_LIB([socket], [setsockopt])])
|
||||
|
||||
dnl IRIX and Solaris 2.5.1 have dirname() in libgen
|
||||
@ -1286,8 +1317,10 @@ AC_SEARCH_LIBS([openpty], [util bsd])
|
||||
AC_SEARCH_LIBS([updwtmp], [util bsd])
|
||||
AC_CHECK_FUNCS([fmt_scaled scan_scaled login logout openpty updwtmp logwtmp])
|
||||
|
||||
# On some platforms, inet_ntop may be found in libresolv or libnsl.
|
||||
# On some platforms, inet_ntop and gethostbyname may be found in libresolv
|
||||
# or libnsl.
|
||||
AC_SEARCH_LIBS([inet_ntop], [resolv nsl])
|
||||
AC_SEARCH_LIBS([gethostbyname], [resolv nsl])
|
||||
|
||||
AC_FUNC_STRFTIME
|
||||
|
||||
@ -1669,6 +1702,7 @@ AC_CHECK_FUNCS([ \
|
||||
nsleep \
|
||||
ogetaddrinfo \
|
||||
openlog_r \
|
||||
pledge \
|
||||
poll \
|
||||
prctl \
|
||||
pstat \
|
||||
@ -2309,10 +2343,10 @@ openssl_engine=no
|
||||
AC_ARG_WITH([ssl-engine],
|
||||
[ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ],
|
||||
[
|
||||
if test "x$openssl" = "xno" ; then
|
||||
AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled])
|
||||
fi
|
||||
if test "x$withval" != "xno" ; then
|
||||
if test "x$openssl" = "xno" ; then
|
||||
AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled])
|
||||
fi
|
||||
openssl_engine=yes
|
||||
fi
|
||||
]
|
||||
@ -2345,6 +2379,7 @@ if test "x$openssl" = "xyes" ; then
|
||||
AC_MSG_CHECKING([OpenSSL header version])
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([[
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <openssl/opensslv.h>
|
||||
@ -2357,7 +2392,8 @@ if test "x$openssl" = "xyes" ; then
|
||||
if(fd == NULL)
|
||||
exit(1);
|
||||
|
||||
if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0)
|
||||
if ((rc = fprintf(fd ,"%08lx (%s)\n",
|
||||
(unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0)
|
||||
exit(1);
|
||||
|
||||
exit(0);
|
||||
@ -2424,6 +2460,7 @@ if test "x$openssl" = "xyes" ; then
|
||||
[AC_LANG_PROGRAM([[
|
||||
#include <string.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/crypto.h>
|
||||
]], [[
|
||||
exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1);
|
||||
]])],
|
||||
@ -2998,7 +3035,7 @@ fi
|
||||
# Decide which sandbox style to use
|
||||
sandbox_arg=""
|
||||
AC_ARG_WITH([sandbox],
|
||||
[ --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, capsicum)],
|
||||
[ --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge)],
|
||||
[
|
||||
if test "x$withval" = "xyes" ; then
|
||||
sandbox_arg=""
|
||||
@ -3094,7 +3131,13 @@ AC_RUN_IFELSE(
|
||||
[AC_MSG_WARN([cross compiling: assuming yes])]
|
||||
)
|
||||
|
||||
if test "x$sandbox_arg" = "xsystrace" || \
|
||||
if test "x$sandbox_arg" = "xpledge" || \
|
||||
( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then
|
||||
test "x$ac_cv_func_pledge" != "xyes" && \
|
||||
AC_MSG_ERROR([pledge sandbox requires pledge(2) support])
|
||||
SANDBOX_STYLE="pledge"
|
||||
AC_DEFINE([SANDBOX_PLEDGE], [1], [Sandbox using pledge(2)])
|
||||
elif test "x$sandbox_arg" = "xsystrace" || \
|
||||
( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then
|
||||
test "x$have_systr_policy_kill" != "x1" && \
|
||||
AC_MSG_ERROR([systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support])
|
||||
@ -3147,6 +3190,10 @@ elif test "x$sandbox_arg" = "xrlimit" || \
|
||||
AC_MSG_ERROR([rlimit sandbox requires select to work with rlimit])
|
||||
SANDBOX_STYLE="rlimit"
|
||||
AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)])
|
||||
elif test "x$sandbox_arg" = "xsolaris" || \
|
||||
( test -z "$sandbox_arg" && test "x$SOLARIS_PRIVS" = "xyes" ) ; then
|
||||
SANDBOX_STYLE="solaris"
|
||||
AC_DEFINE([SANDBOX_SOLARIS], [1], [Sandbox using Solaris/Illumos privileges])
|
||||
elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \
|
||||
test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then
|
||||
SANDBOX_STYLE="none"
|
||||
@ -3970,7 +4017,10 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
extern struct __res_state _res;
|
||||
]], [[ ]])],
|
||||
]], [[
|
||||
struct __res_state *volatile p = &_res; /* force resolution of _res */
|
||||
return 0;
|
||||
]],)],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE__RES_EXTERN], [1],
|
||||
[Define if you have struct __res_state _res as an extern])
|
||||
@ -4933,6 +4983,7 @@ 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 " Solaris privilege support: $SPP_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"
|
||||
|
@ -1,4 +1,4 @@
|
||||
%define ver 7.1p2
|
||||
%define ver 7.2p1
|
||||
%define rel 1
|
||||
|
||||
# OpenSSH privilege separation requires a user & group ID
|
||||
@ -89,7 +89,7 @@ Requires: initscripts >= 5.20
|
||||
BuildRequires: perl, openssl-devel
|
||||
BuildRequires: /bin/login
|
||||
%if ! %{build6x}
|
||||
BuildPreReq: glibc-devel, pam
|
||||
BuildRequires: glibc-devel, pam
|
||||
%else
|
||||
BuildRequires: /usr/include/security/pam_appl.h
|
||||
%endif
|
||||
@ -184,7 +184,7 @@ CFLAGS="$RPM_OPT_FLAGS -Os"; export CFLAGS
|
||||
%endif
|
||||
|
||||
%if %{kerberos5}
|
||||
K5DIR=`rpm -ql krb5-devel | grep include/krb5.h | sed 's,\/include\/krb5.h,,'`
|
||||
K5DIR=`rpm -ql krb5-devel | grep 'include/krb5\.h' | sed 's,\/include\/krb5.h,,'`
|
||||
echo K5DIR=$K5DIR
|
||||
%endif
|
||||
|
||||
@ -192,7 +192,6 @@ echo K5DIR=$K5DIR
|
||||
--sysconfdir=%{_sysconfdir}/ssh \
|
||||
--libexecdir=%{_libexecdir}/openssh \
|
||||
--datadir=%{_datadir}/openssh \
|
||||
--with-rsh=%{_bindir}/rsh \
|
||||
--with-default-path=/usr/local/bin:/bin:/usr/bin \
|
||||
--with-superuser-path=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin \
|
||||
--with-privsep-path=%{_var}/empty/sshd \
|
||||
|
@ -56,10 +56,13 @@ then
|
||||
fi
|
||||
fi
|
||||
|
||||
DEFAULT_PUB_ID_FILE=$(ls -t ${HOME}/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)
|
||||
DEFAULT_PUB_ID_FILE="$HOME/$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)"
|
||||
|
||||
usage () {
|
||||
printf 'Usage: %s [-h|-?|-n] [-i [identity_file]] [-p port] [[-o <ssh -o options>] ...] [user@]hostname\n' "$0" >&2
|
||||
printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o <ssh -o options>] ...] [user@]hostname\n' "$0" >&2
|
||||
printf '\t-f: force mode -- copy keys without trying to check if they are already installed\n' >&2
|
||||
printf '\t-n: dry run -- no keys are actually copied\n' >&2
|
||||
printf '\t-h|-?: print this help\n' >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
@ -77,15 +80,18 @@ use_id_file() {
|
||||
PUB_ID_FILE="$L_ID_FILE.pub"
|
||||
fi
|
||||
|
||||
PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub)
|
||||
[ "$FORCED" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub)
|
||||
|
||||
# check that the files are readable
|
||||
for f in $PUB_ID_FILE $PRIV_ID_FILE ; do
|
||||
ErrMSG=$( { : < $f ; } 2>&1 ) || {
|
||||
printf "\n%s: ERROR: failed to open ID file '%s': %s\n\n" "$0" "$f" "$(printf "%s\n" "$ErrMSG" | sed -e 's/.*: *//')"
|
||||
for f in "$PUB_ID_FILE" ${PRIV_ID_FILE:+"$PRIV_ID_FILE"} ; do
|
||||
ErrMSG=$( { : < "$f" ; } 2>&1 ) || {
|
||||
local L_PRIVMSG=""
|
||||
[ "$f" = "$PRIV_ID_FILE" ] && L_PRIVMSG=" (to install the contents of '$PUB_ID_FILE' anyway, look at the -f option)"
|
||||
printf "\n%s: ERROR: failed to open ID file '%s': %s\n" "$0" "$f" "$(printf "%s\n%s\n" "$ErrMSG" "$L_PRIVMSG" | sed -e 's/.*: *//')"
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" "$PUB_ID_FILE" >&2
|
||||
GET_ID="cat \"$PUB_ID_FILE\""
|
||||
}
|
||||
|
||||
@ -121,7 +127,7 @@ do
|
||||
}
|
||||
shift
|
||||
;;
|
||||
-n|-h|-\?)
|
||||
-f|-n|-h|-\?)
|
||||
OPT="$1"
|
||||
OPTARG=
|
||||
shift
|
||||
@ -154,6 +160,9 @@ do
|
||||
-o|-p)
|
||||
SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }$OPT '$(quote "$OPTARG")'"
|
||||
;;
|
||||
-f)
|
||||
FORCED=1
|
||||
;;
|
||||
-n)
|
||||
DRY_RUN=1
|
||||
;;
|
||||
@ -194,27 +203,35 @@ fi
|
||||
populate_new_ids() {
|
||||
local L_SUCCESS="$1"
|
||||
|
||||
if [ "$FORCED" ] ; then
|
||||
NEW_IDS=$(eval $GET_ID)
|
||||
return
|
||||
fi
|
||||
|
||||
# repopulate "$@" inside this function
|
||||
eval set -- "$SSH_OPTS"
|
||||
|
||||
umask 0177
|
||||
local L_TMP_ID_FILE=$(mktemp ~/.ssh/ssh-copy-id_id.XXXXXXXXXX)
|
||||
if test $? -ne 0 || test "x$L_TMP_ID_FILE" = "x" ; then
|
||||
echo "mktemp failed" 1>&2
|
||||
printf '%s: ERROR: mktemp failed\n' "$0" >&2
|
||||
exit 1
|
||||
fi
|
||||
trap "rm -f $L_TMP_ID_FILE ${L_TMP_ID_FILE}.pub" EXIT TERM INT QUIT
|
||||
local L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\""
|
||||
trap "$L_CLEANUP" EXIT TERM INT QUIT
|
||||
printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2
|
||||
NEW_IDS=$(
|
||||
eval $GET_ID | {
|
||||
while read ID ; do
|
||||
printf '%s\n' "$ID" > $L_TMP_ID_FILE
|
||||
while read ID || [ "$ID" ] ; do
|
||||
printf '%s\n' "$ID" > "$L_TMP_ID_FILE"
|
||||
|
||||
# the next line assumes $PRIV_ID_FILE only set if using a single id file - this
|
||||
# assumption will break if we implement the possibility of multiple -i options.
|
||||
# The point being that if file based, ssh needs the private key, which it cannot
|
||||
# find if only given the contents of the .pub file in an unrelated tmpfile
|
||||
ssh -i "${PRIV_ID_FILE:-$L_TMP_ID_FILE}" \
|
||||
-o ControlPath=none \
|
||||
-o LogLevel=INFO \
|
||||
-o PreferredAuthentications=publickey \
|
||||
-o IdentitiesOnly=yes "$@" exit 2>$L_TMP_ID_FILE.stderr </dev/null
|
||||
if [ "$?" = "$L_SUCCESS" ] ; then
|
||||
@ -230,20 +247,21 @@ populate_new_ids() {
|
||||
done
|
||||
}
|
||||
)
|
||||
rm -f $L_TMP_ID_FILE* && trap - EXIT TERM INT QUIT
|
||||
eval "$L_CLEANUP" && trap - EXIT TERM INT QUIT
|
||||
|
||||
if expr "$NEW_IDS" : "^ERROR: " >/dev/null ; then
|
||||
printf '\n%s: %s\n\n' "$0" "$NEW_IDS" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$NEW_IDS" ] ; then
|
||||
printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n\n' "$0" >&2
|
||||
printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2
|
||||
printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2
|
||||
exit 0
|
||||
fi
|
||||
printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2
|
||||
}
|
||||
|
||||
REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 |
|
||||
REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' -o ControlPath=none "$@" 2>&1 |
|
||||
sed -ne 's/.*remote software version //p')
|
||||
|
||||
case "$REMOTE_VERSION" in
|
||||
@ -269,10 +287,9 @@ case "$REMOTE_VERSION" in
|
||||
*)
|
||||
# Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect
|
||||
populate_new_ids 0
|
||||
[ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" "
|
||||
umask 077 ;
|
||||
mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ;
|
||||
if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi" \
|
||||
# in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; 'cd' to be at $HOME; and all on one line, because tcsh.
|
||||
[ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \
|
||||
ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \
|
||||
|| exit 1
|
||||
ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l)
|
||||
;;
|
||||
|
@ -29,6 +29,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.Nd use locally available keys to authorise logins on a remote machine
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl f
|
||||
.Op Fl n
|
||||
.Op Fl i Op Ar identity_file
|
||||
.Op Fl p Ar port
|
||||
@ -76,6 +77,10 @@ is used.
|
||||
Note that this can be used to ensure that the keys copied have the
|
||||
comment one prefers and/or extra options applied, by ensuring that the
|
||||
key file has these set as preferred before the copy is attempted.
|
||||
.It Fl f
|
||||
Forced mode: doesn't check if the keys are present on the remote server.
|
||||
This means that it does not need the private key. Of course, this can result
|
||||
in more than one copy of the key being installed on the remote system.
|
||||
.It Fl n
|
||||
do a dry-run. Instead of installing keys on the remote system simply
|
||||
prints the key(s) that would have been installed.
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
|
||||
Name: openssh
|
||||
Version: 7.1p2
|
||||
Version: 7.2p1
|
||||
URL: http://www.openssh.com/
|
||||
Release: 1
|
||||
Source0: openssh-%{version}.tar.gz
|
||||
|
@ -850,4 +850,11 @@ struct winsize {
|
||||
# endif /* gcc version */
|
||||
#endif /* __predict_true */
|
||||
|
||||
#if defined(HAVE_GLOB_H) && 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)
|
||||
# define USE_SYSTEM_GLOB
|
||||
#endif
|
||||
|
||||
#endif /* _DEFINES_H */
|
||||
|
9
dh.h
9
dh.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: dh.h,v 1.13 2015/05/27 23:39:18 dtucker Exp $ */
|
||||
/* $OpenBSD: dh.h,v 1.14 2015/10/16 22:32:22 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
@ -44,8 +44,11 @@ int dh_pub_is_valid(DH *, BIGNUM *);
|
||||
|
||||
u_int dh_estimate(int);
|
||||
|
||||
/* Min and max values from RFC4419. */
|
||||
#define DH_GRP_MIN 1024
|
||||
/*
|
||||
* Max value from RFC4419.
|
||||
* Miniumum increased in light of DH precomputation attacks.
|
||||
*/
|
||||
#define DH_GRP_MIN 2048
|
||||
#define DH_GRP_MAX 8192
|
||||
|
||||
/*
|
||||
|
@ -32,12 +32,6 @@
|
||||
#ifdef HAVE_BSTRING_H
|
||||
# include <bstring.h>
|
||||
#endif
|
||||
#if defined(HAVE_GLOB_H) && 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 <glob.h>
|
||||
#endif
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
|
168
kex.c
168
kex.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.c,v 1.109 2015/07/30 00:01:34 djm Exp $ */
|
||||
/* $OpenBSD: kex.c,v 1.117 2016/02/08 10:57:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -49,7 +49,6 @@
|
||||
#include "misc.h"
|
||||
#include "dispatch.h"
|
||||
#include "monitor.h"
|
||||
#include "roaming.h"
|
||||
|
||||
#include "ssherr.h"
|
||||
#include "sshbuf.h"
|
||||
@ -67,6 +66,19 @@ extern const EVP_MD *evp_ssh_sha256(void);
|
||||
static int kex_choose_conf(struct ssh *);
|
||||
static int kex_input_newkeys(int, u_int32_t, void *);
|
||||
|
||||
static const char *proposal_names[PROPOSAL_MAX] = {
|
||||
"KEX algorithms",
|
||||
"host key algorithms",
|
||||
"ciphers ctos",
|
||||
"ciphers stoc",
|
||||
"MACs ctos",
|
||||
"MACs stoc",
|
||||
"compression ctos",
|
||||
"compression stoc",
|
||||
"languages ctos",
|
||||
"languages stoc",
|
||||
};
|
||||
|
||||
struct kexalg {
|
||||
char *name;
|
||||
u_int type;
|
||||
@ -267,7 +279,7 @@ kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
|
||||
for (i = 0; i < PROPOSAL_MAX; i++) {
|
||||
if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
|
||||
goto out;
|
||||
debug2("kex_parse_kexinit: %s", proposal[i]);
|
||||
debug2("%s: %s", proposal_names[i], proposal[i]);
|
||||
}
|
||||
/* first kex follows / reserved */
|
||||
if ((r = sshbuf_get_u8(b, &v)) != 0 || /* first_kex_follows */
|
||||
@ -302,7 +314,14 @@ kex_prop_free(char **proposal)
|
||||
static int
|
||||
kex_protocol_error(int type, u_int32_t seq, void *ctxt)
|
||||
{
|
||||
error("Hm, kex protocol error: type %d seq %u", type, seq);
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
int r;
|
||||
|
||||
error("kex protocol error: type %d seq %u", type, seq);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, seq)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -314,6 +333,20 @@ kex_reset_dispatch(struct ssh *ssh)
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
|
||||
}
|
||||
|
||||
static int
|
||||
kex_send_ext_info(struct ssh *ssh)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, 1)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, "rsa-sha2-256,rsa-sha2-512")) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kex_send_newkeys(struct ssh *ssh)
|
||||
{
|
||||
@ -326,9 +359,51 @@ kex_send_newkeys(struct ssh *ssh)
|
||||
debug("SSH2_MSG_NEWKEYS sent");
|
||||
debug("expecting SSH2_MSG_NEWKEYS");
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
|
||||
if (ssh->kex->ext_info_c)
|
||||
if ((r = kex_send_ext_info(ssh)) != 0)
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kex_input_ext_info(int type, u_int32_t seq, void *ctxt)
|
||||
{
|
||||
struct ssh *ssh = ctxt;
|
||||
struct kex *kex = ssh->kex;
|
||||
u_int32_t i, ninfo;
|
||||
char *name, *val, *found;
|
||||
int r;
|
||||
|
||||
debug("SSH2_MSG_EXT_INFO received");
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);
|
||||
if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)
|
||||
return r;
|
||||
for (i = 0; i < ninfo; i++) {
|
||||
if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
|
||||
return r;
|
||||
if ((r = sshpkt_get_cstring(ssh, &val, NULL)) != 0) {
|
||||
free(name);
|
||||
return r;
|
||||
}
|
||||
debug("%s: %s=<%s>", __func__, name, val);
|
||||
if (strcmp(name, "server-sig-algs") == 0) {
|
||||
found = match_list("rsa-sha2-256", val, NULL);
|
||||
if (found) {
|
||||
kex->rsa_sha2 = 256;
|
||||
free(found);
|
||||
}
|
||||
found = match_list("rsa-sha2-512", val, NULL);
|
||||
if (found) {
|
||||
kex->rsa_sha2 = 512;
|
||||
free(found);
|
||||
}
|
||||
}
|
||||
free(name);
|
||||
free(val);
|
||||
}
|
||||
return sshpkt_get_end(ssh);
|
||||
}
|
||||
|
||||
static int
|
||||
kex_input_newkeys(int type, u_int32_t seq, void *ctxt)
|
||||
{
|
||||
@ -468,7 +543,7 @@ kex_free_newkeys(struct newkeys *newkeys)
|
||||
newkeys->enc.key = NULL;
|
||||
}
|
||||
if (newkeys->enc.iv) {
|
||||
explicit_bzero(newkeys->enc.iv, newkeys->enc.block_size);
|
||||
explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len);
|
||||
free(newkeys->enc.iv);
|
||||
newkeys->enc.iv = NULL;
|
||||
}
|
||||
@ -511,6 +586,8 @@ kex_free(struct kex *kex)
|
||||
free(kex->client_version_string);
|
||||
free(kex->server_version_string);
|
||||
free(kex->failed_choice);
|
||||
free(kex->hostkey_alg);
|
||||
free(kex->name);
|
||||
free(kex);
|
||||
}
|
||||
|
||||
@ -529,6 +606,25 @@ kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Request key re-exchange, returns 0 on success or a ssherr.h error
|
||||
* code otherwise. Must not be called if KEX is incomplete or in-progress.
|
||||
*/
|
||||
int
|
||||
kex_start_rekex(struct ssh *ssh)
|
||||
{
|
||||
if (ssh->kex == NULL) {
|
||||
error("%s: no kex", __func__);
|
||||
return SSH_ERR_INTERNAL_ERROR;
|
||||
}
|
||||
if (ssh->kex->done == 0) {
|
||||
error("%s: requested twice", __func__);
|
||||
return SSH_ERR_INTERNAL_ERROR;
|
||||
}
|
||||
ssh->kex->done = 0;
|
||||
return kex_send_kexinit(ssh);
|
||||
}
|
||||
|
||||
static int
|
||||
choose_enc(struct sshenc *enc, char *client, char *server)
|
||||
{
|
||||
@ -593,6 +689,7 @@ choose_kex(struct kex *k, char *client, char *server)
|
||||
|
||||
k->name = match_list(client, server, NULL);
|
||||
|
||||
debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
|
||||
if (k->name == NULL)
|
||||
return SSH_ERR_NO_KEX_ALG_MATCH;
|
||||
if ((kexalg = kex_alg_by_name(k->name)) == NULL)
|
||||
@ -606,15 +703,16 @@ choose_kex(struct kex *k, char *client, char *server)
|
||||
static int
|
||||
choose_hostkeyalg(struct kex *k, char *client, char *server)
|
||||
{
|
||||
char *hostkeyalg = match_list(client, server, NULL);
|
||||
k->hostkey_alg = match_list(client, server, NULL);
|
||||
|
||||
if (hostkeyalg == NULL)
|
||||
debug("kex: host key algorithm: %s",
|
||||
k->hostkey_alg ? k->hostkey_alg : "(no match)");
|
||||
if (k->hostkey_alg == NULL)
|
||||
return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
|
||||
k->hostkey_type = sshkey_type_from_name(hostkeyalg);
|
||||
k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
|
||||
if (k->hostkey_type == KEY_UNSPEC)
|
||||
return SSH_ERR_INTERNAL_ERROR;
|
||||
k->hostkey_nid = sshkey_ecdsa_nid_from_name(hostkeyalg);
|
||||
free(hostkeyalg);
|
||||
k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -653,8 +751,11 @@ kex_choose_conf(struct ssh *ssh)
|
||||
u_int mode, ctos, need, dh_need, authlen;
|
||||
int r, first_kex_follows;
|
||||
|
||||
if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0 ||
|
||||
(r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
|
||||
debug2("local %s KEXINIT proposal", kex->server ? "server" : "client");
|
||||
if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0)
|
||||
goto out;
|
||||
debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server");
|
||||
if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
|
||||
goto out;
|
||||
|
||||
if (kex->server) {
|
||||
@ -665,18 +766,30 @@ kex_choose_conf(struct ssh *ssh)
|
||||
sprop=peer;
|
||||
}
|
||||
|
||||
/* Check whether server offers roaming */
|
||||
if (!kex->server) {
|
||||
char *roaming = match_list(KEX_RESUME,
|
||||
peer[PROPOSAL_KEX_ALGS], NULL);
|
||||
/* Check whether client supports ext_info_c */
|
||||
if (kex->server) {
|
||||
char *ext;
|
||||
|
||||
if (roaming) {
|
||||
kex->roaming = 1;
|
||||
free(roaming);
|
||||
ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL);
|
||||
if (ext) {
|
||||
kex->ext_info_c = 1;
|
||||
free(ext);
|
||||
}
|
||||
}
|
||||
|
||||
/* Algorithm Negotiation */
|
||||
if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
|
||||
sprop[PROPOSAL_KEX_ALGS])) != 0) {
|
||||
kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
|
||||
peer[PROPOSAL_KEX_ALGS] = NULL;
|
||||
goto out;
|
||||
}
|
||||
if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
|
||||
sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
|
||||
kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
|
||||
peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
|
||||
goto out;
|
||||
}
|
||||
for (mode = 0; mode < MODE_MAX; mode++) {
|
||||
if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
@ -709,24 +822,12 @@ kex_choose_conf(struct ssh *ssh)
|
||||
peer[ncomp] = NULL;
|
||||
goto out;
|
||||
}
|
||||
debug("kex: %s %s %s %s",
|
||||
debug("kex: %s cipher: %s MAC: %s compression: %s",
|
||||
ctos ? "client->server" : "server->client",
|
||||
newkeys->enc.name,
|
||||
authlen == 0 ? newkeys->mac.name : "<implicit>",
|
||||
newkeys->comp.name);
|
||||
}
|
||||
if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
|
||||
sprop[PROPOSAL_KEX_ALGS])) != 0) {
|
||||
kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
|
||||
peer[PROPOSAL_KEX_ALGS] = NULL;
|
||||
goto out;
|
||||
}
|
||||
if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
|
||||
sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
|
||||
kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
|
||||
peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
|
||||
goto out;
|
||||
}
|
||||
need = dh_need = 0;
|
||||
for (mode = 0; mode < MODE_MAX; mode++) {
|
||||
newkeys = kex->newkeys[mode];
|
||||
@ -812,8 +913,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
|
||||
digest = NULL;
|
||||
r = 0;
|
||||
out:
|
||||
if (digest)
|
||||
free(digest);
|
||||
free(digest);
|
||||
ssh_digest_free(hashctx);
|
||||
return r;
|
||||
}
|
||||
|
13
kex.h
13
kex.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.h,v 1.73 2015/07/30 00:01:34 djm Exp $ */
|
||||
/* $OpenBSD: kex.h,v 1.76 2016/02/08 10:57:07 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -54,7 +54,6 @@
|
||||
#define KEX_DH14 "diffie-hellman-group14-sha1"
|
||||
#define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1"
|
||||
#define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256"
|
||||
#define KEX_RESUME "resume@appgate.com"
|
||||
#define KEX_ECDH_SHA2_NISTP256 "ecdh-sha2-nistp256"
|
||||
#define KEX_ECDH_SHA2_NISTP384 "ecdh-sha2-nistp384"
|
||||
#define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521"
|
||||
@ -129,10 +128,12 @@ struct kex {
|
||||
u_int dh_need;
|
||||
int server;
|
||||
char *name;
|
||||
char *hostkey_alg;
|
||||
int hostkey_type;
|
||||
int hostkey_nid;
|
||||
u_int kex_type;
|
||||
int roaming;
|
||||
int rsa_sha2;
|
||||
int ext_info_c;
|
||||
struct sshbuf *my;
|
||||
struct sshbuf *peer;
|
||||
sig_atomic_t done;
|
||||
@ -146,8 +147,8 @@ struct kex {
|
||||
struct sshkey *(*load_host_public_key)(int, int, struct ssh *);
|
||||
struct sshkey *(*load_host_private_key)(int, int, struct ssh *);
|
||||
int (*host_key_index)(struct sshkey *, int, struct ssh *);
|
||||
int (*sign)(struct sshkey *, struct sshkey *,
|
||||
u_char **, size_t *, const u_char *, size_t, u_int);
|
||||
int (*sign)(struct sshkey *, struct sshkey *, u_char **, size_t *,
|
||||
const u_char *, size_t, const char *, u_int);
|
||||
int (*kex[KEX_MAX])(struct ssh *);
|
||||
/* kex specific state */
|
||||
DH *dh; /* DH */
|
||||
@ -174,9 +175,11 @@ void kex_prop_free(char **);
|
||||
|
||||
int kex_send_kexinit(struct ssh *);
|
||||
int kex_input_kexinit(int, u_int32_t, void *);
|
||||
int kex_input_ext_info(int, u_int32_t, void *);
|
||||
int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *);
|
||||
int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *);
|
||||
int kex_send_newkeys(struct ssh *);
|
||||
int kex_start_rekex(struct ssh *);
|
||||
|
||||
int kexdh_client(struct ssh *);
|
||||
int kexdh_server(struct ssh *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexc25519s.c,v 1.9 2015/04/27 00:37:53 dtucker Exp $ */
|
||||
/* $OpenBSD: kexc25519s.c,v 1.10 2015/12/04 16:41:28 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
@ -134,8 +134,8 @@ input_kex_c25519_init(int type, u_int32_t seq, void *ctxt)
|
||||
}
|
||||
|
||||
/* sign H */
|
||||
if ((r = kex->sign(server_host_private, server_host_public,
|
||||
&signature, &slen, hash, hashlen, ssh->compat)) < 0)
|
||||
if ((r = kex->sign(server_host_private, server_host_public, &signature,
|
||||
&slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
|
||||
goto out;
|
||||
|
||||
/* send server hostkey, ECDH pubkey 'Q_S' and signed H */
|
||||
|
6
kexdhs.c
6
kexdhs.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexdhs.c,v 1.22 2015/01/26 06:10:03 djm Exp $ */
|
||||
/* $OpenBSD: kexdhs.c,v 1.23 2015/12/04 16:41:28 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -181,8 +181,8 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
|
||||
}
|
||||
|
||||
/* sign H */
|
||||
if ((r = kex->sign(server_host_private, server_host_public,
|
||||
&signature, &slen, hash, hashlen, ssh->compat)) < 0)
|
||||
if ((r = kex->sign(server_host_private, server_host_public, &signature,
|
||||
&slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
|
||||
goto out;
|
||||
|
||||
/* destroy_sensitive_data(); */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexecdhs.c,v 1.14 2015/01/26 06:10:03 djm Exp $ */
|
||||
/* $OpenBSD: kexecdhs.c,v 1.15 2015/12/04 16:41:28 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
@ -169,8 +169,8 @@ input_kex_ecdh_init(int type, u_int32_t seq, void *ctxt)
|
||||
}
|
||||
|
||||
/* sign H */
|
||||
if ((r = kex->sign(server_host_private, server_host_public,
|
||||
&signature, &slen, hash, hashlen, ssh->compat)) < 0)
|
||||
if ((r = kex->sign(server_host_private, server_host_public, &signature,
|
||||
&slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
|
||||
goto out;
|
||||
|
||||
/* destroy_sensitive_data(); */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexgexs.c,v 1.25 2015/04/13 02:04:08 djm Exp $ */
|
||||
/* $OpenBSD: kexgexs.c,v 1.26 2015/12/04 16:41:28 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
@ -220,8 +220,8 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt)
|
||||
}
|
||||
|
||||
/* sign H */
|
||||
if ((r = kex->sign(server_host_private, server_host_public,
|
||||
&signature, &slen, hash, hashlen, ssh->compat)) < 0)
|
||||
if ((r = kex->sign(server_host_private, server_host_public, &signature,
|
||||
&slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
|
||||
goto out;
|
||||
|
||||
/* destroy_sensitive_data(); */
|
||||
|
6
key.c
6
key.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: key.c,v 1.128 2015/07/03 03:43:18 djm Exp $ */
|
||||
/* $OpenBSD: key.c,v 1.129 2015/12/04 16:41:28 markus Exp $ */
|
||||
/*
|
||||
* placed in the public domain
|
||||
*/
|
||||
@ -132,7 +132,7 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
|
||||
|
||||
int
|
||||
key_sign(const Key *key, u_char **sigp, u_int *lenp,
|
||||
const u_char *data, u_int datalen)
|
||||
const u_char *data, u_int datalen, const char *alg)
|
||||
{
|
||||
int r;
|
||||
u_char *sig;
|
||||
@ -143,7 +143,7 @@ key_sign(const Key *key, u_char **sigp, u_int *lenp,
|
||||
if (lenp != NULL)
|
||||
*lenp = 0;
|
||||
if ((r = sshkey_sign(key, &sig, &siglen,
|
||||
data, datalen, datafellows)) != 0) {
|
||||
data, datalen, alg, datafellows)) != 0) {
|
||||
fatal_on_fatal_errors(r, __func__, 0);
|
||||
error("%s: %s", __func__, ssh_err(r));
|
||||
return -1;
|
||||
|
5
key.h
5
key.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: key.h,v 1.48 2015/07/03 03:43:18 djm Exp $ */
|
||||
/* $OpenBSD: key.h,v 1.49 2015/12/04 16:41:28 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -84,7 +84,8 @@ int key_ec_validate_private(const EC_KEY *);
|
||||
Key *key_from_blob(const u_char *, u_int);
|
||||
int key_to_blob(const Key *, u_char **, u_int *);
|
||||
|
||||
int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
|
||||
int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int,
|
||||
const char *);
|
||||
int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
void key_private_serialize(const Key *, struct sshbuf *);
|
||||
|
23
krl.c
23
krl.c
@ -14,7 +14,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $OpenBSD: krl.c,v 1.33 2015/07/03 03:43:18 djm Exp $ */
|
||||
/* $OpenBSD: krl.c,v 1.37 2015/12/31 00:33:52 djm Exp $ */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
@ -723,7 +723,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
|
||||
if ((r = sshbuf_put(buf, KRL_MAGIC, sizeof(KRL_MAGIC) - 1)) != 0 ||
|
||||
(r = sshbuf_put_u32(buf, KRL_FORMAT_VERSION)) != 0 ||
|
||||
(r = sshbuf_put_u64(buf, krl->krl_version)) != 0 ||
|
||||
(r = sshbuf_put_u64(buf, krl->generated_date) != 0) ||
|
||||
(r = sshbuf_put_u64(buf, krl->generated_date)) != 0 ||
|
||||
(r = sshbuf_put_u64(buf, krl->flags)) != 0 ||
|
||||
(r = sshbuf_put_string(buf, NULL, 0)) != 0 ||
|
||||
(r = sshbuf_put_cstring(buf, krl->comment)) != 0)
|
||||
@ -772,7 +772,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
|
||||
goto out;
|
||||
|
||||
if ((r = sshkey_sign(sign_keys[i], &sblob, &slen,
|
||||
sshbuf_ptr(buf), sshbuf_len(buf), 0)) != 0)
|
||||
sshbuf_ptr(buf), sshbuf_len(buf), NULL, 0)) != 0)
|
||||
goto out;
|
||||
KRL_DBG(("%s: signature sig len %zu", __func__, slen));
|
||||
if ((r = sshbuf_put_string(buf, sblob, slen)) != 0)
|
||||
@ -826,10 +826,8 @@ parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl)
|
||||
goto out;
|
||||
|
||||
while (sshbuf_len(buf) > 0) {
|
||||
if (subsect != NULL) {
|
||||
sshbuf_free(subsect);
|
||||
subsect = NULL;
|
||||
}
|
||||
sshbuf_free(subsect);
|
||||
subsect = NULL;
|
||||
if ((r = sshbuf_get_u8(buf, &type)) != 0 ||
|
||||
(r = sshbuf_froms(buf, &subsect)) != 0)
|
||||
goto out;
|
||||
@ -1017,7 +1015,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
|
||||
}
|
||||
/* Check signature over entire KRL up to this point */
|
||||
if ((r = sshkey_verify(key, blob, blen,
|
||||
sshbuf_ptr(buf), sshbuf_len(buf) - sig_off, 0)) != 0)
|
||||
sshbuf_ptr(buf), sig_off, 0)) != 0)
|
||||
goto out;
|
||||
/* Check if this key has already signed this KRL */
|
||||
for (i = 0; i < nca_used; i++) {
|
||||
@ -1038,7 +1036,6 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
|
||||
ca_used = tmp_ca_used;
|
||||
ca_used[nca_used++] = key;
|
||||
key = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sshbuf_len(copy) != 0) {
|
||||
@ -1059,10 +1056,8 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
|
||||
if ((r = sshbuf_consume(copy, sects_off)) != 0)
|
||||
goto out;
|
||||
while (sshbuf_len(copy) > 0) {
|
||||
if (sect != NULL) {
|
||||
sshbuf_free(sect);
|
||||
sect = NULL;
|
||||
}
|
||||
sshbuf_free(sect);
|
||||
sect = NULL;
|
||||
if ((r = sshbuf_get_u8(copy, &type)) != 0 ||
|
||||
(r = sshbuf_froms(copy, §)) != 0)
|
||||
goto out;
|
||||
@ -1105,7 +1100,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
|
||||
r = SSH_ERR_INVALID_FORMAT;
|
||||
goto out;
|
||||
}
|
||||
if (sshbuf_len(sect) > 0) {
|
||||
if (sect != NULL && sshbuf_len(sect) > 0) {
|
||||
error("KRL section contains unparsed data");
|
||||
r = SSH_ERR_INVALID_FORMAT;
|
||||
goto out;
|
||||
|
3
krl.h
3
krl.h
@ -14,7 +14,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $OpenBSD: krl.h,v 1.4 2015/01/13 19:06:49 djm Exp $ */
|
||||
/* $OpenBSD: krl.h,v 1.5 2015/12/30 23:46:14 djm Exp $ */
|
||||
|
||||
#ifndef _KRL_H
|
||||
#define _KRL_H
|
||||
@ -43,7 +43,6 @@ struct ssh_krl;
|
||||
struct ssh_krl *ssh_krl_init(void);
|
||||
void ssh_krl_free(struct ssh_krl *krl);
|
||||
void ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version);
|
||||
void ssh_krl_set_sign_key(struct ssh_krl *krl, const struct sshkey *sign_key);
|
||||
int ssh_krl_set_comment(struct ssh_krl *krl, const char *comment);
|
||||
int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl,
|
||||
const struct sshkey *ca_key, u_int64_t serial);
|
||||
|
@ -150,6 +150,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
|
58
misc.c
58
misc.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: misc.c,v 1.97 2015/04/24 01:36:00 deraadt Exp $ */
|
||||
/* $OpenBSD: misc.c,v 1.101 2016/01/20 09:22:39 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
|
||||
@ -29,6 +29,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <limits.h>
|
||||
@ -604,6 +605,8 @@ percent_expand(const char *string, ...)
|
||||
/* %% case */
|
||||
if (*string == '%')
|
||||
goto append;
|
||||
if (*string == '\0')
|
||||
fatal("%s: invalid format", __func__);
|
||||
for (j = 0; j < num_keys; j++) {
|
||||
if (strchr(keys[j].key, *string) != NULL) {
|
||||
i = strlcat(buf, keys[j].repl, sizeof(buf));
|
||||
@ -653,62 +656,63 @@ tun_open(int tun, int mode)
|
||||
struct ifreq ifr;
|
||||
char name[100];
|
||||
int fd = -1, sock;
|
||||
const char *tunbase = "tun";
|
||||
|
||||
if (mode == SSH_TUNMODE_ETHERNET)
|
||||
tunbase = "tap";
|
||||
|
||||
/* Open the tunnel device */
|
||||
if (tun <= SSH_TUNID_MAX) {
|
||||
snprintf(name, sizeof(name), "/dev/tun%d", tun);
|
||||
snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun);
|
||||
fd = open(name, O_RDWR);
|
||||
} else if (tun == SSH_TUNID_ANY) {
|
||||
for (tun = 100; tun >= 0; tun--) {
|
||||
snprintf(name, sizeof(name), "/dev/tun%d", tun);
|
||||
snprintf(name, sizeof(name), "/dev/%s%d",
|
||||
tunbase, tun);
|
||||
if ((fd = open(name, O_RDWR)) >= 0)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
debug("%s: invalid tunnel %u", __func__, tun);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
debug("%s: %s open failed: %s", __func__, name, strerror(errno));
|
||||
return (-1);
|
||||
debug("%s: %s open: %s", __func__, name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
|
||||
|
||||
/* Set the tunnel device operation mode */
|
||||
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun);
|
||||
/* Bring interface up if it is not already */
|
||||
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun);
|
||||
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
goto failed;
|
||||
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
|
||||
debug("%s: get interface %s flags: %s", __func__,
|
||||
ifr.ifr_name, strerror(errno));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Set interface mode */
|
||||
ifr.ifr_flags &= ~IFF_UP;
|
||||
if (mode == SSH_TUNMODE_ETHERNET)
|
||||
ifr.ifr_flags |= IFF_LINK0;
|
||||
else
|
||||
ifr.ifr_flags &= ~IFF_LINK0;
|
||||
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
|
||||
goto failed;
|
||||
|
||||
/* Bring interface up */
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
|
||||
goto failed;
|
||||
if (!(ifr.ifr_flags & IFF_UP)) {
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
|
||||
debug("%s: activate interface %s: %s", __func__,
|
||||
ifr.ifr_name, strerror(errno));
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
close(sock);
|
||||
return (fd);
|
||||
return fd;
|
||||
|
||||
failed:
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
if (sock >= 0)
|
||||
close(sock);
|
||||
debug("%s: failed to set %s mode %d: %s", __func__, name,
|
||||
mode, strerror(errno));
|
||||
return (-1);
|
||||
return -1;
|
||||
#else
|
||||
error("Tunnel interfaces are not supported on this platform");
|
||||
return (-1);
|
||||
@ -1107,7 +1111,7 @@ unix_listener(const char *path, int backlog, int unlink_first)
|
||||
void
|
||||
sock_set_v6only(int s)
|
||||
{
|
||||
#ifdef IPV6_V6ONLY
|
||||
#if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)
|
||||
int on = 1;
|
||||
|
||||
debug3("%s: set socket %d IPV6_V6ONLY", __func__, s);
|
||||
|
2
moduli.0
2
moduli.0
@ -71,4 +71,4 @@ STANDARDS
|
||||
the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006,
|
||||
2006.
|
||||
|
||||
OpenBSD 5.8 September 26, 2012 OpenBSD 5.8
|
||||
OpenBSD 5.9 September 26, 2012 OpenBSD 5.9
|
||||
|
39
monitor.c
39
monitor.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor.c,v 1.150 2015/06/22 23:42:16 djm Exp $ */
|
||||
/* $OpenBSD: monitor.c,v 1.157 2016/02/15 23:32:37 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
@ -100,7 +100,6 @@
|
||||
#include "monitor_fdpass.h"
|
||||
#include "compat.h"
|
||||
#include "ssh2.h"
|
||||
#include "roaming.h"
|
||||
#include "authfd.h"
|
||||
#include "match.h"
|
||||
#include "ssherr.h"
|
||||
@ -487,15 +486,10 @@ monitor_sync(struct monitor *pmonitor)
|
||||
static void *
|
||||
mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
|
||||
{
|
||||
size_t len = (size_t) size * ncount;
|
||||
void *address;
|
||||
|
||||
if (len == 0 || ncount > SIZE_MAX / size)
|
||||
if (size == 0 || ncount == 0 || ncount > SIZE_MAX / size)
|
||||
fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size);
|
||||
|
||||
address = mm_malloc(mm, len);
|
||||
|
||||
return (address);
|
||||
return mm_malloc(mm, size * ncount);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -690,17 +684,18 @@ mm_answer_sign(int sock, Buffer *m)
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
extern int auth_sock; /* XXX move to state struct? */
|
||||
struct sshkey *key;
|
||||
struct sshbuf *sigbuf;
|
||||
u_char *p;
|
||||
u_char *signature;
|
||||
size_t datlen, siglen;
|
||||
struct sshbuf *sigbuf = NULL;
|
||||
u_char *p = NULL, *signature = NULL;
|
||||
char *alg = NULL;
|
||||
size_t datlen, siglen, alglen;
|
||||
int r, keyid, is_proof = 0;
|
||||
const char proof_req[] = "hostkeys-prove-00@openssh.com";
|
||||
|
||||
debug3("%s", __func__);
|
||||
|
||||
if ((r = sshbuf_get_u32(m, &keyid)) != 0 ||
|
||||
(r = sshbuf_get_string(m, &p, &datlen)) != 0)
|
||||
(r = sshbuf_get_string(m, &p, &datlen)) != 0 ||
|
||||
(r = sshbuf_get_cstring(m, &alg, &alglen)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
/*
|
||||
@ -727,7 +722,7 @@ mm_answer_sign(int sock, Buffer *m)
|
||||
fatal("%s: sshbuf_new", __func__);
|
||||
if ((r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 ||
|
||||
(r = sshbuf_put_string(sigbuf, session_id2,
|
||||
session_id2_len) != 0) ||
|
||||
session_id2_len)) != 0 ||
|
||||
(r = sshkey_puts(key, sigbuf)) != 0)
|
||||
fatal("%s: couldn't prepare private key "
|
||||
"proof buffer: %s", __func__, ssh_err(r));
|
||||
@ -747,14 +742,14 @@ mm_answer_sign(int sock, Buffer *m)
|
||||
}
|
||||
|
||||
if ((key = get_hostkey_by_index(keyid)) != NULL) {
|
||||
if ((r = sshkey_sign(key, &signature, &siglen, p, datlen,
|
||||
if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
|
||||
datafellows)) != 0)
|
||||
fatal("%s: sshkey_sign failed: %s",
|
||||
__func__, ssh_err(r));
|
||||
} else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
|
||||
auth_sock > 0) {
|
||||
if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen,
|
||||
p, datlen, datafellows)) != 0) {
|
||||
p, datlen, alg, datafellows)) != 0) {
|
||||
fatal("%s: ssh_agent_sign failed: %s",
|
||||
__func__, ssh_err(r));
|
||||
}
|
||||
@ -768,6 +763,7 @@ mm_answer_sign(int sock, Buffer *m)
|
||||
if ((r = sshbuf_put_string(m, signature, siglen)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
free(alg);
|
||||
free(p);
|
||||
free(signature);
|
||||
|
||||
@ -971,7 +967,7 @@ mm_answer_bsdauthrespond(int sock, Buffer *m)
|
||||
char *response;
|
||||
int authok;
|
||||
|
||||
if (authctxt->as == 0)
|
||||
if (authctxt->as == NULL)
|
||||
fatal("%s: no bsd auth session", __func__);
|
||||
|
||||
response = buffer_get_string(m, NULL);
|
||||
@ -1040,7 +1036,8 @@ mm_answer_skeyrespond(int sock, Buffer *m)
|
||||
debug3("%s: sending authenticated: %d", __func__, authok);
|
||||
mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m);
|
||||
|
||||
auth_method = "skey";
|
||||
auth_method = "keyboard-interactive";
|
||||
auth_submethod = "skey";
|
||||
|
||||
return (authok != 0);
|
||||
}
|
||||
@ -1449,7 +1446,7 @@ mm_answer_keyverify(int sock, Buffer *m)
|
||||
__func__, key, (verified == 1) ? "verified" : "unverified");
|
||||
|
||||
/* If auth was successful then record key to ensure it isn't reused */
|
||||
if (verified == 1)
|
||||
if (verified == 1 && key_blobtype == MM_USERKEY)
|
||||
auth2_record_userkey(authctxt, key);
|
||||
else
|
||||
key_free(key);
|
||||
@ -1852,7 +1849,7 @@ monitor_apply_keystate(struct monitor *pmonitor)
|
||||
sshbuf_free(child_state);
|
||||
child_state = NULL;
|
||||
|
||||
if ((kex = ssh->kex) != 0) {
|
||||
if ((kex = ssh->kex) != NULL) {
|
||||
/* XXX set callbacks */
|
||||
#ifdef WITH_OPENSSL
|
||||
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.85 2015/05/01 03:23:51 djm Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.87 2016/01/14 16:17:40 markus Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
@ -80,7 +80,6 @@
|
||||
#include "channels.h"
|
||||
#include "session.h"
|
||||
#include "servconf.h"
|
||||
#include "roaming.h"
|
||||
|
||||
#include "ssherr.h"
|
||||
|
||||
@ -218,7 +217,7 @@ mm_choose_dh(int min, int nbits, int max)
|
||||
|
||||
int
|
||||
mm_key_sign(Key *key, u_char **sigp, u_int *lenp,
|
||||
const u_char *data, u_int datalen)
|
||||
const u_char *data, u_int datalen, const char *hostkey_alg)
|
||||
{
|
||||
struct kex *kex = *pmonitor->m_pkex;
|
||||
Buffer m;
|
||||
@ -228,6 +227,7 @@ mm_key_sign(Key *key, u_char **sigp, u_int *lenp,
|
||||
buffer_init(&m);
|
||||
buffer_put_int(&m, kex->host_key_index(key, 0, active_state));
|
||||
buffer_put_string(&m, data, datalen);
|
||||
buffer_put_cstring(&m, hostkey_alg);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor_wrap.h,v 1.27 2015/05/01 03:23:51 djm Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.h,v 1.29 2015/12/04 16:41:28 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
@ -40,7 +40,7 @@ struct Authctxt;
|
||||
void mm_log_handler(LogLevel, const char *, void *);
|
||||
int mm_is_monitor(void);
|
||||
DH *mm_choose_dh(int, int, int);
|
||||
int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int);
|
||||
int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *);
|
||||
void mm_inform_authserv(char *, char *);
|
||||
struct passwd *mm_getpwnamallow(const char *);
|
||||
char *mm_auth2_read_banner(void);
|
||||
|
34
mux.c
34
mux.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mux.c,v 1.54 2015/08/19 23:18:26 djm Exp $ */
|
||||
/* $OpenBSD: mux.c,v 1.58 2016/01/13 23:04:47 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
@ -1354,16 +1354,18 @@ mux_session_confirm(int id, int success, void *arg)
|
||||
char *proto, *data;
|
||||
|
||||
/* Get reasonable local authentication information. */
|
||||
client_x11_get_proto(display, options.xauth_location,
|
||||
if (client_x11_get_proto(display, options.xauth_location,
|
||||
options.forward_x11_trusted, options.forward_x11_timeout,
|
||||
&proto, &data);
|
||||
/* Request forwarding with authentication spoofing. */
|
||||
debug("Requesting X11 forwarding with authentication "
|
||||
"spoofing.");
|
||||
x11_request_forwarding_with_spoofing(id, display, proto,
|
||||
data, 1);
|
||||
client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN);
|
||||
/* XXX exit_on_forward_failure */
|
||||
&proto, &data) == 0) {
|
||||
/* Request forwarding with authentication spoofing. */
|
||||
debug("Requesting X11 forwarding with authentication "
|
||||
"spoofing.");
|
||||
x11_request_forwarding_with_spoofing(id, display, proto,
|
||||
data, 1);
|
||||
/* XXX exit_on_forward_failure */
|
||||
client_expect_confirm(id, "X11 forwarding",
|
||||
CONFIRM_WARN);
|
||||
}
|
||||
}
|
||||
|
||||
if (cctx->want_agent_fwd && options.forward_agent) {
|
||||
@ -1744,7 +1746,7 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
|
||||
fwd->connect_host ? fwd->connect_host : "",
|
||||
fwd->connect_port);
|
||||
if (muxclient_command == SSHMUX_COMMAND_FORWARD)
|
||||
fprintf(stdout, "%u\n", fwd->allocated_port);
|
||||
fprintf(stdout, "%i\n", fwd->allocated_port);
|
||||
break;
|
||||
case MUX_S_PERMISSION_DENIED:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
@ -1889,6 +1891,10 @@ mux_client_request_session(int fd)
|
||||
}
|
||||
muxclient_request_id++;
|
||||
|
||||
if (pledge("stdio proc tty", NULL) == -1)
|
||||
fatal("%s pledge(): %s", __func__, strerror(errno));
|
||||
platform_pledge_mux();
|
||||
|
||||
signal(SIGHUP, control_client_sighandler);
|
||||
signal(SIGINT, control_client_sighandler);
|
||||
signal(SIGTERM, control_client_sighandler);
|
||||
@ -1996,6 +2002,10 @@ mux_client_request_stdio_fwd(int fd)
|
||||
mm_send_fd(fd, STDOUT_FILENO) == -1)
|
||||
fatal("%s: send fds failed", __func__);
|
||||
|
||||
if (pledge("stdio proc tty", NULL) == -1)
|
||||
fatal("%s pledge(): %s", __func__, strerror(errno));
|
||||
platform_pledge_mux();
|
||||
|
||||
debug3("%s: stdio forward request sent", __func__);
|
||||
|
||||
/* Read their reply */
|
||||
@ -2169,7 +2179,7 @@ muxclient(const char *path)
|
||||
case SSHMUX_COMMAND_ALIVE_CHECK:
|
||||
if ((pid = mux_client_request_alive(sock)) == 0)
|
||||
fatal("%s: master alive check failed", __func__);
|
||||
fprintf(stderr, "Master running (pid=%d)\r\n", pid);
|
||||
fprintf(stderr, "Master running (pid=%u)\r\n", pid);
|
||||
exit(0);
|
||||
case SSHMUX_COMMAND_TERMINATE:
|
||||
mux_client_request_terminate(sock);
|
||||
|
23
myproposal.h
23
myproposal.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: myproposal.h,v 1.47 2015/07/10 06:21:53 markus Exp $ */
|
||||
/* $OpenBSD: myproposal.h,v 1.50 2016/02/09 05:30:04 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -101,7 +101,9 @@
|
||||
"ssh-rsa-cert-v01@openssh.com," \
|
||||
HOSTKEY_ECDSA_METHODS \
|
||||
"ssh-ed25519," \
|
||||
"ssh-rsa" \
|
||||
"rsa-sha2-512," \
|
||||
"rsa-sha2-256," \
|
||||
"ssh-rsa"
|
||||
|
||||
/* the actual algorithms */
|
||||
|
||||
@ -111,9 +113,7 @@
|
||||
AESGCM_CIPHER_MODES
|
||||
|
||||
#define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT "," \
|
||||
"arcfour256,arcfour128," \
|
||||
"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
|
||||
"aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se"
|
||||
"aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc"
|
||||
|
||||
#define KEX_SERVER_MAC \
|
||||
"umac-64-etm@openssh.com," \
|
||||
@ -127,18 +127,9 @@
|
||||
"hmac-sha2-512," \
|
||||
"hmac-sha1"
|
||||
|
||||
#define KEX_CLIENT_MAC KEX_SERVER_MAC "," \
|
||||
"hmac-md5-etm@openssh.com," \
|
||||
"hmac-ripemd160-etm@openssh.com," \
|
||||
"hmac-sha1-96-etm@openssh.com," \
|
||||
"hmac-md5-96-etm@openssh.com," \
|
||||
"hmac-md5," \
|
||||
"hmac-ripemd160," \
|
||||
"hmac-ripemd160@openssh.com," \
|
||||
"hmac-sha1-96," \
|
||||
"hmac-md5-96"
|
||||
#define KEX_CLIENT_MAC KEX_SERVER_MAC
|
||||
|
||||
#else
|
||||
#else /* WITH_OPENSSL */
|
||||
|
||||
#define KEX_SERVER_KEX \
|
||||
"curve25519-sha256@libssh.org"
|
||||
|
12
opacket.c
12
opacket.c
@ -235,18 +235,6 @@ packet_set_connection(int fd_in, int fd_out)
|
||||
fatal("%s: ssh_packet_set_connection failed", __func__);
|
||||
}
|
||||
|
||||
void
|
||||
packet_backup_state(void)
|
||||
{
|
||||
ssh_packet_backup_state(active_state, backup_state);
|
||||
}
|
||||
|
||||
void
|
||||
packet_restore_state(void)
|
||||
{
|
||||
ssh_packet_restore_state(active_state, backup_state);
|
||||
}
|
||||
|
||||
u_int
|
||||
packet_get_char(void)
|
||||
{
|
||||
|
@ -39,8 +39,6 @@ do { \
|
||||
void packet_close(void);
|
||||
u_int packet_get_char(void);
|
||||
u_int packet_get_int(void);
|
||||
void packet_backup_state(void);
|
||||
void packet_restore_state(void);
|
||||
void packet_set_connection(int, int);
|
||||
int packet_read_seqnr(u_int32_t *);
|
||||
int packet_read_poll_seqnr(u_int32_t *);
|
||||
@ -127,8 +125,6 @@ void packet_disconnect(const char *, ...)
|
||||
sshpkt_add_padding(active_state, (pad))
|
||||
#define packet_send_ignore(nbytes) \
|
||||
ssh_packet_send_ignore(active_state, (nbytes))
|
||||
#define packet_need_rekeying() \
|
||||
ssh_packet_need_rekeying(active_state)
|
||||
#define packet_set_server() \
|
||||
ssh_packet_set_server(active_state)
|
||||
#define packet_set_authenticated() \
|
||||
|
@ -276,3 +276,11 @@ getpgid(pid_t pid)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PLEDGE
|
||||
int
|
||||
pledge(const char *promises, const char *paths[])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -122,4 +122,8 @@ pid_t getpgid(pid_t);
|
||||
# define krb5_free_error_message(a,b) do { } while(0)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PLEDGE
|
||||
int pledge(const char *promises, const char *paths[]);
|
||||
#endif
|
||||
|
||||
#endif /* _BSD_MISC_H */
|
||||
|
@ -42,11 +42,11 @@ typedef unsigned int nfds_t;
|
||||
#define POLLIN 0x0001
|
||||
#define POLLOUT 0x0004
|
||||
#define POLLERR 0x0008
|
||||
#define POLLHUP 0x0010
|
||||
#define POLLNVAL 0x0020
|
||||
#if 0
|
||||
/* the following are currently not implemented */
|
||||
#define POLLPRI 0x0002
|
||||
#define POLLHUP 0x0010
|
||||
#define POLLNVAL 0x0020
|
||||
#define POLLRDNORM 0x0040
|
||||
#define POLLNORM POLLRDNORM
|
||||
#define POLLWRNORM POLLOUT
|
||||
|
@ -59,6 +59,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "glob.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -42,11 +42,15 @@
|
||||
!defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
|
||||
defined(BROKEN_GLOB)
|
||||
|
||||
#ifndef _GLOB_H_
|
||||
#define _GLOB_H_
|
||||
#ifndef _COMPAT_GLOB_H_
|
||||
#define _COMPAT_GLOB_H_
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
# define glob_t _ssh_compat_glob_t
|
||||
# define glob(a, b, c, d) _ssh__compat_glob(a, b, c, d)
|
||||
# define globfree(a) _ssh__compat_globfree(a)
|
||||
|
||||
struct stat;
|
||||
typedef struct {
|
||||
int gl_pathc; /* Count of total paths so far. */
|
||||
|
@ -39,7 +39,6 @@
|
||||
/* OpenBSD function replacements */
|
||||
#include "base64.h"
|
||||
#include "sigact.h"
|
||||
#include "glob.h"
|
||||
#include "readpassphrase.h"
|
||||
#include "vis.h"
|
||||
#include "getrrsetbyname.h"
|
||||
|
@ -227,3 +227,139 @@ solaris_set_default_project(struct passwd *pw)
|
||||
}
|
||||
}
|
||||
#endif /* USE_SOLARIS_PROJECTS */
|
||||
|
||||
#ifdef USE_SOLARIS_PRIVS
|
||||
# ifdef HAVE_PRIV_H
|
||||
# include <priv.h>
|
||||
# endif
|
||||
|
||||
priv_set_t *
|
||||
solaris_basic_privset(void)
|
||||
{
|
||||
priv_set_t *pset;
|
||||
|
||||
#ifdef HAVE_PRIV_BASICSET
|
||||
if ((pset = priv_allocset()) == NULL) {
|
||||
error("priv_allocset: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
priv_basicset(pset);
|
||||
#else
|
||||
if ((pset = priv_str_to_set("basic", ",", NULL)) == NULL) {
|
||||
error("priv_str_to_set: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return pset;
|
||||
}
|
||||
|
||||
void
|
||||
solaris_drop_privs_pinfo_net_fork_exec(void)
|
||||
{
|
||||
priv_set_t *pset = NULL, *npset = NULL;
|
||||
|
||||
/*
|
||||
* Note: this variant avoids dropping DAC filesystem rights, in case
|
||||
* the process calling it is running as root and should have the
|
||||
* ability to read/write/chown any file on the system.
|
||||
*
|
||||
* We start with the basic set, then *add* the DAC rights to it while
|
||||
* taking away other parts of BASIC we don't need. Then we intersect
|
||||
* this with our existing PERMITTED set. In this way we keep any
|
||||
* DAC rights we had before, while otherwise reducing ourselves to
|
||||
* the minimum set of privileges we need to proceed.
|
||||
*
|
||||
* This also means we drop any other parts of "root" that we don't
|
||||
* need (e.g. the ability to kill any process, create new device nodes
|
||||
* etc etc).
|
||||
*/
|
||||
|
||||
if ((pset = priv_allocset()) == NULL)
|
||||
fatal("priv_allocset: %s", strerror(errno));
|
||||
if ((npset = solaris_basic_privset()) == NULL)
|
||||
fatal("solaris_basic_privset: %s", strerror(errno));
|
||||
|
||||
if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 ||
|
||||
priv_addset(npset, PRIV_FILE_DAC_READ) != 0 ||
|
||||
priv_addset(npset, PRIV_FILE_DAC_SEARCH) != 0 ||
|
||||
priv_addset(npset, PRIV_FILE_DAC_WRITE) != 0 ||
|
||||
priv_addset(npset, PRIV_FILE_OWNER) != 0)
|
||||
fatal("priv_addset: %s", strerror(errno));
|
||||
|
||||
if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 ||
|
||||
#ifdef PRIV_NET_ACCESS
|
||||
priv_delset(npset, PRIV_NET_ACCESS) != 0 ||
|
||||
#endif
|
||||
priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
|
||||
priv_delset(npset, PRIV_PROC_FORK) != 0 ||
|
||||
priv_delset(npset, PRIV_PROC_INFO) != 0 ||
|
||||
priv_delset(npset, PRIV_PROC_SESSION) != 0)
|
||||
fatal("priv_delset: %s", strerror(errno));
|
||||
|
||||
if (getppriv(PRIV_PERMITTED, pset) != 0)
|
||||
fatal("getppriv: %s", strerror(errno));
|
||||
|
||||
priv_intersect(pset, npset);
|
||||
|
||||
if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 ||
|
||||
setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 ||
|
||||
setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0)
|
||||
fatal("setppriv: %s", strerror(errno));
|
||||
|
||||
priv_freeset(pset);
|
||||
priv_freeset(npset);
|
||||
}
|
||||
|
||||
void
|
||||
solaris_drop_privs_root_pinfo_net(void)
|
||||
{
|
||||
priv_set_t *pset = NULL;
|
||||
|
||||
/* Start with "basic" and drop everything we don't need. */
|
||||
if ((pset = solaris_basic_privset()) == NULL)
|
||||
fatal("solaris_basic_privset: %s", strerror(errno));
|
||||
|
||||
if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
|
||||
#ifdef PRIV_NET_ACCESS
|
||||
priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
|
||||
#endif
|
||||
priv_delset(pset, PRIV_PROC_INFO) != 0 ||
|
||||
priv_delset(pset, PRIV_PROC_SESSION) != 0)
|
||||
fatal("priv_delset: %s", strerror(errno));
|
||||
|
||||
if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
|
||||
setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||
|
||||
setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0)
|
||||
fatal("setppriv: %s", strerror(errno));
|
||||
|
||||
priv_freeset(pset);
|
||||
}
|
||||
|
||||
void
|
||||
solaris_drop_privs_root_pinfo_net_exec(void)
|
||||
{
|
||||
priv_set_t *pset = NULL;
|
||||
|
||||
|
||||
/* Start with "basic" and drop everything we don't need. */
|
||||
if ((pset = solaris_basic_privset()) == NULL)
|
||||
fatal("solaris_basic_privset: %s", strerror(errno));
|
||||
|
||||
if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
|
||||
#ifdef PRIV_NET_ACCESS
|
||||
priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
|
||||
#endif
|
||||
priv_delset(pset, PRIV_PROC_EXEC) != 0 ||
|
||||
priv_delset(pset, PRIV_PROC_INFO) != 0 ||
|
||||
priv_delset(pset, PRIV_PROC_SESSION) != 0)
|
||||
fatal("priv_delset: %s", strerror(errno));
|
||||
|
||||
if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
|
||||
setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||
|
||||
setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0)
|
||||
fatal("setppriv: %s", strerror(errno));
|
||||
|
||||
priv_freeset(pset);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -26,5 +26,11 @@ 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 *);
|
||||
# ifdef USE_SOLARIS_PRIVS
|
||||
priv_set_t *solaris_basic_privset(void);
|
||||
void solaris_drop_privs_pinfo_net_fork_exec(void);
|
||||
void solaris_drop_privs_root_pinfo_net(void);
|
||||
void solaris_drop_privs_root_pinfo_net_exec(void);
|
||||
# endif /* USE_SOLARIS_PRIVS */
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: realpath.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
|
||||
/* $OpenBSD: realpath.c,v 1.20 2015/10/13 20:55:37 millert Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
|
||||
*
|
||||
@ -42,6 +42,13 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef SYMLOOP_MAX
|
||||
# define SYMLOOP_MAX 32
|
||||
#endif
|
||||
|
||||
/* A slightly modified copy of this file exists in libexec/ld.so */
|
||||
|
||||
/*
|
||||
* char *realpath(const char *path, char resolved[PATH_MAX]);
|
||||
@ -51,16 +58,30 @@
|
||||
* in which case the path which caused trouble is left in (resolved).
|
||||
*/
|
||||
char *
|
||||
realpath(const char *path, char resolved[PATH_MAX])
|
||||
realpath(const char *path, char *resolved)
|
||||
{
|
||||
struct stat sb;
|
||||
char *p, *q, *s;
|
||||
size_t left_len, resolved_len;
|
||||
unsigned symlinks;
|
||||
int serrno, slen;
|
||||
int serrno, slen, mem_allocated;
|
||||
char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
|
||||
|
||||
if (path[0] == '\0') {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
serrno = errno;
|
||||
|
||||
if (resolved == NULL) {
|
||||
resolved = malloc(PATH_MAX);
|
||||
if (resolved == NULL)
|
||||
return (NULL);
|
||||
mem_allocated = 1;
|
||||
} else
|
||||
mem_allocated = 0;
|
||||
|
||||
symlinks = 0;
|
||||
if (path[0] == '/') {
|
||||
resolved[0] = '/';
|
||||
@ -71,7 +92,10 @@ realpath(const char *path, char resolved[PATH_MAX])
|
||||
left_len = strlcpy(left, path + 1, sizeof(left));
|
||||
} else {
|
||||
if (getcwd(resolved, PATH_MAX) == NULL) {
|
||||
strlcpy(resolved, ".", PATH_MAX);
|
||||
if (mem_allocated)
|
||||
free(resolved);
|
||||
else
|
||||
strlcpy(resolved, ".", PATH_MAX);
|
||||
return (NULL);
|
||||
}
|
||||
resolved_len = strlen(resolved);
|
||||
@ -79,7 +103,7 @@ realpath(const char *path, char resolved[PATH_MAX])
|
||||
}
|
||||
if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
return (NULL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -94,7 +118,7 @@ realpath(const char *path, char resolved[PATH_MAX])
|
||||
s = p ? p : left + left_len;
|
||||
if (s - left >= (ptrdiff_t)sizeof(next_token)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return (NULL);
|
||||
goto err;
|
||||
}
|
||||
memcpy(next_token, left, s - left);
|
||||
next_token[s - left] = '\0';
|
||||
@ -104,7 +128,7 @@ realpath(const char *path, char resolved[PATH_MAX])
|
||||
if (resolved[resolved_len - 1] != '/') {
|
||||
if (resolved_len + 1 >= PATH_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
return (NULL);
|
||||
goto err;
|
||||
}
|
||||
resolved[resolved_len++] = '/';
|
||||
resolved[resolved_len] = '\0';
|
||||
@ -135,23 +159,23 @@ realpath(const char *path, char resolved[PATH_MAX])
|
||||
resolved_len = strlcat(resolved, next_token, PATH_MAX);
|
||||
if (resolved_len >= PATH_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
return (NULL);
|
||||
goto err;
|
||||
}
|
||||
if (lstat(resolved, &sb) != 0) {
|
||||
if (errno == ENOENT && p == NULL) {
|
||||
errno = serrno;
|
||||
return (resolved);
|
||||
}
|
||||
return (NULL);
|
||||
goto err;
|
||||
}
|
||||
if (S_ISLNK(sb.st_mode)) {
|
||||
if (symlinks++ > MAXSYMLINKS) {
|
||||
if (symlinks++ > SYMLOOP_MAX) {
|
||||
errno = ELOOP;
|
||||
return (NULL);
|
||||
goto err;
|
||||
}
|
||||
slen = readlink(resolved, symlink, sizeof(symlink) - 1);
|
||||
if (slen < 0)
|
||||
return (NULL);
|
||||
goto err;
|
||||
symlink[slen] = '\0';
|
||||
if (symlink[0] == '/') {
|
||||
resolved[1] = 0;
|
||||
@ -174,15 +198,15 @@ realpath(const char *path, char resolved[PATH_MAX])
|
||||
if (slen + 1 >=
|
||||
(ptrdiff_t)sizeof(symlink)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return (NULL);
|
||||
goto err;
|
||||
}
|
||||
symlink[slen] = '/';
|
||||
symlink[slen + 1] = 0;
|
||||
}
|
||||
left_len = strlcat(symlink, left, sizeof(left));
|
||||
if (left_len >= sizeof(left)) {
|
||||
left_len = strlcat(symlink, left, sizeof(symlink));
|
||||
if (left_len >= sizeof(symlink)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return (NULL);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
left_len = strlcpy(left, symlink, sizeof(left));
|
||||
@ -196,5 +220,10 @@ realpath(const char *path, char resolved[PATH_MAX])
|
||||
if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
|
||||
resolved[resolved_len - 1] = '\0';
|
||||
return (resolved);
|
||||
|
||||
err:
|
||||
if (mem_allocated)
|
||||
free(resolved);
|
||||
return (NULL);
|
||||
}
|
||||
#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */
|
||||
|
366
packet.c
366
packet.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: packet.c,v 1.214 2015/08/20 22:32:42 deraadt Exp $ */
|
||||
/* $OpenBSD: packet.c,v 1.229 2016/02/17 22:20:14 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -83,7 +83,6 @@
|
||||
#include "channels.h"
|
||||
#include "ssh.h"
|
||||
#include "packet.h"
|
||||
#include "roaming.h"
|
||||
#include "ssherr.h"
|
||||
#include "sshbuf.h"
|
||||
|
||||
@ -181,8 +180,7 @@ struct session_state {
|
||||
struct packet_state p_read, p_send;
|
||||
|
||||
/* Volume-based rekeying */
|
||||
u_int64_t max_blocks_in, max_blocks_out;
|
||||
u_int32_t rekey_limit;
|
||||
u_int64_t max_blocks_in, max_blocks_out, rekey_limit;
|
||||
|
||||
/* Time-based rekeying */
|
||||
u_int32_t rekey_interval; /* how often in seconds */
|
||||
@ -261,6 +259,14 @@ ssh_alloc_session_state(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Returns nonzero if rekeying is in progress */
|
||||
int
|
||||
ssh_packet_is_rekeying(struct ssh *ssh)
|
||||
{
|
||||
return compat20 &&
|
||||
(ssh->state->rekeying || (ssh->kex != NULL && ssh->kex->done == 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the descriptors used for communication. Disables encryption until
|
||||
* packet_set_encryption_key is called.
|
||||
@ -338,7 +344,8 @@ ssh_packet_stop_discard(struct ssh *ssh)
|
||||
sshbuf_ptr(state->incoming_packet), PACKET_MAX_SIZE,
|
||||
NULL, 0);
|
||||
}
|
||||
logit("Finished discarding for %.200s", ssh_remote_ipaddr(ssh));
|
||||
logit("Finished discarding for %.200s port %d",
|
||||
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
|
||||
return SSH_ERR_MAC_INVALID;
|
||||
}
|
||||
|
||||
@ -455,16 +462,30 @@ ssh_packet_get_connection_out(struct ssh *ssh)
|
||||
const char *
|
||||
ssh_remote_ipaddr(struct ssh *ssh)
|
||||
{
|
||||
const int sock = ssh->state->connection_in;
|
||||
|
||||
/* Check whether we have cached the ipaddr. */
|
||||
if (ssh->remote_ipaddr == NULL)
|
||||
ssh->remote_ipaddr = ssh_packet_connection_is_on_socket(ssh) ?
|
||||
get_peer_ipaddr(ssh->state->connection_in) :
|
||||
strdup("UNKNOWN");
|
||||
if (ssh->remote_ipaddr == NULL)
|
||||
return "UNKNOWN";
|
||||
if (ssh->remote_ipaddr == NULL) {
|
||||
if (ssh_packet_connection_is_on_socket(ssh)) {
|
||||
ssh->remote_ipaddr = get_peer_ipaddr(sock);
|
||||
ssh->remote_port = get_sock_port(sock, 0);
|
||||
} else {
|
||||
ssh->remote_ipaddr = strdup("UNKNOWN");
|
||||
ssh->remote_port = 0;
|
||||
}
|
||||
}
|
||||
return ssh->remote_ipaddr;
|
||||
}
|
||||
|
||||
/* Returns the port number of the remote host. */
|
||||
|
||||
int
|
||||
ssh_remote_port(struct ssh *ssh)
|
||||
{
|
||||
(void)ssh_remote_ipaddr(ssh); /* Will lookup and cache. */
|
||||
return ssh->remote_port;
|
||||
}
|
||||
|
||||
/* Closes the connection and clears and frees internal data structures. */
|
||||
|
||||
void
|
||||
@ -519,10 +540,8 @@ ssh_packet_close(struct ssh *ssh)
|
||||
error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
|
||||
if ((r = cipher_cleanup(&state->receive_context)) != 0)
|
||||
error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
|
||||
if (ssh->remote_ipaddr) {
|
||||
free(ssh->remote_ipaddr);
|
||||
ssh->remote_ipaddr = NULL;
|
||||
}
|
||||
free(ssh->remote_ipaddr);
|
||||
ssh->remote_ipaddr = NULL;
|
||||
free(ssh->state);
|
||||
ssh->state = NULL;
|
||||
}
|
||||
@ -941,7 +960,12 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
|
||||
max_blocks = &state->max_blocks_in;
|
||||
}
|
||||
if (state->newkeys[mode] != NULL) {
|
||||
debug("set_newkeys: rekeying");
|
||||
debug("set_newkeys: rekeying, input %llu bytes %llu blocks, "
|
||||
"output %llu bytes %llu blocks",
|
||||
(unsigned long long)state->p_read.bytes,
|
||||
(unsigned long long)state->p_read.blocks,
|
||||
(unsigned long long)state->p_send.bytes,
|
||||
(unsigned long long)state->p_send.blocks);
|
||||
if ((r = cipher_cleanup(cc)) != 0)
|
||||
return r;
|
||||
enc = &state->newkeys[mode]->enc;
|
||||
@ -1009,9 +1033,55 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
|
||||
if (state->rekey_limit)
|
||||
*max_blocks = MIN(*max_blocks,
|
||||
state->rekey_limit / enc->block_size);
|
||||
debug("rekey after %llu blocks", (unsigned long long)*max_blocks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_PACKETS (1U<<31)
|
||||
static int
|
||||
ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len)
|
||||
{
|
||||
struct session_state *state = ssh->state;
|
||||
u_int32_t out_blocks;
|
||||
|
||||
/* XXX client can't cope with rekeying pre-auth */
|
||||
if (!state->after_authentication)
|
||||
return 0;
|
||||
|
||||
/* Haven't keyed yet or KEX in progress. */
|
||||
if (ssh->kex == NULL || ssh_packet_is_rekeying(ssh))
|
||||
return 0;
|
||||
|
||||
/* Peer can't rekey */
|
||||
if (ssh->compat & SSH_BUG_NOREKEY)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Permit one packet in or out per rekey - this allows us to
|
||||
* make progress when rekey limits are very small.
|
||||
*/
|
||||
if (state->p_send.packets == 0 && state->p_read.packets == 0)
|
||||
return 0;
|
||||
|
||||
/* Time-based rekeying */
|
||||
if (state->rekey_interval != 0 &&
|
||||
state->rekey_time + state->rekey_interval <= monotime())
|
||||
return 1;
|
||||
|
||||
/* Always rekey when MAX_PACKETS sent in either direction */
|
||||
if (state->p_send.packets > MAX_PACKETS ||
|
||||
state->p_read.packets > MAX_PACKETS)
|
||||
return 1;
|
||||
|
||||
/* Rekey after (cipher-specific) maxiumum blocks */
|
||||
out_blocks = roundup(outbound_packet_len,
|
||||
state->newkeys[MODE_OUT]->enc.block_size);
|
||||
return (state->max_blocks_out &&
|
||||
(state->p_send.blocks + out_blocks > state->max_blocks_out)) ||
|
||||
(state->max_blocks_in &&
|
||||
(state->p_read.blocks > state->max_blocks_in));
|
||||
}
|
||||
|
||||
/*
|
||||
* Delayed compression for SSH2 is enabled after authentication:
|
||||
* This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,
|
||||
@ -1050,6 +1120,20 @@ ssh_packet_enable_delayed_compress(struct ssh *ssh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used to mute debug logging for noisy packet types */
|
||||
static int
|
||||
ssh_packet_log_type(u_char type)
|
||||
{
|
||||
switch (type) {
|
||||
case SSH2_MSG_CHANNEL_DATA:
|
||||
case SSH2_MSG_CHANNEL_EXTENDED_DATA:
|
||||
case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
|
||||
*/
|
||||
@ -1078,7 +1162,8 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
|
||||
aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;
|
||||
|
||||
type = (sshbuf_ptr(state->outgoing_packet))[5];
|
||||
|
||||
if (ssh_packet_log_type(type))
|
||||
debug3("send packet: type %u", type);
|
||||
#ifdef PACKET_DEBUG
|
||||
fprintf(stderr, "plain: ");
|
||||
sshbuf_dump(state->outgoing_packet, stderr);
|
||||
@ -1200,34 +1285,58 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* returns non-zero if the specified packet type is usec by KEX */
|
||||
static int
|
||||
ssh_packet_type_is_kex(u_char type)
|
||||
{
|
||||
return
|
||||
type >= SSH2_MSG_TRANSPORT_MIN &&
|
||||
type <= SSH2_MSG_TRANSPORT_MAX &&
|
||||
type != SSH2_MSG_SERVICE_REQUEST &&
|
||||
type != SSH2_MSG_SERVICE_ACCEPT &&
|
||||
type != SSH2_MSG_EXT_INFO;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_packet_send2(struct ssh *ssh)
|
||||
{
|
||||
struct session_state *state = ssh->state;
|
||||
struct packet *p;
|
||||
u_char type;
|
||||
int r;
|
||||
int r, need_rekey;
|
||||
|
||||
if (sshbuf_len(state->outgoing_packet) < 6)
|
||||
return SSH_ERR_INTERNAL_ERROR;
|
||||
type = sshbuf_ptr(state->outgoing_packet)[5];
|
||||
need_rekey = !ssh_packet_type_is_kex(type) &&
|
||||
ssh_packet_need_rekeying(ssh, sshbuf_len(state->outgoing_packet));
|
||||
|
||||
/* during rekeying we can only send key exchange messages */
|
||||
if (state->rekeying) {
|
||||
if ((type < SSH2_MSG_TRANSPORT_MIN) ||
|
||||
(type > SSH2_MSG_TRANSPORT_MAX) ||
|
||||
(type == SSH2_MSG_SERVICE_REQUEST) ||
|
||||
(type == SSH2_MSG_SERVICE_ACCEPT)) {
|
||||
debug("enqueue packet: %u", type);
|
||||
p = calloc(1, sizeof(*p));
|
||||
if (p == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
p->type = type;
|
||||
p->payload = state->outgoing_packet;
|
||||
TAILQ_INSERT_TAIL(&state->outgoing, p, next);
|
||||
state->outgoing_packet = sshbuf_new();
|
||||
if (state->outgoing_packet == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
return 0;
|
||||
/*
|
||||
* During rekeying we can only send key exchange messages.
|
||||
* Queue everything else.
|
||||
*/
|
||||
if ((need_rekey || state->rekeying) && !ssh_packet_type_is_kex(type)) {
|
||||
if (need_rekey)
|
||||
debug3("%s: rekex triggered", __func__);
|
||||
debug("enqueue packet: %u", type);
|
||||
p = calloc(1, sizeof(*p));
|
||||
if (p == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
p->type = type;
|
||||
p->payload = state->outgoing_packet;
|
||||
TAILQ_INSERT_TAIL(&state->outgoing, p, next);
|
||||
state->outgoing_packet = sshbuf_new();
|
||||
if (state->outgoing_packet == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if (need_rekey) {
|
||||
/*
|
||||
* This packet triggered a rekey, so send the
|
||||
* KEXINIT now.
|
||||
* NB. reenters this function via kex_start_rekex().
|
||||
*/
|
||||
return kex_start_rekex(ssh);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* rekeying starts with sending KEXINIT */
|
||||
@ -1243,10 +1352,22 @@ ssh_packet_send2(struct ssh *ssh)
|
||||
state->rekey_time = monotime();
|
||||
while ((p = TAILQ_FIRST(&state->outgoing))) {
|
||||
type = p->type;
|
||||
/*
|
||||
* If this packet triggers a rekex, then skip the
|
||||
* remaining packets in the queue for now.
|
||||
* NB. re-enters this function via kex_start_rekex.
|
||||
*/
|
||||
if (ssh_packet_need_rekeying(ssh,
|
||||
sshbuf_len(p->payload))) {
|
||||
debug3("%s: queued packet triggered rekex",
|
||||
__func__);
|
||||
return kex_start_rekex(ssh);
|
||||
}
|
||||
debug("dequeue packet: %u", type);
|
||||
sshbuf_free(state->outgoing_packet);
|
||||
state->outgoing_packet = p->payload;
|
||||
TAILQ_REMOVE(&state->outgoing, p, next);
|
||||
memset(p, 0, sizeof(*p));
|
||||
free(p);
|
||||
if ((r = ssh_packet_send2_wrapped(ssh)) != 0)
|
||||
return r;
|
||||
@ -1265,7 +1386,7 @@ int
|
||||
ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
{
|
||||
struct session_state *state = ssh->state;
|
||||
int len, r, ms_remain, cont;
|
||||
int len, r, ms_remain;
|
||||
fd_set *setp;
|
||||
char buf[8192];
|
||||
struct timeval timeout, start, *timeoutp = NULL;
|
||||
@ -1335,11 +1456,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
if (r == 0)
|
||||
return SSH_ERR_CONN_TIMEOUT;
|
||||
/* Read data from the socket. */
|
||||
do {
|
||||
cont = 0;
|
||||
len = roaming_read(state->connection_in, buf,
|
||||
sizeof(buf), &cont);
|
||||
} while (len == 0 && cont);
|
||||
len = read(state->connection_in, buf, sizeof(buf));
|
||||
if (len == 0) {
|
||||
r = SSH_ERR_CONN_CLOSED;
|
||||
goto out;
|
||||
@ -1734,6 +1851,8 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
*/
|
||||
if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0)
|
||||
goto out;
|
||||
if (ssh_packet_log_type(*typep))
|
||||
debug3("receive packet: type %u", *typep);
|
||||
if (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) {
|
||||
if ((r = sshpkt_disconnect(ssh,
|
||||
"Invalid ssh2 packet type: %d", *typep)) != 0 ||
|
||||
@ -1753,6 +1872,13 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
#endif
|
||||
/* reset for next packet */
|
||||
state->packlen = 0;
|
||||
|
||||
/* do we need to rekey? */
|
||||
if (ssh_packet_need_rekeying(ssh, 0)) {
|
||||
debug3("%s: rekex triggered", __func__);
|
||||
if ((r = kex_start_rekex(ssh)) != 0)
|
||||
return r;
|
||||
}
|
||||
out:
|
||||
return r;
|
||||
}
|
||||
@ -1783,8 +1909,7 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||
|
||||
(r = sshpkt_get_string(ssh, &msg, NULL)) != 0 ||
|
||||
(r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
|
||||
if (msg)
|
||||
free(msg);
|
||||
free(msg);
|
||||
return r;
|
||||
}
|
||||
debug("Remote: %.900s", msg);
|
||||
@ -1798,8 +1923,9 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
do_log2(ssh->state->server_side &&
|
||||
reason == SSH2_DISCONNECT_BY_APPLICATION ?
|
||||
SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
|
||||
"Received disconnect from %s: %u: %.400s",
|
||||
ssh_remote_ipaddr(ssh), reason, msg);
|
||||
"Received disconnect from %s port %d:"
|
||||
"%u: %.400s", ssh_remote_ipaddr(ssh),
|
||||
ssh_remote_port(ssh), reason, msg);
|
||||
free(msg);
|
||||
return SSH_ERR_DISCONNECTED;
|
||||
case SSH2_MSG_UNIMPLEMENTED:
|
||||
@ -1827,8 +1953,9 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
case SSH_MSG_DISCONNECT:
|
||||
if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
|
||||
return r;
|
||||
error("Received disconnect from %s: %.400s",
|
||||
ssh_remote_ipaddr(ssh), msg);
|
||||
error("Received disconnect from %s port %d: "
|
||||
"%.400s", ssh_remote_ipaddr(ssh),
|
||||
ssh_remote_port(ssh), msg);
|
||||
free(msg);
|
||||
return SSH_ERR_DISCONNECTED;
|
||||
default:
|
||||
@ -1918,19 +2045,22 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
|
||||
{
|
||||
switch (r) {
|
||||
case SSH_ERR_CONN_CLOSED:
|
||||
logit("Connection closed by %.200s", ssh_remote_ipaddr(ssh));
|
||||
logit("Connection closed by %.200s port %d",
|
||||
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
|
||||
cleanup_exit(255);
|
||||
case SSH_ERR_CONN_TIMEOUT:
|
||||
logit("Connection to %.200s timed out", ssh_remote_ipaddr(ssh));
|
||||
logit("Connection %s %.200s port %d timed out",
|
||||
ssh->state->server_side ? "from" : "to",
|
||||
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
|
||||
cleanup_exit(255);
|
||||
case SSH_ERR_DISCONNECTED:
|
||||
logit("Disconnected from %.200s",
|
||||
ssh_remote_ipaddr(ssh));
|
||||
logit("Disconnected from %.200s port %d",
|
||||
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
|
||||
cleanup_exit(255);
|
||||
case SSH_ERR_SYSTEM_ERROR:
|
||||
if (errno == ECONNRESET) {
|
||||
logit("Connection reset by %.200s",
|
||||
ssh_remote_ipaddr(ssh));
|
||||
logit("Connection reset by %.200s port %d",
|
||||
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
|
||||
cleanup_exit(255);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
@ -1940,15 +2070,17 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
|
||||
case SSH_ERR_NO_KEX_ALG_MATCH:
|
||||
case SSH_ERR_NO_HOSTKEY_ALG_MATCH:
|
||||
if (ssh && ssh->kex && ssh->kex->failed_choice) {
|
||||
fatal("Unable to negotiate with %.200s: %s. "
|
||||
fatal("Unable to negotiate with %.200s port %d: %s. "
|
||||
"Their offer: %s", ssh_remote_ipaddr(ssh),
|
||||
ssh_err(r), ssh->kex->failed_choice);
|
||||
ssh_remote_port(ssh), ssh_err(r),
|
||||
ssh->kex->failed_choice);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
fatal("%s%sConnection to %.200s: %s",
|
||||
fatal("%s%sConnection %s %.200s port %d: %s",
|
||||
tag != NULL ? tag : "", tag != NULL ? ": " : "",
|
||||
ssh_remote_ipaddr(ssh), ssh_err(r));
|
||||
ssh->state->server_side ? "from" : "to",
|
||||
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ssh_err(r));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2005,19 +2137,18 @@ ssh_packet_write_poll(struct ssh *ssh)
|
||||
{
|
||||
struct session_state *state = ssh->state;
|
||||
int len = sshbuf_len(state->output);
|
||||
int cont, r;
|
||||
int r;
|
||||
|
||||
if (len > 0) {
|
||||
cont = 0;
|
||||
len = roaming_write(state->connection_out,
|
||||
sshbuf_ptr(state->output), len, &cont);
|
||||
len = write(state->connection_out,
|
||||
sshbuf_ptr(state->output), len);
|
||||
if (len == -1) {
|
||||
if (errno == EINTR || errno == EAGAIN ||
|
||||
errno == EWOULDBLOCK)
|
||||
return 0;
|
||||
return SSH_ERR_SYSTEM_ERROR;
|
||||
}
|
||||
if (len == 0 && !cont)
|
||||
if (len == 0)
|
||||
return SSH_ERR_CONN_CLOSED;
|
||||
if ((r = sshbuf_consume(state->output, len)) != 0)
|
||||
return r;
|
||||
@ -2041,7 +2172,10 @@ ssh_packet_write_wait(struct ssh *ssh)
|
||||
NFDBITS), sizeof(fd_mask));
|
||||
if (setp == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
ssh_packet_write_poll(ssh);
|
||||
if ((r = ssh_packet_write_poll(ssh)) != 0) {
|
||||
free(setp);
|
||||
return r;
|
||||
}
|
||||
while (ssh_packet_have_data_to_write(ssh)) {
|
||||
memset(setp, 0, howmany(state->connection_out + 1,
|
||||
NFDBITS) * sizeof(fd_mask));
|
||||
@ -2229,29 +2363,10 @@ ssh_packet_send_ignore(struct ssh *ssh, int nbytes)
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_PACKETS (1U<<31)
|
||||
int
|
||||
ssh_packet_need_rekeying(struct ssh *ssh)
|
||||
{
|
||||
struct session_state *state = ssh->state;
|
||||
|
||||
if (ssh->compat & SSH_BUG_NOREKEY)
|
||||
return 0;
|
||||
return
|
||||
(state->p_send.packets > MAX_PACKETS) ||
|
||||
(state->p_read.packets > MAX_PACKETS) ||
|
||||
(state->max_blocks_out &&
|
||||
(state->p_send.blocks > state->max_blocks_out)) ||
|
||||
(state->max_blocks_in &&
|
||||
(state->p_read.blocks > state->max_blocks_in)) ||
|
||||
(state->rekey_interval != 0 && state->rekey_time +
|
||||
state->rekey_interval <= monotime());
|
||||
}
|
||||
|
||||
void
|
||||
ssh_packet_set_rekey_limits(struct ssh *ssh, u_int32_t bytes, time_t seconds)
|
||||
ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, time_t seconds)
|
||||
{
|
||||
debug3("rekey after %lld bytes, %d seconds", (long long)bytes,
|
||||
debug3("rekey after %llu bytes, %d seconds", (unsigned long long)bytes,
|
||||
(int)seconds);
|
||||
ssh->state->rekey_limit = bytes;
|
||||
ssh->state->rekey_interval = seconds;
|
||||
@ -2291,58 +2406,6 @@ ssh_packet_get_output(struct ssh *ssh)
|
||||
return (void *)ssh->state->output;
|
||||
}
|
||||
|
||||
/* XXX TODO update roaming to new API (does not work anyway) */
|
||||
/*
|
||||
* Save the state for the real connection, and use a separate state when
|
||||
* resuming a suspended connection.
|
||||
*/
|
||||
void
|
||||
ssh_packet_backup_state(struct ssh *ssh,
|
||||
struct ssh *backup_state)
|
||||
{
|
||||
struct ssh *tmp;
|
||||
|
||||
close(ssh->state->connection_in);
|
||||
ssh->state->connection_in = -1;
|
||||
close(ssh->state->connection_out);
|
||||
ssh->state->connection_out = -1;
|
||||
if (backup_state)
|
||||
tmp = backup_state;
|
||||
else
|
||||
tmp = ssh_alloc_session_state();
|
||||
backup_state = ssh;
|
||||
ssh = tmp;
|
||||
}
|
||||
|
||||
/* XXX FIXME FIXME FIXME */
|
||||
/*
|
||||
* Swap in the old state when resuming a connecion.
|
||||
*/
|
||||
void
|
||||
ssh_packet_restore_state(struct ssh *ssh,
|
||||
struct ssh *backup_state)
|
||||
{
|
||||
struct ssh *tmp;
|
||||
u_int len;
|
||||
int r;
|
||||
|
||||
tmp = backup_state;
|
||||
backup_state = ssh;
|
||||
ssh = tmp;
|
||||
ssh->state->connection_in = backup_state->state->connection_in;
|
||||
backup_state->state->connection_in = -1;
|
||||
ssh->state->connection_out = backup_state->state->connection_out;
|
||||
backup_state->state->connection_out = -1;
|
||||
len = sshbuf_len(backup_state->state->input);
|
||||
if (len > 0) {
|
||||
if ((r = sshbuf_putb(ssh->state->input,
|
||||
backup_state->state->input)) != 0)
|
||||
fatal("%s: %s", __func__, ssh_err(r));
|
||||
sshbuf_reset(backup_state->state->input);
|
||||
add_recv_bytes(len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset after_authentication and reset compression in post-auth privsep */
|
||||
static int
|
||||
ssh_packet_set_postauth(struct ssh *ssh)
|
||||
@ -2430,8 +2493,7 @@ newkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode)
|
||||
goto out;
|
||||
r = sshbuf_put_stringb(m, b);
|
||||
out:
|
||||
if (b != NULL)
|
||||
sshbuf_free(b);
|
||||
sshbuf_free(b);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -2462,7 +2524,7 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m)
|
||||
if ((r = kex_to_blob(m, ssh->kex)) != 0 ||
|
||||
(r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 ||
|
||||
(r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, state->rekey_limit)) != 0 ||
|
||||
(r = sshbuf_put_u64(m, state->rekey_limit)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, state->rekey_interval)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 ||
|
||||
(r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 ||
|
||||
@ -2493,11 +2555,6 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m)
|
||||
(r = sshbuf_put_stringb(m, state->output)) != 0)
|
||||
return r;
|
||||
|
||||
if (compat20) {
|
||||
if ((r = sshbuf_put_u64(m, get_sent_bytes())) != 0 ||
|
||||
(r = sshbuf_put_u64(m, get_recv_bytes())) != 0)
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2566,10 +2623,8 @@ newkeys_from_blob(struct sshbuf *m, struct ssh *ssh, int mode)
|
||||
newkey = NULL;
|
||||
r = 0;
|
||||
out:
|
||||
if (newkey != NULL)
|
||||
free(newkey);
|
||||
if (b != NULL)
|
||||
sshbuf_free(b);
|
||||
free(newkey);
|
||||
sshbuf_free(b);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -2602,10 +2657,8 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp)
|
||||
out:
|
||||
if (r != 0 || kexp == NULL) {
|
||||
if (kex != NULL) {
|
||||
if (kex->my != NULL)
|
||||
sshbuf_free(kex->my);
|
||||
if (kex->peer != NULL)
|
||||
sshbuf_free(kex->peer);
|
||||
sshbuf_free(kex->my);
|
||||
sshbuf_free(kex->peer);
|
||||
free(kex);
|
||||
}
|
||||
if (kexp != NULL)
|
||||
@ -2628,7 +2681,6 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
|
||||
size_t ssh1keylen, rlen, slen, ilen, olen;
|
||||
int r;
|
||||
u_int ssh1cipher = 0;
|
||||
u_int64_t sent_bytes = 0, recv_bytes = 0;
|
||||
|
||||
if (!compat20) {
|
||||
if ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 ||
|
||||
@ -2651,7 +2703,7 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
|
||||
if ((r = kex_from_blob(m, &ssh->kex)) != 0 ||
|
||||
(r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 ||
|
||||
(r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &state->rekey_limit)) != 0 ||
|
||||
(r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 ||
|
||||
(r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 ||
|
||||
@ -2693,12 +2745,6 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
|
||||
(r = sshbuf_put(state->output, output, olen)) != 0)
|
||||
return r;
|
||||
|
||||
if (compat20) {
|
||||
if ((r = sshbuf_get_u64(m, &sent_bytes)) != 0 ||
|
||||
(r = sshbuf_get_u64(m, &recv_bytes)) != 0)
|
||||
return r;
|
||||
roam_set_bytes(sent_bytes, recv_bytes);
|
||||
}
|
||||
if (sshbuf_len(m))
|
||||
return SSH_ERR_INVALID_FORMAT;
|
||||
debug3("%s: done", __func__);
|
||||
|
11
packet.h
11
packet.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: packet.h,v 1.66 2015/01/30 01:13:33 djm Exp $ */
|
||||
/* $OpenBSD: packet.h,v 1.70 2016/02/08 10:57:07 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -86,6 +86,7 @@ int ssh_packet_get_connection_in(struct ssh *);
|
||||
int ssh_packet_get_connection_out(struct ssh *);
|
||||
void ssh_packet_close(struct ssh *);
|
||||
void ssh_packet_set_encryption_key(struct ssh *, const u_char *, u_int, int);
|
||||
int ssh_packet_is_rekeying(struct ssh *);
|
||||
void ssh_packet_set_protocol_flags(struct ssh *, u_int);
|
||||
u_int ssh_packet_get_protocol_flags(struct ssh *);
|
||||
int ssh_packet_start_compression(struct ssh *, int);
|
||||
@ -143,15 +144,11 @@ int ssh_packet_get_state(struct ssh *, struct sshbuf *);
|
||||
int ssh_packet_set_state(struct ssh *, struct sshbuf *);
|
||||
|
||||
const char *ssh_remote_ipaddr(struct ssh *);
|
||||
int ssh_remote_port(struct ssh *);
|
||||
|
||||
int ssh_packet_need_rekeying(struct ssh *);
|
||||
void ssh_packet_set_rekey_limits(struct ssh *, u_int32_t, time_t);
|
||||
void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, time_t);
|
||||
time_t ssh_packet_get_rekey_timeout(struct ssh *);
|
||||
|
||||
/* XXX FIXME */
|
||||
void ssh_packet_backup_state(struct ssh *, struct ssh *);
|
||||
void ssh_packet_restore_state(struct ssh *, struct ssh *);
|
||||
|
||||
void *ssh_packet_get_input(struct ssh *);
|
||||
void *ssh_packet_get_output(struct ssh *);
|
||||
|
||||
|
71
platform-pledge.c
Normal file
71
platform-pledge.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Joyent, Inc
|
||||
* Author: Alex Wilson <alex.wilson@joyent.com>
|
||||
*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "openbsd-compat/openbsd-compat.h"
|
||||
|
||||
/*
|
||||
* Drop any fine-grained privileges that are not needed for post-startup
|
||||
* operation of ssh-agent
|
||||
*
|
||||
* Should be as close as possible to pledge("stdio cpath unix id proc exec", ...)
|
||||
*/
|
||||
void
|
||||
platform_pledge_agent(void)
|
||||
{
|
||||
#ifdef USE_SOLARIS_PRIVS
|
||||
/*
|
||||
* Note: Solaris priv dropping is closer to tame() than pledge(), but
|
||||
* we will use what we have.
|
||||
*/
|
||||
solaris_drop_privs_root_pinfo_net();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop any fine-grained privileges that are not needed for post-startup
|
||||
* operation of sftp-server
|
||||
*/
|
||||
void
|
||||
platform_pledge_sftp_server(void)
|
||||
{
|
||||
#ifdef USE_SOLARIS_PRIVS
|
||||
solaris_drop_privs_pinfo_net_fork_exec();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop any fine-grained privileges that are not needed for the post-startup
|
||||
* operation of the SSH client mux
|
||||
*
|
||||
* Should be as close as possible to pledge("stdio proc tty", ...)
|
||||
*/
|
||||
void
|
||||
platform_pledge_mux(void)
|
||||
{
|
||||
#ifdef USE_SOLARIS_PRIVS
|
||||
solaris_drop_privs_root_pinfo_net_exec();
|
||||
#endif
|
||||
}
|
@ -31,3 +31,8 @@ void platform_setusercontext_post_groups(struct passwd *);
|
||||
char *platform_get_krb5_client(const char *);
|
||||
char *platform_krb5_get_principal_name(const char *);
|
||||
int platform_sys_dir_uid(uid_t);
|
||||
|
||||
/* in platform-pledge.c */
|
||||
void platform_pledge_agent(void);
|
||||
void platform_pledge_sftp_server(void);
|
||||
void platform_pledge_mux(void);
|
||||
|
110
readconf.c
110
readconf.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readconf.c,v 1.239 2015/07/30 00:01:34 djm Exp $ */
|
||||
/* $OpenBSD: readconf.c,v 1.250 2016/02/08 23:40:12 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -135,6 +135,7 @@ typedef enum {
|
||||
oPasswordAuthentication, oRSAAuthentication,
|
||||
oChallengeResponseAuthentication, oXAuthLocation,
|
||||
oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
|
||||
oCertificateFile, oAddKeysToAgent,
|
||||
oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
|
||||
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
|
||||
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
|
||||
@ -151,7 +152,7 @@ typedef enum {
|
||||
oSendEnv, oControlPath, oControlMaster, oControlPersist,
|
||||
oHashKnownHosts,
|
||||
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
|
||||
oVisualHostKey, oUseRoaming,
|
||||
oVisualHostKey,
|
||||
oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
|
||||
oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
|
||||
oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
|
||||
@ -202,6 +203,8 @@ static struct {
|
||||
{ "identityfile", oIdentityFile },
|
||||
{ "identityfile2", oIdentityFile }, /* obsolete */
|
||||
{ "identitiesonly", oIdentitiesOnly },
|
||||
{ "certificatefile", oCertificateFile },
|
||||
{ "addkeystoagent", oAddKeysToAgent },
|
||||
{ "hostname", oHostName },
|
||||
{ "hostkeyalias", oHostKeyAlias },
|
||||
{ "proxycommand", oProxyCommand },
|
||||
@ -260,7 +263,7 @@ static struct {
|
||||
{ "localcommand", oLocalCommand },
|
||||
{ "permitlocalcommand", oPermitLocalCommand },
|
||||
{ "visualhostkey", oVisualHostKey },
|
||||
{ "useroaming", oUseRoaming },
|
||||
{ "useroaming", oDeprecated },
|
||||
{ "kexalgorithms", oKexAlgorithms },
|
||||
{ "ipqos", oIPQoS },
|
||||
{ "requesttty", oRequestTTY },
|
||||
@ -365,6 +368,30 @@ clear_forwardings(Options *options)
|
||||
options->tun_open = SSH_TUNMODE_NO;
|
||||
}
|
||||
|
||||
void
|
||||
add_certificate_file(Options *options, const char *path, int userprovided)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
|
||||
fatal("Too many certificate files specified (max %d)",
|
||||
SSH_MAX_CERTIFICATE_FILES);
|
||||
|
||||
/* Avoid registering duplicates */
|
||||
for (i = 0; i < options->num_certificate_files; i++) {
|
||||
if (options->certificate_file_userprovided[i] == userprovided &&
|
||||
strcmp(options->certificate_files[i], path) == 0) {
|
||||
debug2("%s: ignoring duplicate key %s", __func__, path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
options->certificate_file_userprovided[options->num_certificate_files] =
|
||||
userprovided;
|
||||
options->certificate_files[options->num_certificate_files++] =
|
||||
xstrdup(path);
|
||||
}
|
||||
|
||||
void
|
||||
add_identity_file(Options *options, const char *dir, const char *filename,
|
||||
int userprovided)
|
||||
@ -416,7 +443,7 @@ default_ssh_port(void)
|
||||
static int
|
||||
execute_in_shell(const char *cmd)
|
||||
{
|
||||
char *shell, *command_string;
|
||||
char *shell;
|
||||
pid_t pid;
|
||||
int devnull, status;
|
||||
extern uid_t original_real_uid;
|
||||
@ -424,12 +451,6 @@ execute_in_shell(const char *cmd)
|
||||
if ((shell = getenv("SHELL")) == NULL)
|
||||
shell = _PATH_BSHELL;
|
||||
|
||||
/*
|
||||
* Use "exec" to avoid "sh -c" processes on some platforms
|
||||
* (e.g. Solaris)
|
||||
*/
|
||||
xasprintf(&command_string, "exec %s", cmd);
|
||||
|
||||
/* Need this to redirect subprocess stdin/out */
|
||||
if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
|
||||
fatal("open(/dev/null): %s", strerror(errno));
|
||||
@ -454,7 +475,7 @@ execute_in_shell(const char *cmd)
|
||||
|
||||
argv[0] = shell;
|
||||
argv[1] = "-c";
|
||||
argv[2] = command_string;
|
||||
argv[2] = xstrdup(cmd);
|
||||
argv[3] = NULL;
|
||||
|
||||
execv(argv[0], argv);
|
||||
@ -469,7 +490,6 @@ execute_in_shell(const char *cmd)
|
||||
fatal("%s: fork: %.100s", __func__, strerror(errno));
|
||||
|
||||
close(devnull);
|
||||
free(command_string);
|
||||
|
||||
while (waitpid(pid, &status, 0) == -1) {
|
||||
if (errno != EINTR && errno != EAGAIN)
|
||||
@ -502,12 +522,15 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
|
||||
*/
|
||||
port = options->port <= 0 ? default_ssh_port() : options->port;
|
||||
ruser = options->user == NULL ? pw->pw_name : options->user;
|
||||
if (options->hostname != NULL) {
|
||||
if (post_canon) {
|
||||
host = xstrdup(options->hostname);
|
||||
} else if (options->hostname != NULL) {
|
||||
/* NB. Please keep in sync with ssh.c:main() */
|
||||
host = percent_expand(options->hostname,
|
||||
"h", host_arg, (char *)NULL);
|
||||
} else
|
||||
} else {
|
||||
host = xstrdup(host_arg);
|
||||
}
|
||||
|
||||
debug2("checking match for '%s' host %s originally %s",
|
||||
cp, host, original_host);
|
||||
@ -693,6 +716,15 @@ static const struct multistate multistate_yesnoask[] = {
|
||||
{ "ask", 2 },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
static const struct multistate multistate_yesnoaskconfirm[] = {
|
||||
{ "true", 1 },
|
||||
{ "false", 0 },
|
||||
{ "yes", 1 },
|
||||
{ "no", 0 },
|
||||
{ "ask", 2 },
|
||||
{ "confirm", 3 },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
static const struct multistate multistate_addressfamily[] = {
|
||||
{ "inet", AF_INET },
|
||||
{ "inet6", AF_INET6 },
|
||||
@ -947,16 +979,12 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
|
||||
if (scan_scaled(arg, &val64) == -1)
|
||||
fatal("%.200s line %d: Bad number '%s': %s",
|
||||
filename, linenum, arg, strerror(errno));
|
||||
/* check for too-large or too-small limits */
|
||||
if (val64 > UINT_MAX)
|
||||
fatal("%.200s line %d: RekeyLimit too large",
|
||||
filename, linenum);
|
||||
if (val64 != 0 && val64 < 16)
|
||||
fatal("%.200s line %d: RekeyLimit too small",
|
||||
filename, linenum);
|
||||
}
|
||||
if (*activep && options->rekey_limit == -1)
|
||||
options->rekey_limit = (u_int32_t)val64;
|
||||
options->rekey_limit = val64;
|
||||
if (s != NULL) { /* optional rekey interval present */
|
||||
if (strcmp(s, "none") == 0) {
|
||||
(void)strdelim(&s); /* discard */
|
||||
@ -981,6 +1009,24 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
|
||||
}
|
||||
break;
|
||||
|
||||
case oCertificateFile:
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%.200s line %d: Missing argument.",
|
||||
filename, linenum);
|
||||
if (*activep) {
|
||||
intptr = &options->num_certificate_files;
|
||||
if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
|
||||
fatal("%.200s line %d: Too many certificate "
|
||||
"files specified (max %d).",
|
||||
filename, linenum,
|
||||
SSH_MAX_CERTIFICATE_FILES);
|
||||
}
|
||||
add_certificate_file(options, arg,
|
||||
flags & SSHCONF_USERCONF);
|
||||
}
|
||||
break;
|
||||
|
||||
case oXAuthLocation:
|
||||
charptr=&options->xauth_location;
|
||||
goto parse_string;
|
||||
@ -1378,10 +1424,6 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
|
||||
}
|
||||
break;
|
||||
|
||||
case oUseRoaming:
|
||||
intptr = &options->use_roaming;
|
||||
goto parse_flag;
|
||||
|
||||
case oRequestTTY:
|
||||
intptr = &options->request_tty;
|
||||
multistate_ptr = multistate_requesttty;
|
||||
@ -1496,6 +1538,11 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
|
||||
charptr = &options->pubkey_key_types;
|
||||
goto parse_keytypes;
|
||||
|
||||
case oAddKeysToAgent:
|
||||
intptr = &options->add_keys_to_agent;
|
||||
multistate_ptr = multistate_yesnoaskconfirm;
|
||||
goto parse_multistate;
|
||||
|
||||
case oDeprecated:
|
||||
debug("%s line %d: Deprecated option \"%s\"",
|
||||
filename, linenum, keyword);
|
||||
@ -1625,6 +1672,7 @@ initialize_options(Options * options)
|
||||
options->hostkeyalgorithms = NULL;
|
||||
options->protocol = SSH_PROTO_UNKNOWN;
|
||||
options->num_identity_files = 0;
|
||||
options->num_certificate_files = 0;
|
||||
options->hostname = NULL;
|
||||
options->host_key_alias = NULL;
|
||||
options->proxy_command = NULL;
|
||||
@ -1660,7 +1708,7 @@ initialize_options(Options * options)
|
||||
options->tun_remote = -1;
|
||||
options->local_command = NULL;
|
||||
options->permit_local_command = -1;
|
||||
options->use_roaming = 0;
|
||||
options->add_keys_to_agent = -1;
|
||||
options->visual_host_key = -1;
|
||||
options->ip_qos_interactive = -1;
|
||||
options->ip_qos_bulk = -1;
|
||||
@ -1765,6 +1813,8 @@ fill_default_options(Options * options)
|
||||
/* options->hostkeyalgorithms, default set in myproposals.h */
|
||||
if (options->protocol == SSH_PROTO_UNKNOWN)
|
||||
options->protocol = SSH_PROTO_2;
|
||||
if (options->add_keys_to_agent == -1)
|
||||
options->add_keys_to_agent = 0;
|
||||
if (options->num_identity_files == 0) {
|
||||
if (options->protocol & SSH_PROTO_1) {
|
||||
add_identity_file(options, "~/",
|
||||
@ -1833,7 +1883,6 @@ fill_default_options(Options * options)
|
||||
options->tun_remote = SSH_TUNID_ANY;
|
||||
if (options->permit_local_command == -1)
|
||||
options->permit_local_command = 0;
|
||||
options->use_roaming = 0;
|
||||
if (options->visual_host_key == -1)
|
||||
options->visual_host_key = 0;
|
||||
if (options->ip_qos_interactive == -1)
|
||||
@ -2242,6 +2291,10 @@ dump_client_config(Options *o, const char *host)
|
||||
int i;
|
||||
char vbuf[5];
|
||||
|
||||
/* This is normally prepared in ssh_kex2 */
|
||||
if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
|
||||
fatal("%s: kex_assemble_names failed", __func__);
|
||||
|
||||
/* Most interesting options first: user, host, port */
|
||||
dump_cfg_string(oUser, o->user);
|
||||
dump_cfg_string(oHostName, host);
|
||||
@ -2302,7 +2355,7 @@ dump_client_config(Options *o, const char *host)
|
||||
dump_cfg_string(oBindAddress, o->bind_address);
|
||||
dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
|
||||
dump_cfg_string(oControlPath, o->control_path);
|
||||
dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
|
||||
dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
|
||||
dump_cfg_string(oHostKeyAlias, o->host_key_alias);
|
||||
dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
|
||||
dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
|
||||
@ -2313,6 +2366,7 @@ dump_client_config(Options *o, const char *host)
|
||||
dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
|
||||
dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
|
||||
dump_cfg_string(oProxyCommand, o->proxy_command);
|
||||
dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
|
||||
dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
|
||||
dump_cfg_string(oXAuthLocation, o->xauth_location);
|
||||
|
||||
@ -2381,8 +2435,8 @@ dump_client_config(Options *o, const char *host)
|
||||
printf("%s\n", iptos2str(o->ip_qos_bulk));
|
||||
|
||||
/* oRekeyLimit */
|
||||
printf("rekeylimit %lld %d\n",
|
||||
(long long)o->rekey_limit, o->rekey_interval);
|
||||
printf("rekeylimit %llu %d\n",
|
||||
(unsigned long long)o->rekey_limit, o->rekey_interval);
|
||||
|
||||
/* oStreamLocalBindMask */
|
||||
printf("streamlocalbindmask 0%o\n",
|
||||
|
12
readconf.h
12
readconf.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readconf.h,v 1.110 2015/07/10 06:21:53 markus Exp $ */
|
||||
/* $OpenBSD: readconf.h,v 1.113 2016/01/14 16:17:40 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -95,6 +95,13 @@ typedef struct {
|
||||
int identity_file_userprovided[SSH_MAX_IDENTITY_FILES];
|
||||
struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES];
|
||||
|
||||
int num_certificate_files; /* Number of extra certificates for ssh. */
|
||||
char *certificate_files[SSH_MAX_CERTIFICATE_FILES];
|
||||
int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES];
|
||||
struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
|
||||
|
||||
int add_keys_to_agent;
|
||||
|
||||
/* Local TCP/IP forward requests. */
|
||||
int num_local_forwards;
|
||||
struct Forward *local_forwards;
|
||||
@ -130,8 +137,6 @@ typedef struct {
|
||||
int permit_local_command;
|
||||
int visual_host_key;
|
||||
|
||||
int use_roaming;
|
||||
|
||||
int request_tty;
|
||||
|
||||
int proxy_use_fdpass;
|
||||
@ -194,5 +199,6 @@ void dump_client_config(Options *o, const char *host);
|
||||
void add_local_forward(Options *, const struct Forward *);
|
||||
void add_remote_forward(Options *, const struct Forward *);
|
||||
void add_identity_file(Options *, const char *, const char *, int);
|
||||
void add_certificate_file(Options *, const char *, int);
|
||||
|
||||
#endif /* READCONF_H */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readpass.c,v 1.50 2014/02/02 03:44:31 djm Exp $ */
|
||||
/* $OpenBSD: readpass.c,v 1.51 2015/12/11 00:20:04 mmcc Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -76,7 +76,7 @@ ssh_askpass(char *askpass, const char *msg)
|
||||
close(p[0]);
|
||||
if (dup2(p[1], STDOUT_FILENO) < 0)
|
||||
fatal("ssh_askpass: dup2: %s", strerror(errno));
|
||||
execlp(askpass, askpass, msg, (char *) 0);
|
||||
execlp(askpass, askpass, msg, (char *)NULL);
|
||||
fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
|
||||
}
|
||||
close(p[1]);
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.81 2015/05/21 06:44:25 djm Exp $
|
||||
# $OpenBSD: Makefile,v 1.82 2015/09/24 06:16:53 djm Exp $
|
||||
|
||||
REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec
|
||||
tests: prep $(REGRESS_TARGETS)
|
||||
@ -74,7 +74,8 @@ LTESTS= connect \
|
||||
hostkey-agent \
|
||||
keygen-knownhosts \
|
||||
hostkey-rotate \
|
||||
principals-command
|
||||
principals-command \
|
||||
cert-file
|
||||
|
||||
|
||||
# dhgex \
|
||||
|
@ -12,6 +12,11 @@ if have_prog uname ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ "x$USER" = "xroot" ]; then
|
||||
echo "Skipped: running as root"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if have_prog gdb ; then
|
||||
: ok
|
||||
else
|
||||
|
138
regress/cert-file.sh
Executable file
138
regress/cert-file.sh
Executable file
@ -0,0 +1,138 @@
|
||||
# $OpenBSD: cert-file.sh,v 1.2 2015/09/24 07:15:39 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="ssh with certificates"
|
||||
|
||||
rm -f $OBJ/user_ca_key* $OBJ/user_key*
|
||||
rm -f $OBJ/cert_user_key*
|
||||
|
||||
# Create a CA key
|
||||
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key1 ||\
|
||||
fatal "ssh-keygen failed"
|
||||
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key2 ||\
|
||||
fatal "ssh-keygen failed"
|
||||
|
||||
# Make some keys and certificates.
|
||||
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \
|
||||
fatal "ssh-keygen failed"
|
||||
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key2 || \
|
||||
fatal "ssh-keygen failed"
|
||||
# Move the certificate to a different address to better control
|
||||
# when it is offered.
|
||||
${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \
|
||||
-z $$ -n ${USER} $OBJ/user_key1 ||
|
||||
fail "couldn't sign user_key1 with user_ca_key1"
|
||||
mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_1.pub
|
||||
${SSHKEYGEN} -q -s $OBJ/user_ca_key2 -I "regress user key for $USER" \
|
||||
-z $$ -n ${USER} $OBJ/user_key1 ||
|
||||
fail "couldn't sign user_key1 with user_ca_key2"
|
||||
mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_2.pub
|
||||
|
||||
trace 'try with identity files'
|
||||
opts="-F $OBJ/ssh_proxy -oIdentitiesOnly=yes"
|
||||
opts2="$opts -i $OBJ/user_key1 -i $OBJ/user_key2"
|
||||
echo "cert-authority $(cat $OBJ/user_ca_key1.pub)" > $OBJ/authorized_keys_$USER
|
||||
|
||||
for p in ${SSH_PROTOCOLS}; do
|
||||
# Just keys should fail
|
||||
${SSH} $opts2 somehost exit 5$p
|
||||
r=$?
|
||||
if [ $r -eq 5$p ]; then
|
||||
fail "ssh succeeded with no certs in protocol $p"
|
||||
fi
|
||||
|
||||
# Keys with untrusted cert should fail.
|
||||
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
|
||||
${SSH} $opts3 somehost exit 5$p
|
||||
r=$?
|
||||
if [ $r -eq 5$p ]; then
|
||||
fail "ssh succeeded with bad cert in protocol $p"
|
||||
fi
|
||||
|
||||
# Good cert with bad key should fail.
|
||||
opts3="$opts -i $OBJ/user_key2"
|
||||
opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
|
||||
${SSH} $opts3 somehost exit 5$p
|
||||
r=$?
|
||||
if [ $r -eq 5$p ]; then
|
||||
fail "ssh succeeded with no matching key in protocol $p"
|
||||
fi
|
||||
|
||||
# Keys with one trusted cert, should succeed.
|
||||
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
|
||||
${SSH} $opts3 somehost exit 5$p
|
||||
r=$?
|
||||
if [ $r -ne 5$p ]; then
|
||||
fail "ssh failed with trusted cert and key in protocol $p"
|
||||
fi
|
||||
|
||||
# Multiple certs and keys, with one trusted cert, should succeed.
|
||||
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
|
||||
opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
|
||||
${SSH} $opts3 somehost exit 5$p
|
||||
r=$?
|
||||
if [ $r -ne 5$p ]; then
|
||||
fail "ssh failed with multiple certs in protocol $p"
|
||||
fi
|
||||
|
||||
#Keys with trusted certificate specified in config options, should succeed.
|
||||
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
|
||||
${SSH} $opts3 somehost exit 5$p
|
||||
r=$?
|
||||
if [ $r -ne 5$p ]; then
|
||||
fail "ssh failed with trusted cert in config in protocol $p"
|
||||
fi
|
||||
done
|
||||
|
||||
#next, using an agent in combination with the keys
|
||||
SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1
|
||||
if [ $? -ne 2 ]; then
|
||||
fatal "ssh-add -l did not fail with exit code 2"
|
||||
fi
|
||||
|
||||
trace "start agent"
|
||||
eval `${SSHAGENT} -s` > /dev/null
|
||||
r=$?
|
||||
if [ $r -ne 0 ]; then
|
||||
fatal "could not start ssh-agent: exit code $r"
|
||||
fi
|
||||
|
||||
# add private keys to agent
|
||||
${SSHADD} -k $OBJ/user_key2 > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
fatal "ssh-add did not succeed with exit code 0"
|
||||
fi
|
||||
${SSHADD} -k $OBJ/user_key1 > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
fatal "ssh-add did not succeed with exit code 0"
|
||||
fi
|
||||
|
||||
# try ssh with the agent and certificates
|
||||
# note: ssh agent only uses certificates in protocol 2
|
||||
opts="-F $OBJ/ssh_proxy"
|
||||
# with no certificates, shoud fail
|
||||
${SSH} -2 $opts somehost exit 52
|
||||
if [ $? -eq 52 ]; then
|
||||
fail "ssh connect with agent in protocol 2 succeeded with no cert"
|
||||
fi
|
||||
|
||||
#with an untrusted certificate, should fail
|
||||
opts="$opts -oCertificateFile=$OBJ/cert_user_key1_2.pub"
|
||||
${SSH} -2 $opts somehost exit 52
|
||||
if [ $? -eq 52 ]; then
|
||||
fail "ssh connect with agent in protocol 2 succeeded with bad cert"
|
||||
fi
|
||||
|
||||
#with an additional trusted certificate, should succeed
|
||||
opts="$opts -oCertificateFile=$OBJ/cert_user_key1_1.pub"
|
||||
${SSH} -2 $opts somehost exit 52
|
||||
if [ $? -ne 52 ]; then
|
||||
fail "ssh connect with agent in protocol 2 failed with good cert"
|
||||
fi
|
||||
|
||||
trace "kill agent"
|
||||
${SSHAGENT} -k > /dev/null
|
||||
|
||||
#cleanup
|
||||
rm -f $OBJ/user_ca_key* $OBJ/user_key*
|
||||
rm -f $OBJ/cert_user_key*
|
205
regress/check-perm.c
Normal file
205
regress/check-perm.c
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Placed in the public domain
|
||||
*/
|
||||
|
||||
/* $OpenBSD: modpipe.c,v 1.6 2013/11/21 03:16:47 djm Exp $ */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#ifdef HAVE_LIBGEN_H
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
static void
|
||||
fatal(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
fputc('\n', stderr);
|
||||
va_end(args);
|
||||
exit(1);
|
||||
}
|
||||
/* Based on session.c. NB. keep tests in sync */
|
||||
static void
|
||||
safely_chroot(const char *path, uid_t uid)
|
||||
{
|
||||
const char *cp;
|
||||
char component[PATH_MAX];
|
||||
struct stat st;
|
||||
|
||||
if (*path != '/')
|
||||
fatal("chroot path does not begin at root");
|
||||
if (strlen(path) >= sizeof(component))
|
||||
fatal("chroot path too long");
|
||||
|
||||
/*
|
||||
* Descend the path, checking that each component is a
|
||||
* root-owned directory with strict permissions.
|
||||
*/
|
||||
for (cp = path; cp != NULL;) {
|
||||
if ((cp = strchr(cp, '/')) == NULL)
|
||||
strlcpy(component, path, sizeof(component));
|
||||
else {
|
||||
cp++;
|
||||
memcpy(component, path, cp - path);
|
||||
component[cp - path] = '\0';
|
||||
}
|
||||
|
||||
/* debug3("%s: checking '%s'", __func__, component); */
|
||||
|
||||
if (stat(component, &st) != 0)
|
||||
fatal("%s: stat(\"%s\"): %s", __func__,
|
||||
component, strerror(errno));
|
||||
if (st.st_uid != 0 || (st.st_mode & 022) != 0)
|
||||
fatal("bad ownership or modes for chroot "
|
||||
"directory %s\"%s\"",
|
||||
cp == NULL ? "" : "component ", component);
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
fatal("chroot path %s\"%s\" is not a directory",
|
||||
cp == NULL ? "" : "component ", component);
|
||||
|
||||
}
|
||||
|
||||
if (chdir(path) == -1)
|
||||
fatal("Unable to chdir to chroot path \"%s\": "
|
||||
"%s", path, strerror(errno));
|
||||
}
|
||||
|
||||
/* from platform.c */
|
||||
int
|
||||
platform_sys_dir_uid(uid_t uid)
|
||||
{
|
||||
if (uid == 0)
|
||||
return 1;
|
||||
#ifdef PLATFORM_SYS_DIR_UID
|
||||
if (uid == PLATFORM_SYS_DIR_UID)
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* from auth.c */
|
||||
int
|
||||
auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
|
||||
uid_t uid, char *err, size_t errlen)
|
||||
{
|
||||
char buf[PATH_MAX], homedir[PATH_MAX];
|
||||
char *cp;
|
||||
int comparehome = 0;
|
||||
struct stat st;
|
||||
|
||||
if (realpath(name, buf) == NULL) {
|
||||
snprintf(err, errlen, "realpath %s failed: %s", name,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
|
||||
comparehome = 1;
|
||||
|
||||
if (!S_ISREG(stp->st_mode)) {
|
||||
snprintf(err, errlen, "%s is not a regular file", buf);
|
||||
return -1;
|
||||
}
|
||||
if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||
|
||||
(stp->st_mode & 022) != 0) {
|
||||
snprintf(err, errlen, "bad ownership or modes for file %s",
|
||||
buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* for each component of the canonical path, walking upwards */
|
||||
for (;;) {
|
||||
if ((cp = dirname(buf)) == NULL) {
|
||||
snprintf(err, errlen, "dirname() failed");
|
||||
return -1;
|
||||
}
|
||||
strlcpy(buf, cp, sizeof(buf));
|
||||
|
||||
if (stat(buf, &st) < 0 ||
|
||||
(!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
|
||||
(st.st_mode & 022) != 0) {
|
||||
snprintf(err, errlen,
|
||||
"bad ownership or modes for directory %s", buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If are past the homedir then we can stop */
|
||||
if (comparehome && strcmp(homedir, buf) == 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
* dirname should always complete with a "/" path,
|
||||
* but we can be paranoid and check for "." too
|
||||
*/
|
||||
if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "check-perm -m [chroot | keys-command] [path]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *path = ".";
|
||||
char errmsg[256];
|
||||
int ch, mode = -1;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
struct stat st;
|
||||
|
||||
while ((ch = getopt(argc, argv, "hm:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'm':
|
||||
if (strcasecmp(optarg, "chroot") == 0)
|
||||
mode = 1;
|
||||
else if (strcasecmp(optarg, "keys-command") == 0)
|
||||
mode = 2;
|
||||
else {
|
||||
fprintf(stderr, "Invalid -m option\n"),
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc > 1)
|
||||
usage();
|
||||
else if (argc == 1)
|
||||
path = argv[0];
|
||||
|
||||
if (mode == 1)
|
||||
safely_chroot(path, getuid());
|
||||
else if (mode == 2) {
|
||||
if (stat(path, &st) < 0)
|
||||
fatal("Could not stat %s: %s", path, strerror(errno));
|
||||
if (auth_secure_path(path, &st, NULL, 0,
|
||||
errmsg, sizeof(errmsg)) != 0)
|
||||
fatal("Unsafe %s: %s", path, errmsg);
|
||||
} else {
|
||||
fprintf(stderr, "Invalid mode\n");
|
||||
usage();
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: dhgex.sh,v 1.2 2014/04/21 22:15:37 djm Exp $
|
||||
# $OpenBSD: dhgex.sh,v 1.3 2015/10/23 02:22:01 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="dhgex"
|
||||
@ -20,7 +20,9 @@ ssh_test_dhgex()
|
||||
echo "Ciphers=$cipher" >> $OBJ/sshd_proxy
|
||||
rm -f ${LOG}
|
||||
opts="-oKexAlgorithms=$kex -oCiphers=$cipher"
|
||||
groupsz="1024<$bits<8192"
|
||||
min=2048
|
||||
max=8192
|
||||
groupsz="$min<$bits<$max"
|
||||
verbose "$tid bits $bits $kex $cipher"
|
||||
${SSH} ${opts} $@ -vvv -F ${OBJ}/ssh_proxy somehost true
|
||||
if [ $? -ne 0 ]; then
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: hostkey-rotate.sh,v 1.4 2015/07/10 06:23:25 markus Exp $
|
||||
# $OpenBSD: hostkey-rotate.sh,v 1.5 2015/09/04 04:23:10 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="hostkey rotate"
|
||||
@ -108,21 +108,3 @@ verbose "check rotate primary hostkey"
|
||||
dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa
|
||||
expect_nkeys 1 "learn hostkeys"
|
||||
check_key_present ssh-rsa || fail "didn't learn changed key"
|
||||
|
||||
# $OpenBSD: hostkey-rotate.sh,v 1.4 2015/07/10 06:23:25 markus Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="hostkey rotate"
|
||||
|
||||
# Prepare hostkeys file with one key
|
||||
|
||||
# Connect to sshd
|
||||
|
||||
# Check that other keys learned
|
||||
|
||||
# Change one hostkey (non primary)
|
||||
|
||||
# Connect to sshd
|
||||
|
||||
# Check that the key was replaced
|
||||
|
||||
|
@ -36,6 +36,12 @@ exec cat "$OBJ/authorized_keys_${LOGNAME}"
|
||||
_EOF
|
||||
$SUDO chmod 0755 "$KEY_COMMAND"
|
||||
|
||||
if ! $OBJ/check-perm -m keys-command $KEY_COMMAND ; then
|
||||
echo "skipping: $KEY_COMMAND is unsuitable as AuthorizedKeysCommand"
|
||||
$SUDO rm -f $KEY_COMMAND
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -x $KEY_COMMAND ]; then
|
||||
cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: keyscan.sh,v 1.4 2015/03/03 22:35:19 markus Exp $
|
||||
# $OpenBSD: keyscan.sh,v 1.5 2015/09/11 03:44:21 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="keyscan"
|
||||
@ -8,7 +8,7 @@ rm -f ${OBJ}/host.dsa
|
||||
|
||||
start_sshd
|
||||
|
||||
KEYTYPES="rsa dsa"
|
||||
KEYTYPES=`${SSH} -Q key-plain`
|
||||
if ssh_version 1; then
|
||||
KEYTYPES="${KEYTYPES} rsa1"
|
||||
fi
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: limit-keytype.sh,v 1.1 2015/01/13 07:49:49 djm Exp $
|
||||
# $OpenBSD: limit-keytype.sh,v 1.4 2015/10/29 08:05:17 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="restrict pubkey type"
|
||||
@ -20,18 +20,19 @@ ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key2 || \
|
||||
fatal "ssh-keygen failed"
|
||||
${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key3 || \
|
||||
fatal "ssh-keygen failed"
|
||||
${SSHKEYGEN} -q -N '' -t dsa -f $OBJ/user_key4 || \
|
||||
fatal "ssh-keygen failed"
|
||||
${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \
|
||||
-z $$ -n ${USER},mekmitasdigoat $OBJ/user_key3 ||
|
||||
fatal "couldn't sign user_key1"
|
||||
# Copy the private key alongside the cert to allow better control of when
|
||||
# it is offered.
|
||||
mv $OBJ/user_key3-cert.pub $OBJ/cert_user_key3.pub
|
||||
cp -p $OBJ/user_key3 $OBJ/cert_user_key3
|
||||
|
||||
grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy
|
||||
|
||||
opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes"
|
||||
fullopts="$opts -i $OBJ/cert_user_key3 -i $OBJ/user_key1 -i $OBJ/user_key2"
|
||||
certopts="$opts -i $OBJ/user_key3 -oCertificateFile=$OBJ/cert_user_key3.pub"
|
||||
|
||||
echo mekmitasdigoat > $OBJ/authorized_principals_$USER
|
||||
cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER
|
||||
@ -53,28 +54,44 @@ prepare_config() {
|
||||
prepare_config
|
||||
|
||||
# Check we can log in with all key types.
|
||||
${SSH} $opts -i $OBJ/cert_user_key3 proxy true || fatal "cert failed"
|
||||
${SSH} $certopts proxy true || fatal "cert failed"
|
||||
${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
|
||||
${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed"
|
||||
|
||||
# Allow plain Ed25519 and RSA. The certificate should fail.
|
||||
verbose "privsep=$privsep allow rsa,ed25519"
|
||||
verbose "allow rsa,ed25519"
|
||||
prepare_config "PubkeyAcceptedKeyTypes ssh-rsa,ssh-ed25519"
|
||||
${SSH} $opts -i $OBJ/cert_user_key3 proxy true && fatal "cert succeeded"
|
||||
${SSH} $certopts proxy true && fatal "cert succeeded"
|
||||
${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
|
||||
${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed"
|
||||
|
||||
# Allow Ed25519 only.
|
||||
verbose "privsep=$privsep allow ed25519"
|
||||
verbose "allow ed25519"
|
||||
prepare_config "PubkeyAcceptedKeyTypes ssh-ed25519"
|
||||
${SSH} $opts -i $OBJ/cert_user_key3 proxy true && fatal "cert succeeded"
|
||||
${SSH} $certopts proxy true && fatal "cert succeeded"
|
||||
${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
|
||||
${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded"
|
||||
|
||||
# Allow all certs. Plain keys should fail.
|
||||
verbose "privsep=$privsep allow cert only"
|
||||
verbose "allow cert only"
|
||||
prepare_config "PubkeyAcceptedKeyTypes ssh-*-cert-v01@openssh.com"
|
||||
${SSH} $opts -i $OBJ/cert_user_key3 proxy true || fatal "cert failed"
|
||||
${SSH} $certopts proxy true || fatal "cert failed"
|
||||
${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded"
|
||||
${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded"
|
||||
|
||||
# Allow RSA in main config, Ed25519 for non-existent user.
|
||||
verbose "match w/ no match"
|
||||
prepare_config "PubkeyAcceptedKeyTypes ssh-rsa" \
|
||||
"Match user x$USER" "PubkeyAcceptedKeyTypes +ssh-ed25519"
|
||||
${SSH} $certopts proxy true && fatal "cert succeeded"
|
||||
${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded"
|
||||
${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed"
|
||||
|
||||
# Allow only DSA in main config, Ed25519 for user.
|
||||
verbose "match w/ matching"
|
||||
prepare_config "PubkeyAcceptedKeyTypes ssh-dss" \
|
||||
"Match user $USER" "PubkeyAcceptedKeyTypes +ssh-ed25519"
|
||||
${SSH} $certopts proxy true || fatal "cert failed"
|
||||
${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
|
||||
${SSH} $opts -i $OBJ/user_key4 proxy true && fatal "key4 succeeded"
|
||||
|
||||
|
@ -24,6 +24,13 @@ _EOF
|
||||
test $? -eq 0 || fatal "couldn't prepare principals command"
|
||||
$SUDO chmod 0755 "$PRINCIPALS_CMD"
|
||||
|
||||
if ! $OBJ/check-perm -m keys-command $PRINCIPALS_CMD ; then
|
||||
echo "skipping: $PRINCIPALS_CMD is unsuitable as " \
|
||||
"AuthorizedPrincipalsCommand"
|
||||
$SUDO rm -f $PRINCIPALS_CMD
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create a CA key and a user certificate.
|
||||
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key || \
|
||||
fatal "ssh-keygen of user_ca_key failed"
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: proxy-connect.sh,v 1.8 2015/03/03 22:35:19 markus Exp $
|
||||
# $OpenBSD: proxy-connect.sh,v 1.9 2016/02/17 02:24:17 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="proxy connect"
|
||||
@ -18,7 +18,8 @@ for ps in no yes; do
|
||||
fail "ssh proxyconnect protocol $p privsep=$ps comp=$c failed"
|
||||
fi
|
||||
if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
|
||||
fail "bad SSH_CONNECTION protocol $p privsep=$ps comp=$c"
|
||||
fail "bad SSH_CONNECTION protocol $p privsep=$ps comp=$c: " \
|
||||
"$SSH_CONNECTION"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: rekey.sh,v 1.16 2015/02/14 12:43:16 markus Exp $
|
||||
# $OpenBSD: rekey.sh,v 1.17 2016/01/29 05:18:15 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="rekey"
|
||||
@ -137,13 +137,15 @@ for s in 5 10; do
|
||||
done
|
||||
|
||||
verbose "rekeylimit parsing"
|
||||
for size in 16 1k 1K 1m 1M 1g 1G; do
|
||||
for size in 16 1k 1K 1m 1M 1g 1G 4G 8G; do
|
||||
for time in 1 1m 1M 1h 1H 1d 1D 1w 1W; do
|
||||
case $size in
|
||||
16) bytes=16 ;;
|
||||
1k|1K) bytes=1024 ;;
|
||||
1m|1M) bytes=1048576 ;;
|
||||
1g|1G) bytes=1073741824 ;;
|
||||
4g|4G) bytes=4294967296 ;;
|
||||
8g|8G) bytes=8589934592 ;;
|
||||
esac
|
||||
case $time in
|
||||
1) seconds=1 ;;
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
void
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "check-setuid [path]\n");
|
||||
|
@ -12,6 +12,11 @@ if [ -z "$SUDO" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! $OBJ/check-perm -m chroot "$CHROOT" ; then
|
||||
echo "skipped: $CHROOT is unsuitable as ChrootDirectory"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
$SUDO sh -c "echo mekmitastdigoat > $PRIVDATA" || \
|
||||
fatal "create $PRIVDATA failed"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: test_file.c,v 1.4 2015/07/07 14:53:30 markus Exp $ */
|
||||
/* $OpenBSD: test_file.c,v 1.5 2015/10/06 01:20:59 djm Exp $ */
|
||||
/*
|
||||
* Regress test for sshkey.h key management API
|
||||
*
|
||||
@ -54,8 +54,7 @@ sshkey_file_tests(void)
|
||||
#ifdef WITH_SSH1
|
||||
TEST_START("parse RSA1 from private");
|
||||
buf = load_file("rsa1_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k1, NULL);
|
||||
a = load_bignum("rsa1_1.param.n");
|
||||
@ -66,7 +65,7 @@ sshkey_file_tests(void)
|
||||
TEST_START("parse RSA1 from private w/ passphrase");
|
||||
buf = load_file("rsa1_1_pw");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
(const char *)sshbuf_ptr(pw), "rsa1_1_pw", &k2, NULL), 0);
|
||||
(const char *)sshbuf_ptr(pw), &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
@ -104,8 +103,7 @@ sshkey_file_tests(void)
|
||||
|
||||
TEST_START("parse RSA from private");
|
||||
buf = load_file("rsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa_1",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k1, NULL);
|
||||
a = load_bignum("rsa_1.param.n");
|
||||
@ -122,7 +120,7 @@ sshkey_file_tests(void)
|
||||
TEST_START("parse RSA from private w/ passphrase");
|
||||
buf = load_file("rsa_1_pw");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
(const char *)sshbuf_ptr(pw), "rsa_1_pw", &k2, NULL), 0);
|
||||
(const char *)sshbuf_ptr(pw), &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
@ -131,8 +129,7 @@ sshkey_file_tests(void)
|
||||
|
||||
TEST_START("parse RSA from new-format");
|
||||
buf = load_file("rsa_n");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
"", "rsa_n", &k2, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
@ -142,7 +139,7 @@ sshkey_file_tests(void)
|
||||
TEST_START("parse RSA from new-format w/ passphrase");
|
||||
buf = load_file("rsa_n_pw");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
(const char *)sshbuf_ptr(pw), "rsa_n_pw", &k2, NULL), 0);
|
||||
(const char *)sshbuf_ptr(pw), &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
@ -197,8 +194,7 @@ sshkey_file_tests(void)
|
||||
|
||||
TEST_START("parse DSA from private");
|
||||
buf = load_file("dsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "dsa_1",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k1, NULL);
|
||||
a = load_bignum("dsa_1.param.g");
|
||||
@ -215,7 +211,7 @@ sshkey_file_tests(void)
|
||||
TEST_START("parse DSA from private w/ passphrase");
|
||||
buf = load_file("dsa_1_pw");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
(const char *)sshbuf_ptr(pw), "dsa_1_pw", &k2, NULL), 0);
|
||||
(const char *)sshbuf_ptr(pw), &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
@ -224,8 +220,7 @@ sshkey_file_tests(void)
|
||||
|
||||
TEST_START("parse DSA from new-format");
|
||||
buf = load_file("dsa_n");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
"", "dsa_n", &k2, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
@ -235,7 +230,7 @@ sshkey_file_tests(void)
|
||||
TEST_START("parse DSA from new-format w/ passphrase");
|
||||
buf = load_file("dsa_n_pw");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
(const char *)sshbuf_ptr(pw), "dsa_n_pw", &k2, NULL), 0);
|
||||
(const char *)sshbuf_ptr(pw), &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
@ -291,8 +286,7 @@ sshkey_file_tests(void)
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
TEST_START("parse ECDSA from private");
|
||||
buf = load_file("ecdsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ecdsa_1",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k1, NULL);
|
||||
buf = load_text_file("ecdsa_1.param.curve");
|
||||
@ -315,7 +309,7 @@ sshkey_file_tests(void)
|
||||
TEST_START("parse ECDSA from private w/ passphrase");
|
||||
buf = load_file("ecdsa_1_pw");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
(const char *)sshbuf_ptr(pw), "ecdsa_1_pw", &k2, NULL), 0);
|
||||
(const char *)sshbuf_ptr(pw), &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
@ -324,8 +318,7 @@ sshkey_file_tests(void)
|
||||
|
||||
TEST_START("parse ECDSA from new-format");
|
||||
buf = load_file("ecdsa_n");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
"", "ecdsa_n", &k2, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
@ -335,7 +328,7 @@ sshkey_file_tests(void)
|
||||
TEST_START("parse ECDSA from new-format w/ passphrase");
|
||||
buf = load_file("ecdsa_n_pw");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
(const char *)sshbuf_ptr(pw), "ecdsa_n_pw", &k2, NULL), 0);
|
||||
(const char *)sshbuf_ptr(pw), &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
@ -391,8 +384,7 @@ sshkey_file_tests(void)
|
||||
|
||||
TEST_START("parse Ed25519 from private");
|
||||
buf = load_file("ed25519_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ed25519_1",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k1, NULL);
|
||||
ASSERT_INT_EQ(k1->type, KEY_ED25519);
|
||||
@ -402,7 +394,7 @@ sshkey_file_tests(void)
|
||||
TEST_START("parse Ed25519 from private w/ passphrase");
|
||||
buf = load_file("ed25519_1_pw");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
|
||||
(const char *)sshbuf_ptr(pw), "ed25519_1_pw", &k2, NULL), 0);
|
||||
(const char *)sshbuf_ptr(pw), &k2, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: test_fuzz.c,v 1.4 2015/03/04 23:22:35 djm Exp $ */
|
||||
/* $OpenBSD: test_fuzz.c,v 1.6 2015/12/07 02:20:46 djm Exp $ */
|
||||
/*
|
||||
* Fuzz tests for key parsing
|
||||
*
|
||||
@ -72,13 +72,13 @@ public_fuzz(struct sshkey *k)
|
||||
}
|
||||
|
||||
static void
|
||||
sig_fuzz(struct sshkey *k)
|
||||
sig_fuzz(struct sshkey *k, const char *sig_alg)
|
||||
{
|
||||
struct fuzz *fuzz;
|
||||
u_char *sig, c[] = "some junk to be signed";
|
||||
size_t l;
|
||||
|
||||
ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), 0), 0);
|
||||
ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), sig_alg, 0), 0);
|
||||
ASSERT_SIZE_T_GT(l, 0);
|
||||
fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* too slow FUZZ_2_BIT_FLIP | */
|
||||
FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
|
||||
@ -110,8 +110,7 @@ sshkey_fuzz_tests(void)
|
||||
fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
|
||||
FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
|
||||
sshbuf_mutable_ptr(buf), sshbuf_len(buf));
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshkey_free(k1);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
|
||||
@ -119,8 +118,7 @@ sshkey_fuzz_tests(void)
|
||||
for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
|
||||
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
|
||||
ASSERT_INT_EQ(r, 0);
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", "key",
|
||||
&k1, NULL) == 0)
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
|
||||
sshkey_free(k1);
|
||||
sshbuf_reset(fuzzed);
|
||||
}
|
||||
@ -154,8 +152,7 @@ sshkey_fuzz_tests(void)
|
||||
buf = load_file("rsa_1");
|
||||
fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
|
||||
sshbuf_len(buf));
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshkey_free(k1);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
|
||||
@ -163,8 +160,7 @@ sshkey_fuzz_tests(void)
|
||||
for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
|
||||
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
|
||||
ASSERT_INT_EQ(r, 0);
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", "key",
|
||||
&k1, NULL) == 0)
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
|
||||
sshkey_free(k1);
|
||||
sshbuf_reset(fuzzed);
|
||||
}
|
||||
@ -176,8 +172,7 @@ sshkey_fuzz_tests(void)
|
||||
buf = load_file("rsa_n");
|
||||
fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
|
||||
sshbuf_len(buf));
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshkey_free(k1);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
|
||||
@ -185,8 +180,7 @@ sshkey_fuzz_tests(void)
|
||||
for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
|
||||
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
|
||||
ASSERT_INT_EQ(r, 0);
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", "key",
|
||||
&k1, NULL) == 0)
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
|
||||
sshkey_free(k1);
|
||||
sshbuf_reset(fuzzed);
|
||||
}
|
||||
@ -198,8 +192,7 @@ sshkey_fuzz_tests(void)
|
||||
buf = load_file("dsa_1");
|
||||
fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
|
||||
sshbuf_len(buf));
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshkey_free(k1);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
|
||||
@ -207,8 +200,7 @@ sshkey_fuzz_tests(void)
|
||||
for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
|
||||
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
|
||||
ASSERT_INT_EQ(r, 0);
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", "key",
|
||||
&k1, NULL) == 0)
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
|
||||
sshkey_free(k1);
|
||||
sshbuf_reset(fuzzed);
|
||||
}
|
||||
@ -220,8 +212,7 @@ sshkey_fuzz_tests(void)
|
||||
buf = load_file("dsa_n");
|
||||
fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
|
||||
sshbuf_len(buf));
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshkey_free(k1);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
|
||||
@ -229,8 +220,7 @@ sshkey_fuzz_tests(void)
|
||||
for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
|
||||
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
|
||||
ASSERT_INT_EQ(r, 0);
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", "key",
|
||||
&k1, NULL) == 0)
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
|
||||
sshkey_free(k1);
|
||||
sshbuf_reset(fuzzed);
|
||||
}
|
||||
@ -243,8 +233,7 @@ sshkey_fuzz_tests(void)
|
||||
buf = load_file("ecdsa_1");
|
||||
fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
|
||||
sshbuf_len(buf));
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshkey_free(k1);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
|
||||
@ -252,8 +241,7 @@ sshkey_fuzz_tests(void)
|
||||
for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
|
||||
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
|
||||
ASSERT_INT_EQ(r, 0);
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", "key",
|
||||
&k1, NULL) == 0)
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
|
||||
sshkey_free(k1);
|
||||
sshbuf_reset(fuzzed);
|
||||
}
|
||||
@ -265,8 +253,7 @@ sshkey_fuzz_tests(void)
|
||||
buf = load_file("ecdsa_n");
|
||||
fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
|
||||
sshbuf_len(buf));
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshkey_free(k1);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
|
||||
@ -274,8 +261,7 @@ sshkey_fuzz_tests(void)
|
||||
for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
|
||||
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
|
||||
ASSERT_INT_EQ(r, 0);
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", "key",
|
||||
&k1, NULL) == 0)
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
|
||||
sshkey_free(k1);
|
||||
sshbuf_reset(fuzzed);
|
||||
}
|
||||
@ -288,8 +274,7 @@ sshkey_fuzz_tests(void)
|
||||
buf = load_file("ed25519_1");
|
||||
fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
|
||||
sshbuf_len(buf));
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshkey_free(k1);
|
||||
sshbuf_free(buf);
|
||||
ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
|
||||
@ -297,8 +282,7 @@ sshkey_fuzz_tests(void)
|
||||
for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
|
||||
r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
|
||||
ASSERT_INT_EQ(r, 0);
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", "key",
|
||||
&k1, NULL) == 0)
|
||||
if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
|
||||
sshkey_free(k1);
|
||||
sshbuf_reset(fuzzed);
|
||||
}
|
||||
@ -308,8 +292,7 @@ sshkey_fuzz_tests(void)
|
||||
|
||||
TEST_START("fuzz RSA public");
|
||||
buf = load_file("rsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
public_fuzz(k1);
|
||||
sshkey_free(k1);
|
||||
@ -323,8 +306,7 @@ sshkey_fuzz_tests(void)
|
||||
|
||||
TEST_START("fuzz DSA public");
|
||||
buf = load_file("dsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
public_fuzz(k1);
|
||||
sshkey_free(k1);
|
||||
@ -339,8 +321,7 @@ sshkey_fuzz_tests(void)
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
TEST_START("fuzz ECDSA public");
|
||||
buf = load_file("ecdsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
public_fuzz(k1);
|
||||
sshkey_free(k1);
|
||||
@ -355,8 +336,7 @@ sshkey_fuzz_tests(void)
|
||||
|
||||
TEST_START("fuzz Ed25519 public");
|
||||
buf = load_file("ed25519_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
public_fuzz(k1);
|
||||
sshkey_free(k1);
|
||||
@ -370,39 +350,51 @@ sshkey_fuzz_tests(void)
|
||||
|
||||
TEST_START("fuzz RSA sig");
|
||||
buf = load_file("rsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
sig_fuzz(k1);
|
||||
sig_fuzz(k1, "ssh-rsa");
|
||||
sshkey_free(k1);
|
||||
TEST_DONE();
|
||||
|
||||
TEST_START("fuzz RSA SHA256 sig");
|
||||
buf = load_file("rsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
sig_fuzz(k1, "rsa-sha2-256");
|
||||
sshkey_free(k1);
|
||||
TEST_DONE();
|
||||
|
||||
TEST_START("fuzz RSA SHA512 sig");
|
||||
buf = load_file("rsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
sig_fuzz(k1, "rsa-sha2-512");
|
||||
sshkey_free(k1);
|
||||
TEST_DONE();
|
||||
|
||||
TEST_START("fuzz DSA sig");
|
||||
buf = load_file("dsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
sig_fuzz(k1);
|
||||
sig_fuzz(k1, NULL);
|
||||
sshkey_free(k1);
|
||||
TEST_DONE();
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
TEST_START("fuzz ECDSA sig");
|
||||
buf = load_file("ecdsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
sig_fuzz(k1);
|
||||
sig_fuzz(k1, NULL);
|
||||
sshkey_free(k1);
|
||||
TEST_DONE();
|
||||
#endif
|
||||
|
||||
TEST_START("fuzz Ed25519 sig");
|
||||
buf = load_file("ed25519_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
|
||||
&k1, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
sig_fuzz(k1);
|
||||
sig_fuzz(k1, NULL);
|
||||
sshkey_free(k1);
|
||||
TEST_DONE();
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: test_sshkey.c,v 1.7 2015/08/05 05:27:33 djm Exp $ */
|
||||
/* $OpenBSD: test_sshkey.c,v 1.9 2015/12/07 02:20:46 djm Exp $ */
|
||||
/*
|
||||
* Regress test for sshkey.h key management API
|
||||
*
|
||||
@ -52,7 +52,8 @@ put_opt(struct sshbuf *b, const char *name, const char *value)
|
||||
|
||||
static void
|
||||
build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
|
||||
const struct sshkey *sign_key, const struct sshkey *ca_key)
|
||||
const struct sshkey *sign_key, const struct sshkey *ca_key,
|
||||
const char *sig_alg)
|
||||
{
|
||||
struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts;
|
||||
u_char *sigblob;
|
||||
@ -99,7 +100,7 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
|
||||
ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
|
||||
ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
|
||||
ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
|
||||
sshbuf_ptr(b), sshbuf_len(b), 0), 0);
|
||||
sshbuf_ptr(b), sshbuf_len(b), sig_alg, 0), 0);
|
||||
ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
|
||||
|
||||
free(sigblob);
|
||||
@ -111,12 +112,13 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
|
||||
}
|
||||
|
||||
static void
|
||||
signature_test(struct sshkey *k, struct sshkey *bad, const u_char *d, size_t l)
|
||||
signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg,
|
||||
const u_char *d, size_t l)
|
||||
{
|
||||
size_t len;
|
||||
u_char *sig;
|
||||
|
||||
ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, 0), 0);
|
||||
ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, 0), 0);
|
||||
ASSERT_SIZE_T_GT(len, 8);
|
||||
ASSERT_PTR_NE(sig, NULL);
|
||||
ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, 0), 0);
|
||||
@ -143,7 +145,7 @@ banana(u_char *s, size_t l)
|
||||
}
|
||||
|
||||
static void
|
||||
signature_tests(struct sshkey *k, struct sshkey *bad)
|
||||
signature_tests(struct sshkey *k, struct sshkey *bad, const char *sig_alg)
|
||||
{
|
||||
u_char i, buf[2049];
|
||||
size_t lens[] = {
|
||||
@ -155,7 +157,7 @@ signature_tests(struct sshkey *k, struct sshkey *bad)
|
||||
test_subtest_info("%s key, banana length %zu",
|
||||
sshkey_type(k), lens[i]);
|
||||
banana(buf, lens[i]);
|
||||
signature_test(k, bad, buf, lens[i]);
|
||||
signature_test(k, bad, sig_alg, buf, lens[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,7 +168,7 @@ get_private(const char *n)
|
||||
struct sshkey *ret;
|
||||
|
||||
b = load_file(n);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", n, &ret, NULL), 0);
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", &ret, NULL), 0);
|
||||
sshbuf_free(b);
|
||||
return ret;
|
||||
}
|
||||
@ -469,7 +471,25 @@ sshkey_tests(void)
|
||||
k1 = get_private("rsa_1");
|
||||
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
|
||||
NULL), 0);
|
||||
signature_tests(k1, k2);
|
||||
signature_tests(k1, k2, "ssh-rsa");
|
||||
sshkey_free(k1);
|
||||
sshkey_free(k2);
|
||||
TEST_DONE();
|
||||
|
||||
TEST_START("sign and verify RSA-SHA256");
|
||||
k1 = get_private("rsa_1");
|
||||
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
|
||||
NULL), 0);
|
||||
signature_tests(k1, k2, "rsa-sha2-256");
|
||||
sshkey_free(k1);
|
||||
sshkey_free(k2);
|
||||
TEST_DONE();
|
||||
|
||||
TEST_START("sign and verify RSA-SHA512");
|
||||
k1 = get_private("rsa_1");
|
||||
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
|
||||
NULL), 0);
|
||||
signature_tests(k1, k2, "rsa-sha2-512");
|
||||
sshkey_free(k1);
|
||||
sshkey_free(k2);
|
||||
TEST_DONE();
|
||||
@ -478,7 +498,7 @@ sshkey_tests(void)
|
||||
k1 = get_private("dsa_1");
|
||||
ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2,
|
||||
NULL), 0);
|
||||
signature_tests(k1, k2);
|
||||
signature_tests(k1, k2, NULL);
|
||||
sshkey_free(k1);
|
||||
sshkey_free(k2);
|
||||
TEST_DONE();
|
||||
@ -488,7 +508,7 @@ sshkey_tests(void)
|
||||
k1 = get_private("ecdsa_1");
|
||||
ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2,
|
||||
NULL), 0);
|
||||
signature_tests(k1, k2);
|
||||
signature_tests(k1, k2, NULL);
|
||||
sshkey_free(k1);
|
||||
sshkey_free(k2);
|
||||
TEST_DONE();
|
||||
@ -498,7 +518,7 @@ sshkey_tests(void)
|
||||
k1 = get_private("ed25519_1");
|
||||
ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2,
|
||||
NULL), 0);
|
||||
signature_tests(k1, k2);
|
||||
signature_tests(k1, k2, NULL);
|
||||
sshkey_free(k1);
|
||||
sshkey_free(k2);
|
||||
TEST_DONE();
|
||||
@ -508,7 +528,7 @@ sshkey_tests(void)
|
||||
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
|
||||
NULL), 0);
|
||||
k3 = get_private("rsa_1");
|
||||
build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1);
|
||||
build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL);
|
||||
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
|
||||
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
|
||||
ASSERT_PTR_EQ(k4, NULL);
|
||||
|
45
roaming.h
45
roaming.h
@ -1,45 +0,0 @@
|
||||
/* $OpenBSD: roaming.h,v 1.6 2011/12/07 05:44:38 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004-2009 AppGate Network Security AB
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ROAMING_H
|
||||
#define ROAMING_H
|
||||
|
||||
#define DEFAULT_ROAMBUF 65536
|
||||
#define MAX_ROAMBUF (2*1024*1024) /* XXX arbitrary */
|
||||
#define ROAMING_REQUEST "roaming@appgate.com"
|
||||
|
||||
extern int roaming_enabled;
|
||||
extern int resume_in_progress;
|
||||
|
||||
void request_roaming(void);
|
||||
int get_snd_buf_size(void);
|
||||
int get_recv_buf_size(void);
|
||||
void add_recv_bytes(u_int64_t);
|
||||
int wait_for_roaming_reconnect(void);
|
||||
void roaming_reply(int, u_int32_t, void *);
|
||||
void set_out_buffer_size(size_t);
|
||||
ssize_t roaming_write(int, const void *, size_t, int *);
|
||||
ssize_t roaming_read(int, void *, size_t, int *);
|
||||
size_t roaming_atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
u_int64_t get_recv_bytes(void);
|
||||
u_int64_t get_sent_bytes(void);
|
||||
void roam_set_bytes(u_int64_t, u_int64_t);
|
||||
void resend_bytes(int, u_int64_t *);
|
||||
void calculate_new_key(u_int64_t *, u_int64_t, u_int64_t);
|
||||
int resume_kex(void);
|
||||
|
||||
#endif /* ROAMING */
|
271
roaming_client.c
271
roaming_client.c
@ -1,271 +0,0 @@
|
||||
/* $OpenBSD: roaming_client.c,v 1.9 2015/01/27 12:54:06 okan Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004-2009 AppGate Network Security AB
|
||||
*
|
||||
* 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"
|
||||
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "channels.h"
|
||||
#include "cipher.h"
|
||||
#include "dispatch.h"
|
||||
#include "clientloop.h"
|
||||
#include "log.h"
|
||||
#include "match.h"
|
||||
#include "misc.h"
|
||||
#include "packet.h"
|
||||
#include "ssh.h"
|
||||
#include "key.h"
|
||||
#include "kex.h"
|
||||
#include "readconf.h"
|
||||
#include "roaming.h"
|
||||
#include "ssh2.h"
|
||||
#include "sshconnect.h"
|
||||
#include "digest.h"
|
||||
|
||||
/* import */
|
||||
extern Options options;
|
||||
extern char *host;
|
||||
extern struct sockaddr_storage hostaddr;
|
||||
extern int session_resumed;
|
||||
|
||||
static u_int32_t roaming_id;
|
||||
static u_int64_t cookie;
|
||||
static u_int64_t lastseenchall;
|
||||
static u_int64_t key1, key2, oldkey1, oldkey2;
|
||||
|
||||
void
|
||||
roaming_reply(int type, u_int32_t seq, void *ctxt)
|
||||
{
|
||||
if (type == SSH2_MSG_REQUEST_FAILURE) {
|
||||
logit("Server denied roaming");
|
||||
return;
|
||||
}
|
||||
verbose("Roaming enabled");
|
||||
roaming_id = packet_get_int();
|
||||
cookie = packet_get_int64();
|
||||
key1 = oldkey1 = packet_get_int64();
|
||||
key2 = oldkey2 = packet_get_int64();
|
||||
set_out_buffer_size(packet_get_int() + get_snd_buf_size());
|
||||
roaming_enabled = 1;
|
||||
}
|
||||
|
||||
void
|
||||
request_roaming(void)
|
||||
{
|
||||
packet_start(SSH2_MSG_GLOBAL_REQUEST);
|
||||
packet_put_cstring(ROAMING_REQUEST);
|
||||
packet_put_char(1);
|
||||
packet_put_int(get_recv_buf_size());
|
||||
packet_send();
|
||||
client_register_global_confirm(roaming_reply, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
roaming_auth_required(void)
|
||||
{
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
Buffer b;
|
||||
u_int64_t chall, oldchall;
|
||||
|
||||
chall = packet_get_int64();
|
||||
oldchall = packet_get_int64();
|
||||
if (oldchall != lastseenchall) {
|
||||
key1 = oldkey1;
|
||||
key2 = oldkey2;
|
||||
}
|
||||
lastseenchall = chall;
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_put_int64(&b, cookie);
|
||||
buffer_put_int64(&b, chall);
|
||||
if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, digest, sizeof(digest)) != 0)
|
||||
fatal("%s: ssh_digest_buffer failed", __func__);
|
||||
buffer_free(&b);
|
||||
|
||||
packet_start(SSH2_MSG_KEX_ROAMING_AUTH);
|
||||
packet_put_int64(key1 ^ get_recv_bytes());
|
||||
packet_put_raw(digest, ssh_digest_bytes(SSH_DIGEST_SHA1));
|
||||
packet_send();
|
||||
|
||||
oldkey1 = key1;
|
||||
oldkey2 = key2;
|
||||
calculate_new_key(&key1, cookie, chall);
|
||||
calculate_new_key(&key2, cookie, chall);
|
||||
|
||||
debug("Received %llu bytes", (unsigned long long)get_recv_bytes());
|
||||
debug("Sent roaming_auth packet");
|
||||
}
|
||||
|
||||
int
|
||||
resume_kex(void)
|
||||
{
|
||||
/*
|
||||
* This should not happen - if the client sends the kex method
|
||||
* resume@appgate.com then the kex is done in roaming_resume().
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
roaming_resume(void)
|
||||
{
|
||||
u_int64_t recv_bytes;
|
||||
char *str = NULL, *kexlist = NULL, *c;
|
||||
int i, type;
|
||||
int timeout_ms = options.connection_timeout * 1000;
|
||||
u_int len;
|
||||
u_int32_t rnd = 0;
|
||||
|
||||
resume_in_progress = 1;
|
||||
|
||||
/* Exchange banners */
|
||||
ssh_exchange_identification(timeout_ms);
|
||||
packet_set_nonblocking();
|
||||
|
||||
/* Send a kexinit message with resume@appgate.com as only kex algo */
|
||||
packet_start(SSH2_MSG_KEXINIT);
|
||||
for (i = 0; i < KEX_COOKIE_LEN; i++) {
|
||||
if (i % 4 == 0)
|
||||
rnd = arc4random();
|
||||
packet_put_char(rnd & 0xff);
|
||||
rnd >>= 8;
|
||||
}
|
||||
packet_put_cstring(KEX_RESUME);
|
||||
for (i = 1; i < PROPOSAL_MAX; i++) {
|
||||
/* kex algorithm added so start with i=1 and not 0 */
|
||||
packet_put_cstring(""); /* Not used when we resume */
|
||||
}
|
||||
packet_put_char(1); /* first kex_packet follows */
|
||||
packet_put_int(0); /* reserved */
|
||||
packet_send();
|
||||
|
||||
/* Assume that resume@appgate.com will be accepted */
|
||||
packet_start(SSH2_MSG_KEX_ROAMING_RESUME);
|
||||
packet_put_int(roaming_id);
|
||||
packet_send();
|
||||
|
||||
/* Read the server's kexinit and check for resume@appgate.com */
|
||||
if ((type = packet_read()) != SSH2_MSG_KEXINIT) {
|
||||
debug("expected kexinit on resume, got %d", type);
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < KEX_COOKIE_LEN; i++)
|
||||
(void)packet_get_char();
|
||||
kexlist = packet_get_string(&len);
|
||||
if (!kexlist
|
||||
|| (str = match_list(KEX_RESUME, kexlist, NULL)) == NULL) {
|
||||
debug("server doesn't allow resume");
|
||||
goto fail;
|
||||
}
|
||||
free(str);
|
||||
for (i = 1; i < PROPOSAL_MAX; i++) {
|
||||
/* kex algorithm taken care of so start with i=1 and not 0 */
|
||||
free(packet_get_string(&len));
|
||||
}
|
||||
i = packet_get_char(); /* first_kex_packet_follows */
|
||||
if (i && (c = strchr(kexlist, ',')))
|
||||
*c = 0;
|
||||
if (i && strcmp(kexlist, KEX_RESUME)) {
|
||||
debug("server's kex guess (%s) was wrong, skipping", kexlist);
|
||||
(void)packet_read(); /* Wrong guess - discard packet */
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the ROAMING_AUTH_REQUIRED challenge from the server and
|
||||
* send ROAMING_AUTH
|
||||
*/
|
||||
if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED) {
|
||||
debug("expected roaming_auth_required, got %d", type);
|
||||
goto fail;
|
||||
}
|
||||
roaming_auth_required();
|
||||
|
||||
/* Read ROAMING_AUTH_OK from the server */
|
||||
if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_OK) {
|
||||
debug("expected roaming_auth_ok, got %d", type);
|
||||
goto fail;
|
||||
}
|
||||
recv_bytes = packet_get_int64() ^ oldkey2;
|
||||
debug("Peer received %llu bytes", (unsigned long long)recv_bytes);
|
||||
resend_bytes(packet_get_connection_out(), &recv_bytes);
|
||||
|
||||
resume_in_progress = 0;
|
||||
|
||||
session_resumed = 1; /* Tell clientloop */
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
free(kexlist);
|
||||
if (packet_get_connection_in() == packet_get_connection_out())
|
||||
close(packet_get_connection_in());
|
||||
else {
|
||||
close(packet_get_connection_in());
|
||||
close(packet_get_connection_out());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
wait_for_roaming_reconnect(void)
|
||||
{
|
||||
static int reenter_guard = 0;
|
||||
int timeout_ms = options.connection_timeout * 1000;
|
||||
int c;
|
||||
|
||||
if (reenter_guard != 0)
|
||||
fatal("Server refused resume, roaming timeout may be exceeded");
|
||||
reenter_guard = 1;
|
||||
|
||||
fprintf(stderr, "[connection suspended, press return to resume]");
|
||||
fflush(stderr);
|
||||
packet_backup_state();
|
||||
/* TODO Perhaps we should read from tty here */
|
||||
while ((c = fgetc(stdin)) != EOF) {
|
||||
if (c == 'Z' - 64) {
|
||||
kill(getpid(), SIGTSTP);
|
||||
continue;
|
||||
}
|
||||
if (c != '\n' && c != '\r')
|
||||
continue;
|
||||
|
||||
if (ssh_connect(host, NULL, &hostaddr, options.port,
|
||||
options.address_family, 1, &timeout_ms,
|
||||
options.tcp_keep_alive, options.use_privileged_port) == 0 &&
|
||||
roaming_resume() == 0) {
|
||||
packet_restore_state();
|
||||
reenter_guard = 0;
|
||||
fprintf(stderr, "[connection resumed]\n");
|
||||
fflush(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[reconnect failed, press return to retry]");
|
||||
fflush(stderr);
|
||||
}
|
||||
fprintf(stderr, "[exiting]\n");
|
||||
fflush(stderr);
|
||||
exit(0);
|
||||
}
|
241
roaming_common.c
241
roaming_common.c
@ -1,241 +0,0 @@
|
||||
/* $OpenBSD: roaming_common.c,v 1.13 2015/01/27 12:54:06 okan Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004-2009 AppGate Network Security AB
|
||||
*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "atomicio.h"
|
||||
#include "log.h"
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "cipher.h"
|
||||
#include "buffer.h"
|
||||
#include "roaming.h"
|
||||
#include "digest.h"
|
||||
|
||||
static size_t out_buf_size = 0;
|
||||
static char *out_buf = NULL;
|
||||
static size_t out_start;
|
||||
static size_t out_last;
|
||||
|
||||
static u_int64_t write_bytes = 0;
|
||||
static u_int64_t read_bytes = 0;
|
||||
|
||||
int roaming_enabled = 0;
|
||||
int resume_in_progress = 0;
|
||||
|
||||
int
|
||||
get_snd_buf_size(void)
|
||||
{
|
||||
int fd = packet_get_connection_out();
|
||||
int optval;
|
||||
socklen_t optvallen = sizeof(optval);
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optvallen) != 0)
|
||||
optval = DEFAULT_ROAMBUF;
|
||||
return optval;
|
||||
}
|
||||
|
||||
int
|
||||
get_recv_buf_size(void)
|
||||
{
|
||||
int fd = packet_get_connection_in();
|
||||
int optval;
|
||||
socklen_t optvallen = sizeof(optval);
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, &optvallen) != 0)
|
||||
optval = DEFAULT_ROAMBUF;
|
||||
return optval;
|
||||
}
|
||||
|
||||
void
|
||||
set_out_buffer_size(size_t size)
|
||||
{
|
||||
if (size == 0 || size > MAX_ROAMBUF)
|
||||
fatal("%s: bad buffer size %lu", __func__, (u_long)size);
|
||||
/*
|
||||
* The buffer size can only be set once and the buffer will live
|
||||
* as long as the session lives.
|
||||
*/
|
||||
if (out_buf == NULL) {
|
||||
out_buf_size = size;
|
||||
out_buf = xmalloc(size);
|
||||
out_start = 0;
|
||||
out_last = 0;
|
||||
}
|
||||
}
|
||||
|
||||
u_int64_t
|
||||
get_recv_bytes(void)
|
||||
{
|
||||
return read_bytes;
|
||||
}
|
||||
|
||||
void
|
||||
add_recv_bytes(u_int64_t num)
|
||||
{
|
||||
read_bytes += num;
|
||||
}
|
||||
|
||||
u_int64_t
|
||||
get_sent_bytes(void)
|
||||
{
|
||||
return write_bytes;
|
||||
}
|
||||
|
||||
void
|
||||
roam_set_bytes(u_int64_t sent, u_int64_t recvd)
|
||||
{
|
||||
read_bytes = recvd;
|
||||
write_bytes = sent;
|
||||
}
|
||||
|
||||
static void
|
||||
buf_append(const char *buf, size_t count)
|
||||
{
|
||||
if (count > out_buf_size) {
|
||||
buf += count - out_buf_size;
|
||||
count = out_buf_size;
|
||||
}
|
||||
if (count < out_buf_size - out_last) {
|
||||
memcpy(out_buf + out_last, buf, count);
|
||||
if (out_start > out_last)
|
||||
out_start += count;
|
||||
out_last += count;
|
||||
} else {
|
||||
/* data will wrap */
|
||||
size_t chunk = out_buf_size - out_last;
|
||||
memcpy(out_buf + out_last, buf, chunk);
|
||||
memcpy(out_buf, buf + chunk, count - chunk);
|
||||
out_last = count - chunk;
|
||||
out_start = out_last + 1;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
roaming_write(int fd, const void *buf, size_t count, int *cont)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
ret = write(fd, buf, count);
|
||||
if (ret > 0 && !resume_in_progress) {
|
||||
write_bytes += ret;
|
||||
if (out_buf_size > 0)
|
||||
buf_append(buf, ret);
|
||||
}
|
||||
if (out_buf_size > 0 &&
|
||||
(ret == 0 || (ret == -1 && errno == EPIPE))) {
|
||||
if (wait_for_roaming_reconnect() != 0) {
|
||||
ret = 0;
|
||||
*cont = 1;
|
||||
} else {
|
||||
ret = -1;
|
||||
errno = EAGAIN;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
roaming_read(int fd, void *buf, size_t count, int *cont)
|
||||
{
|
||||
ssize_t ret = read(fd, buf, count);
|
||||
if (ret > 0) {
|
||||
if (!resume_in_progress) {
|
||||
read_bytes += ret;
|
||||
}
|
||||
} else if (out_buf_size > 0 &&
|
||||
(ret == 0 || (ret == -1 && (errno == ECONNRESET
|
||||
|| errno == ECONNABORTED || errno == ETIMEDOUT
|
||||
|| errno == EHOSTUNREACH)))) {
|
||||
debug("roaming_read failed for %d ret=%ld errno=%d",
|
||||
fd, (long)ret, errno);
|
||||
ret = 0;
|
||||
if (wait_for_roaming_reconnect() == 0)
|
||||
*cont = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
roaming_atomicio(ssize_t(*f)(int, void*, size_t), int fd, void *buf,
|
||||
size_t count)
|
||||
{
|
||||
size_t ret = atomicio(f, fd, buf, count);
|
||||
|
||||
if (f == vwrite && ret > 0 && !resume_in_progress) {
|
||||
write_bytes += ret;
|
||||
} else if (f == read && ret > 0 && !resume_in_progress) {
|
||||
read_bytes += ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
resend_bytes(int fd, u_int64_t *offset)
|
||||
{
|
||||
size_t available, needed;
|
||||
|
||||
if (out_start < out_last)
|
||||
available = out_last - out_start;
|
||||
else
|
||||
available = out_buf_size;
|
||||
needed = write_bytes - *offset;
|
||||
debug3("resend_bytes: resend %lu bytes from %llu",
|
||||
(unsigned long)needed, (unsigned long long)*offset);
|
||||
if (needed > available)
|
||||
fatal("Needed to resend more data than in the cache");
|
||||
if (out_last < needed) {
|
||||
int chunkend = needed - out_last;
|
||||
atomicio(vwrite, fd, out_buf + out_buf_size - chunkend,
|
||||
chunkend);
|
||||
atomicio(vwrite, fd, out_buf, out_last);
|
||||
} else {
|
||||
atomicio(vwrite, fd, out_buf + (out_last - needed), needed);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Caclulate a new key after a reconnect
|
||||
*/
|
||||
void
|
||||
calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge)
|
||||
{
|
||||
u_char hash[SSH_DIGEST_MAX_LENGTH];
|
||||
Buffer b;
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_put_int64(&b, *key);
|
||||
buffer_put_int64(&b, cookie);
|
||||
buffer_put_int64(&b, challenge);
|
||||
|
||||
if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, hash, sizeof(hash)) != 0)
|
||||
fatal("%s: digest_buffer failed", __func__);
|
||||
|
||||
buffer_clear(&b);
|
||||
buffer_append(&b, hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
|
||||
*key = buffer_get_int64(&b);
|
||||
buffer_free(&b);
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/* $OpenBSD: roaming_dummy.c,v 1.4 2015/01/19 19:52:16 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004-2009 AppGate Network Security AB
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is included in the client programs which should not
|
||||
* support roaming.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "roaming.h"
|
||||
|
||||
int resume_in_progress = 0;
|
||||
|
||||
u_int64_t
|
||||
get_recv_bytes(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u_int64_t
|
||||
get_sent_bytes(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
roam_set_bytes(u_int64_t sent, u_int64_t recvd)
|
||||
{
|
||||
}
|
||||
|
||||
ssize_t
|
||||
roaming_write(int fd, const void *buf, size_t count, int *cont)
|
||||
{
|
||||
return write(fd, buf, count);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
roaming_read(int fd, void *buf, size_t count, int *cont)
|
||||
{
|
||||
if (cont)
|
||||
*cont = 0;
|
||||
return read(fd, buf, count);
|
||||
}
|
||||
|
||||
void
|
||||
add_recv_bytes(u_int64_t num)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
resume_kex(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/* $OpenBSD: roaming_serv.c,v 1.1 2009/10/24 11:18:23 andreas Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004-2009 AppGate Network Security AB
|
||||
*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "roaming.h"
|
||||
|
||||
/*
|
||||
* Wait for the roaming client to reconnect. Returns 0 if a connect ocurred.
|
||||
*/
|
||||
int
|
||||
wait_for_roaming_reconnect(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
77
sandbox-pledge.c
Normal file
77
sandbox-pledge.c
Normal file
@ -0,0 +1,77 @@
|
||||
/* $OpenBSD: sandbox-pledge.c,v 1.1 2015/10/09 01:37:08 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Theo de Raadt <deraadt@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef SANDBOX_PLEDGE
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "ssh-sandbox.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
struct ssh_sandbox {
|
||||
pid_t child_pid;
|
||||
};
|
||||
|
||||
struct ssh_sandbox *
|
||||
ssh_sandbox_init(struct monitor *m)
|
||||
{
|
||||
struct ssh_sandbox *box;
|
||||
|
||||
debug3("%s: preparing pledge sandbox", __func__);
|
||||
box = xcalloc(1, sizeof(*box));
|
||||
box->child_pid = 0;
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
void
|
||||
ssh_sandbox_child(struct ssh_sandbox *box)
|
||||
{
|
||||
if (pledge("stdio", NULL) == -1)
|
||||
fatal("%s: pledge()", __func__);
|
||||
}
|
||||
|
||||
void
|
||||
ssh_sandbox_parent_finish(struct ssh_sandbox *box)
|
||||
{
|
||||
free(box);
|
||||
debug3("%s: finished", __func__);
|
||||
}
|
||||
|
||||
void
|
||||
ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
|
||||
{
|
||||
box->child_pid = child_pid;
|
||||
/* Nothing to do here */
|
||||
}
|
||||
|
||||
#endif /* SANDBOX_PLEDGE */
|
@ -147,6 +147,9 @@ static const struct sock_filter preauth_insns[] = {
|
||||
#ifdef __NR_getpid
|
||||
SC_ALLOW(getpid),
|
||||
#endif
|
||||
#ifdef __NR_getrandom
|
||||
SC_ALLOW(getrandom),
|
||||
#endif
|
||||
#ifdef __NR_gettimeofday
|
||||
SC_ALLOW(gettimeofday),
|
||||
#endif
|
||||
|
108
sandbox-solaris.c
Normal file
108
sandbox-solaris.c
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Joyent, Inc
|
||||
* Author: Alex Wilson <alex.wilson@joyent.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef SANDBOX_SOLARIS
|
||||
#ifndef USE_SOLARIS_PRIVS
|
||||
# error "--with-solaris-privs must be used with the Solaris sandbox"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_PRIV_H
|
||||
# include <priv.h>
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "ssh-sandbox.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
struct ssh_sandbox {
|
||||
priv_set_t *pset;
|
||||
};
|
||||
|
||||
struct ssh_sandbox *
|
||||
ssh_sandbox_init(struct monitor *monitor)
|
||||
{
|
||||
struct ssh_sandbox *box = NULL;
|
||||
|
||||
box = xcalloc(1, sizeof(*box));
|
||||
|
||||
/* Start with "basic" and drop everything we don't need. */
|
||||
box->pset = solaris_basic_privset();
|
||||
|
||||
if (box->pset == NULL) {
|
||||
free(box);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Drop everything except the ability to use already-opened files */
|
||||
if (priv_delset(box->pset, PRIV_FILE_LINK_ANY) != 0 ||
|
||||
#ifdef PRIV_NET_ACCESS
|
||||
priv_delset(box->pset, PRIV_NET_ACCESS) != 0 ||
|
||||
#endif
|
||||
priv_delset(box->pset, PRIV_PROC_EXEC) != 0 ||
|
||||
priv_delset(box->pset, PRIV_PROC_FORK) != 0 ||
|
||||
priv_delset(box->pset, PRIV_PROC_INFO) != 0 ||
|
||||
priv_delset(box->pset, PRIV_PROC_SESSION) != 0) {
|
||||
free(box);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* These may not be available on older Solaris-es */
|
||||
# if defined(PRIV_FILE_READ) && defined(PRIV_FILE_WRITE)
|
||||
if (priv_delset(box->pset, PRIV_FILE_READ) != 0 ||
|
||||
priv_delset(box->pset, PRIV_FILE_WRITE) != 0) {
|
||||
free(box);
|
||||
return NULL;
|
||||
}
|
||||
# endif
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
void
|
||||
ssh_sandbox_child(struct ssh_sandbox *box)
|
||||
{
|
||||
if (setppriv(PRIV_SET, PRIV_PERMITTED, box->pset) != 0 ||
|
||||
setppriv(PRIV_SET, PRIV_LIMIT, box->pset) != 0 ||
|
||||
setppriv(PRIV_SET, PRIV_INHERITABLE, box->pset) != 0)
|
||||
fatal("setppriv: %s", strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
ssh_sandbox_parent_finish(struct ssh_sandbox *box)
|
||||
{
|
||||
priv_freeset(box->pset);
|
||||
box->pset = NULL;
|
||||
free(box);
|
||||
}
|
||||
|
||||
void
|
||||
ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
|
||||
{
|
||||
/* Nothing to do here */
|
||||
}
|
||||
|
||||
#endif /* SANDBOX_SOLARIS */
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sandbox-systrace.c,v 1.17 2015/07/27 16:29:23 guenther Exp $ */
|
||||
/* $OpenBSD: sandbox-systrace.c,v 1.18 2015/10/02 01:39:26 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
@ -50,9 +50,17 @@ struct sandbox_policy {
|
||||
|
||||
/* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */
|
||||
static const struct sandbox_policy preauth_policy[] = {
|
||||
{ SYS_clock_gettime, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_close, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_exit, SYSTR_POLICY_PERMIT },
|
||||
#ifdef SYS_kbind
|
||||
{ SYS_kbind, SYSTR_POLICY_PERMIT },
|
||||
#endif
|
||||
|
||||
{ SYS_getpid, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_getpgid, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_clock_gettime, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_gettimeofday, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_sigprocmask, SYSTR_POLICY_PERMIT },
|
||||
|
||||
#ifdef SYS_getentropy
|
||||
/* OpenBSD 5.6 and newer use getentropy(2) to seed arc4random(3). */
|
||||
{ SYS_getentropy, SYSTR_POLICY_PERMIT },
|
||||
@ -60,27 +68,25 @@ static const struct sandbox_policy preauth_policy[] = {
|
||||
/* Previous releases used sysctl(3)'s kern.arnd variable. */
|
||||
{ SYS___sysctl, SYSTR_POLICY_PERMIT },
|
||||
#endif
|
||||
{ SYS_getpid, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_getpgid, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_gettimeofday, SYSTR_POLICY_PERMIT },
|
||||
#ifdef SYS_kbind
|
||||
{ SYS_kbind, SYSTR_POLICY_PERMIT },
|
||||
#ifdef SYS_sendsyslog
|
||||
{ SYS_sendsyslog, SYSTR_POLICY_PERMIT },
|
||||
#endif
|
||||
|
||||
{ SYS_madvise, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_mmap, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_mprotect, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_mquery, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_munmap, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_open, SYSTR_POLICY_NEVER },
|
||||
|
||||
{ SYS_poll, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_read, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_select, SYSTR_POLICY_PERMIT },
|
||||
#ifdef SYS_sendsyslog
|
||||
{ SYS_sendsyslog, SYSTR_POLICY_PERMIT },
|
||||
#endif
|
||||
{ SYS_shutdown, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_sigprocmask, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_read, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_write, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_shutdown, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_close, SYSTR_POLICY_PERMIT },
|
||||
|
||||
{ SYS_open, SYSTR_POLICY_NEVER },
|
||||
|
||||
{ -1, -1 }
|
||||
};
|
||||
|
||||
|
3
scp.0
3
scp.0
@ -72,6 +72,7 @@ DESCRIPTION
|
||||
CanonicalizeHostname
|
||||
CanonicalizeMaxDots
|
||||
CanonicalizePermittedCNAMEs
|
||||
CertificateFile
|
||||
ChallengeResponseAuthentication
|
||||
CheckHostIP
|
||||
Cipher
|
||||
@ -162,4 +163,4 @@ AUTHORS
|
||||
Timo Rinne <tri@iki.fi>
|
||||
Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
||||
OpenBSD 5.8 July 10, 2015 OpenBSD 5.8
|
||||
OpenBSD 5.9 September 25, 2015 OpenBSD 5.9
|
||||
|
5
scp.1
5
scp.1
@ -8,9 +8,9 @@
|
||||
.\"
|
||||
.\" Created: Sun May 7 00:14:37 1995 ylo
|
||||
.\"
|
||||
.\" $OpenBSD: scp.1,v 1.67 2015/07/10 06:21:53 markus Exp $
|
||||
.\" $OpenBSD: scp.1,v 1.68 2015/09/25 18:19:54 jmc Exp $
|
||||
.\"
|
||||
.Dd $Mdocdate: July 10 2015 $
|
||||
.Dd $Mdocdate: September 25 2015 $
|
||||
.Dt SCP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -133,6 +133,7 @@ For full details of the options listed below, and their possible values, see
|
||||
.It CanonicalizeHostname
|
||||
.It CanonicalizeMaxDots
|
||||
.It CanonicalizePermittedCNAMEs
|
||||
.It CertificateFile
|
||||
.It ChallengeResponseAuthentication
|
||||
.It CheckHostIP
|
||||
.It Cipher
|
||||
|
14
scp.c
14
scp.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: scp.c,v 1.182 2015/04/24 01:36:00 deraadt Exp $ */
|
||||
/* $OpenBSD: scp.c,v 1.184 2015/11/27 00:49:31 deraadt Exp $ */
|
||||
/*
|
||||
* scp - secure remote copy. This is basically patched BSD rcp which
|
||||
* uses ssh to do the data transfer (instead of using rcmd).
|
||||
@ -484,6 +484,16 @@ main(int argc, char **argv)
|
||||
if (!isatty(STDOUT_FILENO))
|
||||
showprogress = 0;
|
||||
|
||||
if (pflag) {
|
||||
/* Cannot pledge: -p allows setuid/setgid files... */
|
||||
} else {
|
||||
if (pledge("stdio rpath wpath cpath fattr tty proc exec",
|
||||
NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
remin = STDIN_FILENO;
|
||||
remout = STDOUT_FILENO;
|
||||
|
||||
@ -866,7 +876,7 @@ rsource(char *name, struct stat *statp)
|
||||
return;
|
||||
}
|
||||
last = strrchr(name, '/');
|
||||
if (last == 0)
|
||||
if (last == NULL)
|
||||
last = name;
|
||||
else
|
||||
last++;
|
||||
|
59
servconf.c
59
servconf.c
@ -1,5 +1,5 @@
|
||||
|
||||
/* $OpenBSD: servconf.c,v 1.280 2015/08/06 14:53:21 deraadt Exp $ */
|
||||
/* $OpenBSD: servconf.c,v 1.285 2016/02/17 05:29:04 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -178,6 +178,20 @@ option_clear_or_none(const char *o)
|
||||
return o == NULL || strcasecmp(o, "none") == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
assemble_algorithms(ServerOptions *o)
|
||||
{
|
||||
if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 ||
|
||||
kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 ||
|
||||
kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 ||
|
||||
kex_assemble_names(KEX_DEFAULT_PK_ALG,
|
||||
&o->hostkeyalgorithms) != 0 ||
|
||||
kex_assemble_names(KEX_DEFAULT_PK_ALG,
|
||||
&o->hostbased_key_types) != 0 ||
|
||||
kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0)
|
||||
fatal("kex_assemble_names failed");
|
||||
}
|
||||
|
||||
void
|
||||
fill_default_server_options(ServerOptions *options)
|
||||
{
|
||||
@ -259,8 +273,6 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->hostbased_authentication = 0;
|
||||
if (options->hostbased_uses_name_from_packet_only == -1)
|
||||
options->hostbased_uses_name_from_packet_only = 0;
|
||||
if (options->hostkeyalgorithms == NULL)
|
||||
options->hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG);
|
||||
if (options->rsa_authentication == -1)
|
||||
options->rsa_authentication = 1;
|
||||
if (options->pubkey_authentication == -1)
|
||||
@ -342,18 +354,11 @@ fill_default_server_options(ServerOptions *options)
|
||||
if (options->fingerprint_hash == -1)
|
||||
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
|
||||
|
||||
if (kex_assemble_names(KEX_SERVER_ENCRYPT, &options->ciphers) != 0 ||
|
||||
kex_assemble_names(KEX_SERVER_MAC, &options->macs) != 0 ||
|
||||
kex_assemble_names(KEX_SERVER_KEX, &options->kex_algorithms) != 0 ||
|
||||
kex_assemble_names(KEX_DEFAULT_PK_ALG,
|
||||
&options->hostbased_key_types) != 0 ||
|
||||
kex_assemble_names(KEX_DEFAULT_PK_ALG,
|
||||
&options->pubkey_key_types) != 0)
|
||||
fatal("%s: kex_assemble_names failed", __func__);
|
||||
assemble_algorithms(options);
|
||||
|
||||
/* Turn privilege separation on by default */
|
||||
/* Turn privilege separation and sandboxing on by default */
|
||||
if (use_privsep == -1)
|
||||
use_privsep = PRIVSEP_NOSANDBOX;
|
||||
use_privsep = PRIVSEP_ON;
|
||||
|
||||
#define CLEAR_ON_NONE(v) \
|
||||
do { \
|
||||
@ -368,6 +373,8 @@ fill_default_server_options(ServerOptions *options)
|
||||
CLEAR_ON_NONE(options->trusted_user_ca_keys);
|
||||
CLEAR_ON_NONE(options->revoked_keys_file);
|
||||
CLEAR_ON_NONE(options->authorized_principals_file);
|
||||
CLEAR_ON_NONE(options->adm_forced_command);
|
||||
CLEAR_ON_NONE(options->chroot_directory);
|
||||
for (i = 0; i < options->num_host_key_files; i++)
|
||||
CLEAR_ON_NONE(options->host_key_files[i]);
|
||||
for (i = 0; i < options->num_host_cert_files; i++)
|
||||
@ -499,7 +506,11 @@ static struct {
|
||||
{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
|
||||
{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
|
||||
{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
|
||||
#ifdef DISABLE_LASTLOG
|
||||
{ "printlastlog", sUnsupported, SSHCFG_GLOBAL },
|
||||
#else
|
||||
{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
|
||||
{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
|
||||
{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
|
||||
@ -1319,16 +1330,12 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
if (scan_scaled(arg, &val64) == -1)
|
||||
fatal("%.200s line %d: Bad number '%s': %s",
|
||||
filename, linenum, arg, strerror(errno));
|
||||
/* check for too-large or too-small limits */
|
||||
if (val64 > UINT_MAX)
|
||||
fatal("%.200s line %d: RekeyLimit too large",
|
||||
filename, linenum);
|
||||
if (val64 != 0 && val64 < 16)
|
||||
fatal("%.200s line %d: RekeyLimit too small",
|
||||
filename, linenum);
|
||||
}
|
||||
if (*activep && options->rekey_limit == -1)
|
||||
options->rekey_limit = (u_int32_t)val64;
|
||||
options->rekey_limit = val64;
|
||||
if (cp != NULL) { /* optional rekey interval present */
|
||||
if (strcmp(cp, "none") == 0) {
|
||||
(void)strdelim(&cp); /* discard */
|
||||
@ -2015,6 +2022,9 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
||||
/* See comment in servconf.h */
|
||||
COPY_MATCH_STRING_OPTS();
|
||||
|
||||
/* Arguments that accept '+...' need to be expanded */
|
||||
assemble_algorithms(dst);
|
||||
|
||||
/*
|
||||
* The only things that should be below this point are string options
|
||||
* which are only used after authentication.
|
||||
@ -2022,8 +2032,17 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
||||
if (preauth)
|
||||
return;
|
||||
|
||||
/* These options may be "none" to clear a global setting */
|
||||
M_CP_STROPT(adm_forced_command);
|
||||
if (option_clear_or_none(dst->adm_forced_command)) {
|
||||
free(dst->adm_forced_command);
|
||||
dst->adm_forced_command = NULL;
|
||||
}
|
||||
M_CP_STROPT(chroot_directory);
|
||||
if (option_clear_or_none(dst->chroot_directory)) {
|
||||
free(dst->chroot_directory);
|
||||
dst->chroot_directory = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#undef M_CP_INTOPT
|
||||
@ -2254,7 +2273,9 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_fmtint(sChallengeResponseAuthentication,
|
||||
o->challenge_response_authentication);
|
||||
dump_cfg_fmtint(sPrintMotd, o->print_motd);
|
||||
#ifndef DISABLE_LASTLOG
|
||||
dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
|
||||
#endif
|
||||
dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
|
||||
dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
|
||||
dump_cfg_fmtint(sPermitTTY, o->permit_tty);
|
||||
@ -2338,7 +2359,7 @@ dump_config(ServerOptions *o)
|
||||
printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
|
||||
printf("%s\n", iptos2str(o->ip_qos_bulk));
|
||||
|
||||
printf("rekeylimit %lld %d\n", (long long)o->rekey_limit,
|
||||
printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
|
||||
o->rekey_interval);
|
||||
|
||||
channel_print_adm_permitted_opens();
|
||||
|
31
serverloop.c
31
serverloop.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: serverloop.c,v 1.178 2015/02/20 22:17:21 djm Exp $ */
|
||||
/* $OpenBSD: serverloop.c,v 1.182 2016/02/08 10:57:07 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -78,7 +78,6 @@
|
||||
#include "dispatch.h"
|
||||
#include "auth-options.h"
|
||||
#include "serverloop.h"
|
||||
#include "roaming.h"
|
||||
#include "ssherr.h"
|
||||
|
||||
extern ServerOptions options;
|
||||
@ -399,11 +398,8 @@ process_input(fd_set *readset)
|
||||
|
||||
/* Read and buffer any input data from the client. */
|
||||
if (FD_ISSET(connection_in, readset)) {
|
||||
int cont = 0;
|
||||
len = roaming_read(connection_in, buf, sizeof(buf), &cont);
|
||||
len = read(connection_in, buf, sizeof(buf));
|
||||
if (len == 0) {
|
||||
if (cont)
|
||||
return;
|
||||
verbose("Connection closed by %.100s",
|
||||
get_remote_ipaddr());
|
||||
connection_closed = 1;
|
||||
@ -824,7 +820,7 @@ void
|
||||
server_loop2(Authctxt *authctxt)
|
||||
{
|
||||
fd_set *readset = NULL, *writeset = NULL;
|
||||
int rekeying = 0, max_fd;
|
||||
int max_fd;
|
||||
u_int nalloc = 0;
|
||||
u_int64_t rekey_timeout_ms = 0;
|
||||
|
||||
@ -851,11 +847,11 @@ server_loop2(Authctxt *authctxt)
|
||||
for (;;) {
|
||||
process_buffered_input_packets();
|
||||
|
||||
rekeying = (active_state->kex != NULL && !active_state->kex->done);
|
||||
|
||||
if (!rekeying && packet_not_very_much_data_to_write())
|
||||
if (!ssh_packet_is_rekeying(active_state) &&
|
||||
packet_not_very_much_data_to_write())
|
||||
channel_output_poll();
|
||||
if (options.rekey_interval > 0 && compat20 && !rekeying)
|
||||
if (options.rekey_interval > 0 && compat20 &&
|
||||
!ssh_packet_is_rekeying(active_state))
|
||||
rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
|
||||
else
|
||||
rekey_timeout_ms = 0;
|
||||
@ -870,14 +866,8 @@ server_loop2(Authctxt *authctxt)
|
||||
}
|
||||
|
||||
collect_children();
|
||||
if (!rekeying) {
|
||||
if (!ssh_packet_is_rekeying(active_state))
|
||||
channel_after_select(readset, writeset);
|
||||
if (packet_need_rekeying()) {
|
||||
debug("need rekeying");
|
||||
active_state->kex->done = 0;
|
||||
kex_send_kexinit(active_state);
|
||||
}
|
||||
}
|
||||
process_input(readset);
|
||||
if (connection_closed)
|
||||
break;
|
||||
@ -1201,7 +1191,7 @@ server_input_hostkeys_prove(struct sshbuf **respp)
|
||||
ssh->kex->session_id, ssh->kex->session_id_len)) != 0 ||
|
||||
(r = sshkey_puts(key, sigbuf)) != 0 ||
|
||||
(r = ssh->kex->sign(key_prv, key_pub, &sig, &slen,
|
||||
sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), 0)) != 0 ||
|
||||
sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), NULL, 0)) != 0 ||
|
||||
(r = sshbuf_put_string(resp, sig, slen)) != 0) {
|
||||
error("%s: couldn't prepare signature: %s",
|
||||
__func__, ssh_err(r));
|
||||
@ -1265,7 +1255,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
|
||||
free(fwd.listen_host);
|
||||
if ((resp = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new", __func__);
|
||||
if ((r = sshbuf_put_u32(resp, allocated_listen_port)) != 0)
|
||||
if (allocated_listen_port != 0 &&
|
||||
(r = sshbuf_put_u32(resp, allocated_listen_port)) != 0)
|
||||
fatal("%s: sshbuf_put_u32: %s", __func__, ssh_err(r));
|
||||
} else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
|
||||
struct Forward fwd;
|
||||
|
52
session.c
52
session.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: session.c,v 1.278 2015/04/24 01:36:00 deraadt Exp $ */
|
||||
/* $OpenBSD: session.c,v 1.280 2016/02/16 03:37:48 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -160,6 +160,7 @@ login_cap_t *lc;
|
||||
#endif
|
||||
|
||||
static int is_child = 0;
|
||||
static int in_chroot = 0;
|
||||
|
||||
/* Name and directory of socket for authentication agent forwarding. */
|
||||
static char *auth_sock_name = NULL;
|
||||
@ -778,8 +779,8 @@ int
|
||||
do_exec(Session *s, const char *command)
|
||||
{
|
||||
int ret;
|
||||
const char *forced = NULL;
|
||||
char session_type[1024], *tty = NULL;
|
||||
const char *forced = NULL, *tty = NULL;
|
||||
char session_type[1024];
|
||||
|
||||
if (options.adm_forced_command) {
|
||||
original_command = command;
|
||||
@ -814,13 +815,14 @@ do_exec(Session *s, const char *command)
|
||||
tty += 5;
|
||||
}
|
||||
|
||||
verbose("Starting session: %s%s%s for %s from %.200s port %d",
|
||||
verbose("Starting session: %s%s%s for %s from %.200s port %d id %d",
|
||||
session_type,
|
||||
tty == NULL ? "" : " on ",
|
||||
tty == NULL ? "" : tty,
|
||||
s->pw->pw_name,
|
||||
get_remote_ipaddr(),
|
||||
get_remote_port());
|
||||
get_remote_port(),
|
||||
s->self);
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
if (command != NULL)
|
||||
@ -1490,9 +1492,6 @@ void
|
||||
do_setusercontext(struct passwd *pw)
|
||||
{
|
||||
char *chroot_path, *tmp;
|
||||
#ifdef USE_LIBIAF
|
||||
int doing_chroot = 0;
|
||||
#endif
|
||||
|
||||
platform_setusercontext(pw);
|
||||
|
||||
@ -1520,7 +1519,7 @@ do_setusercontext(struct passwd *pw)
|
||||
|
||||
platform_setusercontext_post_groups(pw);
|
||||
|
||||
if (options.chroot_directory != NULL &&
|
||||
if (!in_chroot && options.chroot_directory != NULL &&
|
||||
strcasecmp(options.chroot_directory, "none") != 0) {
|
||||
tmp = tilde_expand_filename(options.chroot_directory,
|
||||
pw->pw_uid);
|
||||
@ -1532,9 +1531,7 @@ do_setusercontext(struct passwd *pw)
|
||||
/* Make sure we don't attempt to chroot again */
|
||||
free(options.chroot_directory);
|
||||
options.chroot_directory = NULL;
|
||||
#ifdef USE_LIBIAF
|
||||
doing_chroot = 1;
|
||||
#endif
|
||||
in_chroot = 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
@ -1549,16 +1546,16 @@ do_setusercontext(struct passwd *pw)
|
||||
(void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUMASK);
|
||||
#else
|
||||
# ifdef USE_LIBIAF
|
||||
/* In a chroot environment, the set_id() will always fail; typically
|
||||
* because of the lack of necessary authentication services and runtime
|
||||
* such as ./usr/lib/libiaf.so, ./usr/lib/libpam.so.1, and ./etc/passwd
|
||||
* We skip it in the internal sftp chroot case.
|
||||
* We'll lose auditing and ACLs but permanently_set_uid will
|
||||
* take care of the rest.
|
||||
*/
|
||||
if ((doing_chroot == 0) && set_id(pw->pw_name) != 0) {
|
||||
fatal("set_id(%s) Failed", pw->pw_name);
|
||||
}
|
||||
/*
|
||||
* In a chroot environment, the set_id() will always fail;
|
||||
* typically because of the lack of necessary authentication
|
||||
* services and runtime such as ./usr/lib/libiaf.so,
|
||||
* ./usr/lib/libpam.so.1, and ./etc/passwd We skip it in the
|
||||
* internal sftp chroot case. We'll lose auditing and ACLs but
|
||||
* permanently_set_uid will take care of the rest.
|
||||
*/
|
||||
if (!in_chroot && set_id(pw->pw_name) != 0)
|
||||
fatal("set_id(%s) Failed", pw->pw_name);
|
||||
# endif /* USE_LIBIAF */
|
||||
/* Permanently switch to the desired uid. */
|
||||
permanently_set_uid(pw);
|
||||
@ -1790,11 +1787,11 @@ do_child(Session *s, const char *command)
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
r = login_getcapbool(lc, "requirehome", 0);
|
||||
#endif
|
||||
if (r || options.chroot_directory == NULL ||
|
||||
strcasecmp(options.chroot_directory, "none") == 0)
|
||||
if (r || !in_chroot) {
|
||||
fprintf(stderr, "Could not chdir to home "
|
||||
"directory %s: %s\n", pw->pw_dir,
|
||||
strerror(errno));
|
||||
}
|
||||
if (r)
|
||||
exit(1);
|
||||
}
|
||||
@ -2503,7 +2500,12 @@ session_close(Session *s)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
debug("session_close: session %d pid %ld", s->self, (long)s->pid);
|
||||
verbose("Close session: user %s from %.200s port %d id %d",
|
||||
s->pw->pw_name,
|
||||
get_remote_ipaddr(),
|
||||
get_remote_port(),
|
||||
s->self);
|
||||
|
||||
if (s->ttyfd != -1)
|
||||
session_pty_cleanup(s);
|
||||
free(s->term);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-client.c,v 1.120 2015/05/28 04:50:53 djm Exp $ */
|
||||
/* $OpenBSD: sftp-client.c,v 1.121 2016/02/11 02:21:34 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
@ -1760,7 +1760,7 @@ do_upload(struct sftp_conn *conn, const char *local_path,
|
||||
if (fsync_flag)
|
||||
(void)do_fsync(conn, handle, handle_len);
|
||||
|
||||
if (do_close(conn, handle, handle_len) != SSH2_FX_OK)
|
||||
if (do_close(conn, handle, handle_len) != 0)
|
||||
status = SSH2_FX_FAILURE;
|
||||
|
||||
free(handle);
|
||||
@ -1773,12 +1773,11 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
int depth, int preserve_flag, int print_flag, int resume, int fsync_flag)
|
||||
{
|
||||
int ret = 0;
|
||||
u_int status;
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
char *filename, *new_src, *new_dst;
|
||||
struct stat sb;
|
||||
Attrib a;
|
||||
Attrib a, *dirattrib;
|
||||
|
||||
if (depth >= MAX_DIR_DEPTH) {
|
||||
error("Maximum directory depth exceeded: %d levels", depth);
|
||||
@ -1805,17 +1804,18 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
if (!preserve_flag)
|
||||
a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
|
||||
|
||||
status = do_mkdir(conn, dst, &a, 0);
|
||||
/*
|
||||
* we lack a portable status for errno EEXIST,
|
||||
* so if we get a SSH2_FX_FAILURE back we must check
|
||||
* if it was created successfully.
|
||||
* sftp lacks a portable status value to match errno EEXIST,
|
||||
* so if we get a failure back then we must check whether
|
||||
* the path already existed and is a directory.
|
||||
*/
|
||||
if (status != SSH2_FX_OK) {
|
||||
if (status != SSH2_FX_FAILURE)
|
||||
if (do_mkdir(conn, dst, &a, 0) != 0) {
|
||||
if ((dirattrib = do_stat(conn, dst, 0)) == NULL)
|
||||
return -1;
|
||||
if (do_stat(conn, dst, 0) == NULL)
|
||||
if (!S_ISDIR(dirattrib->perm)) {
|
||||
error("\"%s\" exists but is not a directory", dst);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((dirp = opendir(src)) == NULL) {
|
||||
|
@ -21,6 +21,12 @@
|
||||
#ifndef _SFTP_CLIENT_H
|
||||
#define _SFTP_CLIENT_H
|
||||
|
||||
#ifdef USE_SYSTEM_GLOB
|
||||
# include <glob.h>
|
||||
#else
|
||||
# include "openbsd-compat/glob.h"
|
||||
#endif
|
||||
|
||||
typedef struct SFTP_DIRENT SFTP_DIRENT;
|
||||
|
||||
struct SFTP_DIRENT {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-server-main.c,v 1.4 2009/02/21 19:32:04 tobias Exp $ */
|
||||
/* $OpenBSD: sftp-server-main.c,v 1.5 2016/02/15 09:47:49 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -26,6 +26,7 @@
|
||||
#include "log.h"
|
||||
#include "sftp.h"
|
||||
#include "misc.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
void
|
||||
cleanup_exit(int i)
|
||||
@ -38,6 +39,7 @@ main(int argc, char **argv)
|
||||
{
|
||||
struct passwd *user_pw;
|
||||
|
||||
ssh_malloc_init(); /* must be called before any mallocs */
|
||||
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
||||
sanitise_stdfd();
|
||||
|
||||
|
@ -93,4 +93,4 @@ HISTORY
|
||||
AUTHORS
|
||||
Markus Friedl <markus@openbsd.org>
|
||||
|
||||
OpenBSD 5.8 December 11, 2014 OpenBSD 5.8
|
||||
OpenBSD 5.9 December 11, 2014 OpenBSD 5.9
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-server.c,v 1.107 2015/08/20 22:32:42 deraadt Exp $ */
|
||||
/* $OpenBSD: sftp-server.c,v 1.109 2016/02/15 09:47:49 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -1513,6 +1513,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
extern char *optarg;
|
||||
extern char *__progname;
|
||||
|
||||
ssh_malloc_init(); /* must be called before any mallocs */
|
||||
__progname = ssh_get_progname(argv[0]);
|
||||
log_init(__progname, log_level, log_facility, log_stderr);
|
||||
|
||||
@ -1598,6 +1599,9 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
fatal("unable to make the process undumpable");
|
||||
#endif /* defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) */
|
||||
|
||||
/* Drop any fine-grained privileges we don't need */
|
||||
platform_pledge_sftp_server();
|
||||
|
||||
if ((cp = getenv("SSH_CONNECTION")) != NULL) {
|
||||
client_addr = xstrdup(cp);
|
||||
if ((cp = strchr(client_addr, ' ')) == NULL) {
|
||||
@ -1631,9 +1635,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
if ((oqueue = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
|
||||
set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask);
|
||||
rset = xmalloc(set_size);
|
||||
wset = xmalloc(set_size);
|
||||
rset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask));
|
||||
wset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask));
|
||||
|
||||
if (homedir != NULL) {
|
||||
if (chdir(homedir) != 0) {
|
||||
@ -1642,6 +1645,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
}
|
||||
}
|
||||
|
||||
set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask);
|
||||
for (;;) {
|
||||
memset(rset, 0, set_size);
|
||||
memset(wset, 0, set_size);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user