Upgrade to OpenSSH 7.2p2.

This commit is contained in:
Dag-Erling Smørgrav 2016-03-11 00:15:29 +00:00
commit acc1a9ef83
153 changed files with 5781 additions and 3345 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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) \

View File

@ -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.2p2 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

View File

@ -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
------

View File

@ -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)

View File

@ -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.

View File

@ -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;

View File

@ -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>

View File

@ -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)));

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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 *,

View File

@ -698,9 +698,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). */
#define HAVE_LIBPAM 1
@ -849,6 +846,9 @@
/* define if you have pid_t data type */
#define HAVE_PID_T 1
/* Define to 1 if you have the `pledge' function. */
/* #undef HAVE_PLEDGE */
/* Define to 1 if you have the `poll' function. */
#define HAVE_POLL 1
@ -858,6 +858,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 */
@ -960,6 +966,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. */
#define HAVE_SETPROCTITLE 1
@ -1451,6 +1460,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 */
@ -1530,6 +1542,9 @@
/* no privsep sandboxing */
/* #undef SANDBOX_NULL */
/* Sandbox using pledge(2) */
/* #undef SANDBOX_PLEDGE */
/* Sandbox using setrlimit(2) */
/* #undef SANDBOX_RLIMIT */
@ -1542,6 +1557,9 @@
/* define if setrlimit RLIMIT_NOFILE breaks things */
#define SANDBOX_SKIP_RLIMIT_NOFILE 1
/* Sandbox using Solaris/Illumos privileges */
/* #undef SANDBOX_SOLARIS */
/* Sandbox using systrace(4) */
/* #undef SANDBOX_SYSTRACE */
@ -1648,6 +1666,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 */

View File

@ -141,7 +141,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
@ -476,6 +476,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
@ -582,6 +587,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],
@ -644,6 +651,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"
@ -896,13 +906,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" ], )
],
)
@ -912,10 +925,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*)
@ -1129,7 +1161,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
@ -1293,8 +1324,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
@ -1732,6 +1765,7 @@ AC_CHECK_FUNCS([ \
nsleep \
ogetaddrinfo \
openlog_r \
pledge \
poll \
prctl \
pstat \
@ -2372,10 +2406,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
]
@ -2408,6 +2442,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>
@ -2420,7 +2455,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);
@ -2487,6 +2523,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);
]])],
@ -3061,7 +3098,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=""
@ -3157,7 +3194,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])
@ -3210,6 +3253,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"
@ -4033,7 +4080,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])
@ -4997,6 +5047,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"

View File

@ -1,4 +1,4 @@
%define ver 7.1p2
%define ver 7.2p2
%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 \

View File

@ -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)
;;

View File

@ -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.

View File

@ -13,7 +13,7 @@
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
Name: openssh
Version: 7.1p2
Version: 7.2p2
URL: http://www.openssh.com/
Release: 1
Source0: openssh-%{version}.tar.gz

View File

@ -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 */

View File

@ -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
/*

View File

@ -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

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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 */

View File

@ -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(); */

View File

@ -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(); */

View File

@ -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(); */

View File

@ -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;

View File

@ -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 *);

View File

@ -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, &sect)) != 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;

View File

@ -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);

View File

@ -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>

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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>
*
@ -1355,16 +1355,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) {
@ -1745,7 +1747,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);
@ -1890,6 +1892,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);
@ -1997,6 +2003,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 */
@ -2170,7 +2180,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);

View File

@ -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 $ */
/* $FreeBSD$ */
/*
@ -103,6 +103,8 @@
"ssh-dss-cert-v01@openssh.com," \
HOSTKEY_ECDSA_METHODS \
"ssh-ed25519," \
"rsa-sha2-512," \
"rsa-sha2-256," \
"ssh-rsa," \
"ssh-dss"
@ -114,9 +116,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," \
@ -130,18 +130,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"

View File

@ -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)
{

View File

@ -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() \

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -59,6 +59,7 @@
*/
#include "includes.h"
#include "glob.h"
#include <sys/types.h>
#include <sys/stat.h>

View File

@ -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. */

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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) */

View File

@ -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
@ -84,7 +84,6 @@ __RCSID("$FreeBSD$");
#include "channels.h"
#include "ssh.h"
#include "packet.h"
#include "roaming.h"
#include "ssherr.h"
#include "sshbuf.h"
@ -182,8 +181,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 */
@ -262,6 +260,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.
@ -339,7 +345,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;
}
@ -456,16 +463,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
@ -520,10 +541,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;
}
@ -942,7 +961,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;
@ -1010,9 +1034,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,
@ -1051,6 +1121,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)
*/
@ -1079,7 +1163,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);
@ -1201,34 +1286,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 */
@ -1244,10 +1353,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;
@ -1266,7 +1387,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;
@ -1336,11 +1457,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;
@ -1735,6 +1852,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 ||
@ -1754,6 +1873,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;
}
@ -1784,8 +1910,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);
@ -1799,8 +1924,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:
@ -1828,8 +1954,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;
logit("Received disconnect from %s: %.400s",
ssh_remote_ipaddr(ssh), msg);
logit("Received disconnect from %s port %d: "
"%.400s", ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh), msg);
free(msg);
return SSH_ERR_DISCONNECTED;
default:
@ -1919,19 +2046,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 */
@ -1941,15 +2071,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));
}
}
@ -2006,19 +2138,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;
@ -2042,7 +2173,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));
@ -2230,29 +2364,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;
@ -2292,58 +2407,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)
@ -2431,8 +2494,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;
}
@ -2463,7 +2525,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 ||
@ -2494,11 +2556,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;
}
@ -2567,10 +2624,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;
}
@ -2603,10 +2658,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)
@ -2629,7 +2682,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 ||
@ -2652,7 +2704,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 ||
@ -2694,12 +2746,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__);

View File

@ -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 *);

View 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
}

View File

@ -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);

View File

@ -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
@ -139,6 +139,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,
@ -155,7 +156,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,
@ -206,6 +207,8 @@ static struct {
{ "identityfile", oIdentityFile },
{ "identityfile2", oIdentityFile }, /* obsolete */
{ "identitiesonly", oIdentitiesOnly },
{ "certificatefile", oCertificateFile },
{ "addkeystoagent", oAddKeysToAgent },
{ "hostname", oHostName },
{ "hostkeyalias", oHostKeyAlias },
{ "proxycommand", oProxyCommand },
@ -264,7 +267,7 @@ static struct {
{ "localcommand", oLocalCommand },
{ "permitlocalcommand", oPermitLocalCommand },
{ "visualhostkey", oVisualHostKey },
{ "useroaming", oUseRoaming },
{ "useroaming", oDeprecated },
{ "kexalgorithms", oKexAlgorithms },
{ "ipqos", oIPQoS },
{ "requesttty", oRequestTTY },
@ -389,6 +392,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)
@ -440,7 +467,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;
@ -448,12 +475,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));
@ -478,7 +499,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);
@ -493,7 +514,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)
@ -526,12 +546,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);
@ -717,6 +740,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 },
@ -971,16 +1003,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 */
@ -1005,6 +1033,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;
@ -1402,10 +1448,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;
@ -1536,6 +1578,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);
@ -1666,6 +1713,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;
@ -1701,7 +1749,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;
@ -1806,6 +1854,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, "~/",
@ -1880,7 +1930,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)
@ -2291,6 +2340,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);
@ -2351,7 +2404,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);
@ -2362,6 +2415,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);
@ -2430,8 +2484,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",

View File

@ -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 $ */
/* $FreeBSD$ */
/*
@ -96,6 +96,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;
@ -131,8 +138,6 @@ typedef struct {
int permit_local_command;
int visual_host_key;
int use_roaming;
int request_tty;
int proxy_use_fdpass;
@ -197,5 +202,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 */

View File

@ -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]);

View File

@ -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 \

View File

@ -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

View 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*

View 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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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 ;;

View File

@ -26,7 +26,7 @@
#include <string.h>
#include <errno.h>
void
static void
usage(void)
{
fprintf(stderr, "check-setuid [path]\n");

View File

@ -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"

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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 */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View 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 */

View File

@ -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

View 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 */

View File

@ -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 }
};

View File

@ -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

View File

@ -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++;

View File

@ -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
@ -180,6 +180,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)
{
@ -263,8 +277,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)
@ -346,16 +358,9 @@ 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_ON;
@ -372,6 +377,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++)
@ -503,7 +510,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 },
@ -1327,16 +1338,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 */
@ -2023,6 +2030,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.
@ -2030,8 +2040,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
@ -2262,7 +2281,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);
@ -2346,7 +2367,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();

View File

@ -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;

View File

@ -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
@ -47,6 +47,7 @@ __RCSID("$FreeBSD$");
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
@ -161,6 +162,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;
@ -274,6 +276,21 @@ do_authenticated(Authctxt *authctxt)
do_cleanup(authctxt);
}
/* Check untrusted xauth strings for metacharacters */
static int
xauth_valid_string(const char *s)
{
size_t i;
for (i = 0; s[i] != '\0'; i++) {
if (!isalnum((u_char)s[i]) &&
s[i] != '.' && s[i] != ':' && s[i] != '/' &&
s[i] != '-' && s[i] != '_')
return 0;
}
return 1;
}
/*
* Prepares for an interactive session. This is called after the user has
* been successfully authenticated. During this message exchange, pseudo
@ -347,7 +364,13 @@ do_authenticated1(Authctxt *authctxt)
s->screen = 0;
}
packet_check_eom();
success = session_setup_x11fwd(s);
if (xauth_valid_string(s->auth_proto) &&
xauth_valid_string(s->auth_data))
success = session_setup_x11fwd(s);
else {
success = 0;
error("Invalid X11 forwarding data");
}
if (!success) {
free(s->auth_proto);
free(s->auth_data);
@ -779,8 +802,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;
@ -815,13 +838,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)
@ -1502,9 +1526,6 @@ void
do_setusercontext(struct passwd *pw)
{
char *chroot_path, *tmp;
#ifdef USE_LIBIAF
int doing_chroot = 0;
#endif
platform_setusercontext(pw);
@ -1532,7 +1553,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);
@ -1544,9 +1565,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
@ -1561,16 +1580,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);
@ -1802,11 +1821,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);
}
@ -2193,7 +2212,13 @@ session_x11_req(Session *s)
s->screen = packet_get_int();
packet_check_eom();
success = session_setup_x11fwd(s);
if (xauth_valid_string(s->auth_proto) &&
xauth_valid_string(s->auth_data))
success = session_setup_x11fwd(s);
else {
success = 0;
error("Invalid X11 forwarding data");
}
if (!success) {
free(s->auth_proto);
free(s->auth_data);
@ -2515,7 +2540,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);

View File

@ -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) {

View File

@ -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 {

View File

@ -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();

View File

@ -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);

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: sftp.1,v 1.101 2015/01/30 11:43:14 djm Exp $
.\" $OpenBSD: sftp.1,v 1.102 2015/09/25 18:19:54 jmc Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@ -22,7 +22,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate: January 30 2015 $
.Dd $Mdocdate: September 25 2015 $
.Dt SFTP 1
.Os
.Sh NAME
@ -198,6 +198,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

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sftp.c,v 1.171 2015/08/20 22:32:42 deraadt Exp $ */
/* $OpenBSD: sftp.c,v 1.172 2016/02/15 09:47:49 dtucker Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@ -2248,6 +2248,7 @@ main(int argc, char **argv)
size_t num_requests = DEFAULT_NUM_REQUESTS;
long long limit_kbps = 0;
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();
setlocale(LC_CTYPE, "");

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-add.c,v 1.123 2015/07/03 03:43:18 djm Exp $ */
/* $OpenBSD: ssh-add.c,v 1.128 2016/02/15 09:47:49 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -93,7 +93,7 @@ static int lifetime = 0;
/* User has to confirm key use */
static int confirm = 0;
/* we keep a cache of one passphrases */
/* we keep a cache of one passphrase */
static char *pass = NULL;
static void
clear_pass(void)
@ -150,10 +150,8 @@ delete_file(int agent_fd, const char *filename, int key_only)
certpath, ssh_err(r));
out:
if (cert != NULL)
sshkey_free(cert);
if (public != NULL)
sshkey_free(public);
sshkey_free(cert);
sshkey_free(public);
free(certpath);
free(comment);
@ -218,35 +216,32 @@ add_file(int agent_fd, const char *filename, int key_only)
close(fd);
/* At first, try empty passphrase */
if ((r = sshkey_parse_private_fileblob(keyblob, "", filename,
&private, &comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE) {
if ((r = sshkey_parse_private_fileblob(keyblob, "", &private,
&comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE) {
fprintf(stderr, "Error loading key \"%s\": %s\n",
filename, ssh_err(r));
goto fail_load;
}
/* try last */
if (private == NULL && pass != NULL) {
if ((r = sshkey_parse_private_fileblob(keyblob, pass, filename,
&private, &comment)) != 0 &&
r != SSH_ERR_KEY_WRONG_PASSPHRASE) {
if ((r = sshkey_parse_private_fileblob(keyblob, pass, &private,
&comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE) {
fprintf(stderr, "Error loading key \"%s\": %s\n",
filename, ssh_err(r));
goto fail_load;
}
}
if (comment == NULL)
comment = xstrdup(filename);
if (private == NULL) {
/* clear passphrase since it did not work */
clear_pass();
snprintf(msg, sizeof msg, "Enter passphrase for %.200s%s: ",
comment, confirm ? " (will confirm each use)" : "");
snprintf(msg, sizeof msg, "Enter passphrase for %s%s: ",
filename, confirm ? " (will confirm each use)" : "");
for (;;) {
pass = read_passphrase(msg, RP_ALLOW_STDIN);
if (strcmp(pass, "") == 0)
goto fail_load;
if ((r = sshkey_parse_private_fileblob(keyblob, pass,
filename, &private, NULL)) == 0)
&private, &comment)) == 0)
break;
else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) {
fprintf(stderr,
@ -254,16 +249,17 @@ add_file(int agent_fd, const char *filename, int key_only)
filename, ssh_err(r));
fail_load:
clear_pass();
free(comment);
sshbuf_free(keyblob);
return -1;
}
clear_pass();
snprintf(msg, sizeof msg,
"Bad passphrase, try again for %.200s%s: ", comment,
"Bad passphrase, try again for %s%s: ", filename,
confirm ? " (will confirm each use)" : "");
}
}
if (comment == NULL || *comment == '\0')
comment = xstrdup(filename);
sshbuf_free(keyblob);
if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
@ -386,7 +382,7 @@ list_identities(int agent_fd, int do_fp)
if (do_fp) {
fp = sshkey_fingerprint(idlist->keys[i],
fingerprint_hash, SSH_FP_DEFAULT);
printf("%d %s %s (%s)\n",
printf("%u %s %s (%s)\n",
sshkey_size(idlist->keys[i]),
fp == NULL ? "(null)" : fp,
idlist->comments[i],
@ -485,6 +481,7 @@ main(int argc, char **argv)
int r, i, ch, deleting = 0, ret = 0, key_only = 0;
int xflag = 0, lflag = 0, Dflag = 0;
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();

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-agent.1,v 1.59 2015/04/24 06:26:49 jmc Exp $
.\" $OpenBSD: ssh-agent.1,v 1.62 2015/11/15 23:54:15 jmc Exp $
.\" $FreeBSD$
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate: April 24 2015 $
.Dd $Mdocdate: November 15 2015 $
.Dt SSH-AGENT 1
.Os
.Sh NAME
@ -44,7 +44,7 @@
.Sh SYNOPSIS
.Nm ssh-agent
.Op Fl c | s
.Op Fl Ddx
.Op Fl \&Ddx
.Op Fl a Ar bind_address
.Op Fl E Ar fingerprint_hash
.Op Fl t Ar life
@ -67,6 +67,13 @@ machines using
.Pp
The agent initially does not have any private keys.
Keys are added using
.Xr ssh 1
(see
.Cm AddKeysToAgent
in
.Xr ssh_config 5
for details)
or
.Xr ssh-add 1 .
Multiple identities may be stored in
.Nm
@ -133,7 +140,7 @@ Without this option the default maximum lifetime is forever.
Exit after the last client has disconnected.
.El
.Pp
If a commandline is given, this is executed as a subprocess of the agent.
If a command line is given, this is executed as a subprocess of the agent.
When the command dies, so does the agent.
.Pp
The idea is that the agent is run in the user's local PC, laptop, or

Some files were not shown because too many files have changed in this diff Show More