Merge branch 'master' of https://github.com/openssh/openssh-portable into latestw

This commit is contained in:
Manoj Ampalam 2017-03-14 13:02:26 -07:00
commit b69a1eda8e
15 changed files with 317 additions and 95 deletions

View File

@ -236,6 +236,8 @@ clean: regressclean
rm -f regress/unittests/sshkey/test_sshkey
rm -f regress/unittests/bitmap/*.o
rm -f regress/unittests/bitmap/test_bitmap
rm -f regress/unittests/conversion/*.o
rm -f regress/unittests/conversion/test_conversion
rm -f regress/unittests/hostkeys/*.o
rm -f regress/unittests/hostkeys/test_hostkeys
rm -f regress/unittests/kex/*.o
@ -262,6 +264,8 @@ distclean: regressclean
rm -f regress/unittests/sshkey/test_sshkey
rm -f regress/unittests/bitmap/*.o
rm -f regress/unittests/bitmap/test_bitmap
rm -f regress/unittests/conversion/*.o
rm -f regress/unittests/conversion/test_conversion
rm -f regress/unittests/hostkeys/*.o
rm -f regress/unittests/hostkeys/test_hostkeys
rm -f regress/unittests/kex/*.o
@ -426,6 +430,8 @@ regress-prep:
mkdir -p `pwd`/regress/unittests/sshkey
[ -d `pwd`/regress/unittests/bitmap ] || \
mkdir -p `pwd`/regress/unittests/bitmap
[ -d `pwd`/regress/unittests/conversion ] || \
mkdir -p `pwd`/regress/unittests/conversion
[ -d `pwd`/regress/unittests/hostkeys ] || \
mkdir -p `pwd`/regress/unittests/hostkeys
[ -d `pwd`/regress/unittests/kex ] || \
@ -503,6 +509,16 @@ regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
UNITTESTS_TEST_CONVERSION_OBJS=\
regress/unittests/conversion/tests.o
regress/unittests/conversion/test_conversion$(EXEEXT): \
${UNITTESTS_TEST_CONVERSION_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_CONVERSION_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
UNITTESTS_TEST_KEX_OBJS=\
regress/unittests/kex/tests.o \
regress/unittests/kex/test_kex.o
@ -558,13 +574,14 @@ regress-binaries: regress/modpipe$(EXEEXT) \
regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \
regress/unittests/sshkey/test_sshkey$(EXEEXT) \
regress/unittests/bitmap/test_bitmap$(EXEEXT) \
regress/unittests/conversion/test_conversion$(EXEEXT) \
regress/unittests/hostkeys/test_hostkeys$(EXEEXT) \
regress/unittests/kex/test_kex$(EXEEXT) \
regress/unittests/match/test_match$(EXEEXT) \
regress/unittests/utf8/test_utf8$(EXEEXT) \
regress/misc/kexfuzz/kexfuzz$(EXEEXT)
tests interop-tests t-exec: regress-prep regress-binaries $(TARGETS)
tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS)
BUILDDIR=`pwd`; \
TEST_SSH_SCP="$${BUILDDIR}/scp"; \
TEST_SSH_SSH="$${BUILDDIR}/ssh"; \

View File

@ -2531,8 +2531,8 @@ if test "x$openssl" = "xyes" ; then
ssl_library_ver=`cat conftest.ssllibver`
# Check version is supported.
case "$ssl_library_ver" in
0090[[0-7]]*|009080[[0-5]]*)
AC_MSG_ERROR([OpenSSL >= 0.9.8f required (have "$ssl_library_ver")])
10000*|0*)
AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
;;
*) ;;
esac

7
krl.c
View File

@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $OpenBSD: krl.c,v 1.38 2016/09/12 01:22:38 deraadt Exp $ */
/* $OpenBSD: krl.c,v 1.39 2017/03/10 07:18:32 dtucker Exp $ */
#include "includes.h"
@ -1089,7 +1089,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
break;
case KRL_SECTION_SIGNATURE:
/* Handled above, but still need to stay in synch */
sshbuf_reset(sect);
sshbuf_free(sect);
sect = NULL;
if ((r = sshbuf_skip_string(copy)) != 0)
goto out;
@ -1288,7 +1288,8 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
debug2("%s: checking KRL %s", __func__, path);
r = ssh_krl_check_key(krl, key);
out:
close(fd);
if (fd != -1)
close(fd);
sshbuf_free(krlbuf);
ssh_krl_free(krl);
if (r != 0)

17
misc.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.107 2016/11/30 00:28:31 dtucker Exp $ */
/* $OpenBSD: misc.c,v 1.109 2017/03/14 00:55:37 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@ -310,7 +310,7 @@ a2tun(const char *s, int *remote)
long
convtime(const char *s)
{
long total, secs;
long total, secs, multiplier = 1;
const char *p;
char *endp;
@ -337,23 +337,28 @@ convtime(const char *s)
break;
case 'm':
case 'M':
secs *= MINUTES;
multiplier = MINUTES;
break;
case 'h':
case 'H':
secs *= HOURS;
multiplier = HOURS;
break;
case 'd':
case 'D':
secs *= DAYS;
multiplier = DAYS;
break;
case 'w':
case 'W':
secs *= WEEKS;
multiplier = WEEKS;
break;
default:
return -1;
}
if (secs >= LONG_MAX / multiplier)
return -1;
secs *= multiplier;
if (total >= LONG_MAX - secs)
return -1;
total += secs;
if (total < 0)
return -1;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: fmt_scaled.c,v 1.9 2007/03/20 03:42:52 tedu Exp $ */
/* $OpenBSD: fmt_scaled.c,v 1.13 2017/03/11 23:37:23 djm Exp $ */
/*
* Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved.
@ -69,7 +69,7 @@ static long long scale_factors[] = {
#define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */
/** Convert the given input string "scaled" into numeric in "result".
/* Convert the given input string "scaled" into numeric in "result".
* Return 0 on success, -1 and errno set on error.
*/
int
@ -81,7 +81,7 @@ scan_scaled(char *scaled, long long *result)
long long scale_fact = 1, whole = 0, fpart = 0;
/* Skip leading whitespace */
while (isascii(*p) && isspace(*p))
while (isascii((unsigned char)*p) && isspace((unsigned char)*p))
++p;
/* Then at most one leading + or - */
@ -108,7 +108,8 @@ scan_scaled(char *scaled, long long *result)
* (but note that E for Exa might look like e to some!).
* Advance 'p' to end, to get scale factor.
*/
for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) {
for (; isascii((unsigned char)*p) &&
(isdigit((unsigned char)*p) || *p=='.'); ++p) {
if (*p == '.') {
if (fract_digits > 0) { /* oops, more than one '.' */
errno = EINVAL;
@ -124,6 +125,10 @@ scan_scaled(char *scaled, long long *result)
/* ignore extra fractional digits */
continue;
fract_digits++; /* for later scaling */
if (fpart >= LLONG_MAX / 10) {
errno = ERANGE;
return -1;
}
fpart *= 10;
fpart += i;
} else { /* normal digit */
@ -131,6 +136,10 @@ scan_scaled(char *scaled, long long *result)
errno = ERANGE;
return -1;
}
if (whole >= LLONG_MAX / 10) {
errno = ERANGE;
return -1;
}
whole *= 10;
whole += i;
}
@ -150,17 +159,22 @@ scan_scaled(char *scaled, long long *result)
/* Validate scale factor, and scale whole and fraction by it. */
for (i = 0; i < SCALE_LENGTH; i++) {
/** Are we there yet? */
/* Are we there yet? */
if (*p == scale_chars[i] ||
*p == tolower(scale_chars[i])) {
*p == tolower((unsigned char)scale_chars[i])) {
/* If it ends with alphanumerics after the scale char, bad. */
if (isalnum(*(p+1))) {
if (isalnum((unsigned char)*(p+1))) {
errno = EINVAL;
return -1;
}
scale_fact = scale_factors[i];
if (whole >= LLONG_MAX / scale_fact) {
errno = ERANGE;
return -1;
}
/* scale whole part */
whole *= scale_fact;
@ -181,7 +195,9 @@ scan_scaled(char *scaled, long long *result)
return 0;
}
}
errno = ERANGE;
/* Invalid unit or character */
errno = EINVAL;
return -1;
}
@ -196,7 +212,7 @@ fmt_scaled(long long number, char *result)
unsigned int i;
unit_type unit = NONE;
abval = (number < 0LL) ? -number : number; /* no long long_abs yet */
abval = llabs(number);
/* Not every negative long long has a positive representation.
* Also check for numbers that are just too darned big to format

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.246 2017/02/28 06:10:08 djm Exp $ */
/* $OpenBSD: packet.c,v 1.247 2017/03/11 13:07:35 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1850,11 +1850,11 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
if (r != SSH_ERR_MAC_INVALID)
goto out;
logit("Corrupted MAC on input.");
if (need > PACKET_MAX_SIZE)
if (need + block_size > PACKET_MAX_SIZE)
return SSH_ERR_INTERNAL_ERROR;
return ssh_packet_start_discard(ssh, enc, mac,
sshbuf_len(state->incoming_packet),
PACKET_MAX_SIZE - need);
PACKET_MAX_SIZE - need - block_size);
}
/* Remove MAC from input buffer */
DBG(debug("MAC #%d ok", state->p_read.seqnr));

View File

@ -222,6 +222,7 @@ unit:
$$V ${.OBJDIR}/unittests/sshkey/test_sshkey \
-d ${.CURDIR}/unittests/sshkey/testdata ; \
$$V ${.OBJDIR}/unittests/bitmap/test_bitmap ; \
$$V ${.OBJDIR}/unittests/conversion/test_conversion ; \
$$V ${.OBJDIR}/unittests/kex/test_kex ; \
$$V ${.OBJDIR}/unittests/hostkeys/test_hostkeys \
-d ${.CURDIR}/unittests/hostkeys/testdata ; \

View File

@ -1,4 +1,4 @@
# $OpenBSD: cert-file.sh,v 1.4 2016/12/16 02:48:55 djm Exp $
# $OpenBSD: cert-file.sh,v 1.5 2017/03/11 23:44:16 djm Exp $
# Placed in the Public Domain.
tid="ssh with certificates"
@ -17,24 +17,59 @@ ${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"
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key3 || \
fatal "ssh-keygen failed"
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key4 || \
fatal "ssh-keygen failed"
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key5 || \
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"
fatal "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"
fatal "couldn't sign user_key1 with user_ca_key2"
mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_2.pub
${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \
-z $$ -n ${USER} $OBJ/user_key3 ||
fatal "couldn't sign user_key3 with user_ca_key1"
rm $OBJ/user_key3.pub # to test use of private key w/o public half.
${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \
-z $$ -n ${USER} $OBJ/user_key4 ||
fatal "couldn't sign user_key4 with user_ca_key1"
rm $OBJ/user_key4 $OBJ/user_key4.pub # to test no matching pub/private key case.
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
# Make a clean config that doesn't have any pre-added identities.
cat $OBJ/ssh_proxy | grep -v IdentityFile > $OBJ/no_identity_config
# XXX: verify that certificate used was what we expect. Needs exposure of
# keys via enviornment variable or similar.
for p in ${SSH_PROTOCOLS}; do
# Key with no .pub should work - finding the equivalent *-cert.pub.
verbose "protocol $p: identity cert with no plain public file"
${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \
-i $OBJ/user_key3 somehost exit 5$p
[ $? -ne 5$p ] && fail "ssh failed"
# CertificateFile matching private key with no .pub file should work.
verbose "protocol $p: CertificateFile with no plain public file"
${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \
-oCertificateFile=$OBJ/user_key3-cert.pub \
-i $OBJ/user_key3 somehost exit 5$p
[ $? -ne 5$p ] && fail "ssh failed"
# Just keys should fail
verbose "protocol $p: plain keys"
${SSH} $opts2 somehost exit 5$p
r=$?
if [ $r -eq 5$p ]; then
@ -42,6 +77,7 @@ for p in ${SSH_PROTOCOLS}; do
fi
# Keys with untrusted cert should fail.
verbose "protocol $p: untrusted cert"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
${SSH} $opts3 somehost exit 5$p
r=$?
@ -50,6 +86,7 @@ for p in ${SSH_PROTOCOLS}; do
fi
# Good cert with bad key should fail.
verbose "protocol $p: good cert, bad key"
opts3="$opts -i $OBJ/user_key2"
opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 5$p
@ -59,6 +96,7 @@ for p in ${SSH_PROTOCOLS}; do
fi
# Keys with one trusted cert, should succeed.
verbose "protocol $p: single trusted"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 5$p
r=$?
@ -67,6 +105,7 @@ for p in ${SSH_PROTOCOLS}; do
fi
# Multiple certs and keys, with one trusted cert, should succeed.
verbose "protocol $p: multiple trusted"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 5$p
@ -74,14 +113,6 @@ for p in ${SSH_PROTOCOLS}; do
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

View File

@ -1,5 +1,6 @@
# $OpenBSD: Makefile,v 1.7 2016/08/19 06:44:13 djm Exp $
REGRESS_FAIL_EARLY= yes
SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match
# $OpenBSD: Makefile,v 1.9 2017/03/14 01:20:29 dtucker Exp $
REGRESS_FAIL_EARLY?= yes
SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion
.include <bsd.subdir.mk>

View File

@ -0,0 +1,10 @@
# $OpenBSD: Makefile,v 1.1 2017/03/14 01:20:29 dtucker Exp $
PROG=test_conversion
SRCS=tests.c
REGRESS_TARGETS=run-regress-${PROG}
run-regress-${PROG}: ${PROG}
env ${TEST_ENV} ./${PROG}
.include <bsd.regress.mk>

View File

@ -0,0 +1,47 @@
/* $OpenBSD: tests.c,v 1.1 2017/03/14 01:20:29 dtucker Exp $ */
/*
* Regress test for conversions
*
* Placed in the public domain
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "../test_helper/test_helper.h"
#include "misc.h"
void
tests(void)
{
char buf[1024];
TEST_START("conversion_convtime");
ASSERT_LONG_EQ(convtime("0"), 0);
ASSERT_LONG_EQ(convtime("1"), 1);
ASSERT_LONG_EQ(convtime("1S"), 1);
/* from the examples in the comment above the function */
ASSERT_LONG_EQ(convtime("90m"), 5400);
ASSERT_LONG_EQ(convtime("1h30m"), 5400);
ASSERT_LONG_EQ(convtime("2d"), 172800);
ASSERT_LONG_EQ(convtime("1w"), 604800);
/* negative time is not allowed */
ASSERT_LONG_EQ(convtime("-7"), -1);
ASSERT_LONG_EQ(convtime("-9d"), -1);
/* overflow */
snprintf(buf, sizeof buf, "%llu", (unsigned long long)LONG_MAX + 1);
ASSERT_LONG_EQ(convtime(buf), -1);
/* overflow with multiplier */
snprintf(buf, sizeof buf, "%lluM", (unsigned long long)LONG_MAX/60 + 1);
ASSERT_LONG_EQ(convtime(buf), -1);
ASSERT_LONG_EQ(convtime("1000000000000000000000w"), -1);
TEST_DONE();
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: test_helper.c,v 1.6 2015/03/03 20:42:49 djm Exp $ */
/* $OpenBSD: test_helper.c,v 1.7 2017/03/14 01:10:07 dtucker Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@ -441,6 +441,17 @@ assert_u_int(const char *file, int line, const char *a1, const char *a2,
test_die();
}
void
assert_long(const char *file, int line, const char *a1, const char *a2,
long aa1, long aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "LONG", pred);
fprintf(stderr, "%12s = %ld / 0x%lx\n", a1, aa1, aa1);
fprintf(stderr, "%12s = %ld / 0x%lx\n", a2, aa2, aa2);
test_die();
}
void
assert_long_long(const char *file, int line, const char *a1, const char *a2,
long long aa1, long long aa2, enum test_predicate pred)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: test_helper.h,v 1.6 2015/01/18 19:52:44 djm Exp $ */
/* $OpenBSD: test_helper.h,v 1.7 2017/03/14 01:10:07 dtucker Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@ -67,6 +67,9 @@ void assert_size_t(const char *file, int line,
void assert_u_int(const char *file, int line,
const char *a1, const char *a2,
u_int aa1, u_int aa2, enum test_predicate pred);
void assert_long(const char *file, int line,
const char *a1, const char *a2,
long aa1, long aa2, enum test_predicate pred);
void assert_long_long(const char *file, int line,
const char *a1, const char *a2,
long long aa1, long long aa2, enum test_predicate pred);
@ -110,6 +113,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_U_INT_EQ(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_LONG_EQ(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_LONG_LONG_EQ(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_CHAR_EQ(a1, a2) \
@ -139,6 +144,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_U_INT_NE(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_LONG_NE(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_LONG_LONG_NE(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_CHAR_NE(a1, a2) \
@ -166,6 +173,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_U_INT_LT(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_LONG_LT(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_LONG_LONG_LT(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_CHAR_LT(a1, a2) \
@ -193,6 +202,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_U_INT_LE(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_LONG_LE(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_LONG_LONG_LE(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_CHAR_LE(a1, a2) \
@ -220,6 +231,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_U_INT_GT(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_LONG_GT(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_LONG_LONG_GT(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_CHAR_GT(a1, a2) \
@ -247,6 +260,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_U_INT_GE(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_LONG_GE(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_LONG_LONG_GE(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_CHAR_GE(a1, a2) \

View File

@ -73,19 +73,35 @@
# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP
#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
#if __BYTE_ORDER == __LITTLE_ENDIAN
# define ARG_LO_OFFSET 0
# define ARG_HI_OFFSET sizeof(uint32_t)
#elif __BYTE_ORDER == __BIG_ENDIAN
# define ARG_LO_OFFSET sizeof(uint32_t)
# define ARG_HI_OFFSET 0
#else
#error "Unknown endianness"
#endif
/* Simple helpers to avoid manual errors (but larger BPF programs). */
#define SC_DENY(_nr, _errno) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno))
#define SC_ALLOW(_nr) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
#define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 4), \
/* load first syscall argument */ \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 6), \
/* load and test first syscall argument, low word */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)])), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_arg_val), 0, 1), \
offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
((_arg_val) & 0xFFFFFFFF), 0, 3), \
/* load and test first syscall argument, high word */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
(((uint32_t)((uint64_t)(_arg_val) >> 32)) & 0xFFFFFFFF), 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \
/* reload syscall number; all rules expect it in accumulator */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
@ -104,108 +120,122 @@ static const struct sock_filter preauth_insns[] = {
/* Syscalls to non-fatally deny */
#ifdef __NR_lstat
SC_DENY(lstat, EACCES),
SC_DENY(__NR_lstat, EACCES),
#endif
#ifdef __NR_lstat64
SC_DENY(lstat64, EACCES),
SC_DENY(__NR_lstat64, EACCES),
#endif
#ifdef __NR_fstat
SC_DENY(fstat, EACCES),
SC_DENY(__NR_fstat, EACCES),
#endif
#ifdef __NR_fstat64
SC_DENY(fstat64, EACCES),
SC_DENY(__NR_fstat64, EACCES),
#endif
#ifdef __NR_open
SC_DENY(open, EACCES),
SC_DENY(__NR_open, EACCES),
#endif
#ifdef __NR_openat
SC_DENY(openat, EACCES),
SC_DENY(__NR_openat, EACCES),
#endif
#ifdef __NR_newfstatat
SC_DENY(newfstatat, EACCES),
SC_DENY(__NR_newfstatat, EACCES),
#endif
#ifdef __NR_stat
SC_DENY(stat, EACCES),
SC_DENY(__NR_stat, EACCES),
#endif
#ifdef __NR_stat64
SC_DENY(stat64, EACCES),
SC_DENY(__NR_stat64, EACCES),
#endif
/* Syscalls to permit */
#ifdef __NR_brk
SC_ALLOW(brk),
SC_ALLOW(__NR_brk),
#endif
#ifdef __NR_clock_gettime
SC_ALLOW(clock_gettime),
SC_ALLOW(__NR_clock_gettime),
#endif
#ifdef __NR_close
SC_ALLOW(close),
SC_ALLOW(__NR_close),
#endif
#ifdef __NR_exit
SC_ALLOW(exit),
SC_ALLOW(__NR_exit),
#endif
#ifdef __NR_exit_group
SC_ALLOW(exit_group),
SC_ALLOW(__NR_exit_group),
#endif
#ifdef __NR_getpgid
SC_ALLOW(getpgid),
SC_ALLOW(__NR_getpgid),
#endif
#ifdef __NR_getpid
SC_ALLOW(getpid),
SC_ALLOW(__NR_getpid),
#endif
#ifdef __NR_getrandom
SC_ALLOW(getrandom),
SC_ALLOW(__NR_getrandom),
#endif
#ifdef __NR_gettimeofday
SC_ALLOW(gettimeofday),
SC_ALLOW(__NR_gettimeofday),
#endif
#ifdef __NR_madvise
SC_ALLOW(madvise),
SC_ALLOW(__NR_madvise),
#endif
#ifdef __NR_mmap
SC_ALLOW(mmap),
SC_ALLOW(__NR_mmap),
#endif
#ifdef __NR_mmap2
SC_ALLOW(mmap2),
SC_ALLOW(__NR_mmap2),
#endif
#ifdef __NR_mremap
SC_ALLOW(mremap),
SC_ALLOW(__NR_mremap),
#endif
#ifdef __NR_munmap
SC_ALLOW(munmap),
SC_ALLOW(__NR_munmap),
#endif
#ifdef __NR__newselect
SC_ALLOW(_newselect),
SC_ALLOW(__NR__newselect),
#endif
#ifdef __NR_poll
SC_ALLOW(poll),
SC_ALLOW(__NR_poll),
#endif
#ifdef __NR_pselect6
SC_ALLOW(pselect6),
SC_ALLOW(__NR_pselect6),
#endif
#ifdef __NR_read
SC_ALLOW(read),
SC_ALLOW(__NR_read),
#endif
#ifdef __NR_rt_sigprocmask
SC_ALLOW(rt_sigprocmask),
SC_ALLOW(__NR_rt_sigprocmask),
#endif
#ifdef __NR_select
SC_ALLOW(select),
SC_ALLOW(__NR_select),
#endif
#ifdef __NR_shutdown
SC_ALLOW(shutdown),
SC_ALLOW(__NR_shutdown),
#endif
#ifdef __NR_sigprocmask
SC_ALLOW(sigprocmask),
SC_ALLOW(__NR_sigprocmask),
#endif
#ifdef __NR_time
SC_ALLOW(time),
SC_ALLOW(__NR_time),
#endif
#ifdef __NR_write
SC_ALLOW(write),
SC_ALLOW(__NR_write),
#endif
#ifdef __NR_socketcall
SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN),
SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN),
#endif
#if defined(__NR_ioctl) && defined(__s390__)
/* Allow ioctls for ICA crypto card on s390 */
SC_ALLOW_ARG(__NR_ioctl, 1, Z90STAT_STATUS_MASK),
SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO),
SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT),
#endif
#if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT)
/*
* On Linux x32, the clock_gettime VDSO falls back to the
* x86-64 syscall under some circumstances, e.g.
* https://bugs.debian.org/849923
*/
SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT);
#endif
/* Default deny */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect2.c,v 1.254 2017/02/03 02:56:00 dtucker Exp $ */
/* $OpenBSD: sshconnect2.c,v 1.255 2017/03/11 23:40:26 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@ -1001,11 +1001,11 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
}
static const char *
identity_sign_encode(struct identity *id)
key_sign_encode(const struct sshkey *key)
{
struct ssh *ssh = active_state;
if (id->key->type == KEY_RSA) {
if (key->type == KEY_RSA) {
switch (ssh->kex->rsa_sha2) {
case 256:
return "rsa-sha2-256";
@ -1013,7 +1013,7 @@ identity_sign_encode(struct identity *id)
return "rsa-sha2-512";
}
}
return key_ssh_name(id->key);
return key_ssh_name(key);
}
static int
@ -1022,30 +1022,49 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
{
Key *prv;
int ret;
const char *alg;
alg = identity_sign_encode(id);
/* the agent supports this key */
if (id->agent_fd != -1)
if (id->key != NULL && id->agent_fd != -1)
return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,
data, datalen, alg, compat);
data, datalen, key_sign_encode(id->key), compat);
/*
* we have already loaded the private key or
* the private key is stored in external hardware
*/
if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))
return (sshkey_sign(id->key, sigp, lenp, data, datalen, alg,
compat));
if (id->key != NULL &&
(id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)))
return (sshkey_sign(id->key, sigp, lenp, data, datalen,
key_sign_encode(id->key), compat));
/* load the private key from the file */
if ((prv = load_identity_file(id)) == NULL)
return SSH_ERR_KEY_NOT_FOUND;
ret = sshkey_sign(prv, sigp, lenp, data, datalen, alg, compat);
ret = sshkey_sign(prv, sigp, lenp, data, datalen,
key_sign_encode(prv), compat);
sshkey_free(prv);
return (ret);
}
static int
id_filename_matches(Identity *id, Identity *private_id)
{
const char *suffixes[] = { ".pub", "-cert.pub", NULL };
size_t len = strlen(id->filename), plen = strlen(private_id->filename);
size_t i, slen;
if (strcmp(id->filename, private_id->filename) == 0)
return 1;
for (i = 0; suffixes[i]; i++) {
slen = strlen(suffixes[i]);
if (len > slen && plen == len - slen &&
strcmp(id->filename + (len - slen), suffixes[i]) == 0 &&
memcmp(id->filename, private_id->filename, plen) == 0)
return 1;
}
return 0;
}
static int
sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
{
@ -1088,7 +1107,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
} else {
buffer_put_cstring(&b, authctxt->method->name);
buffer_put_char(&b, have_sig);
buffer_put_cstring(&b, identity_sign_encode(id));
buffer_put_cstring(&b, key_sign_encode(id->key));
}
buffer_put_string(&b, blob, bloblen);
@ -1108,6 +1127,24 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
break;
}
}
/*
* Exact key matches are preferred, but also allow
* filename matches for non-PKCS#11/agent keys that
* didn't load public keys. This supports the case
* of keeping just a private key file and public
* certificate on disk.
*/
if (!matched && !id->isprivate && id->agent_fd == -1 &&
(id->key->flags & SSHKEY_FLAG_EXT) == 0) {
TAILQ_FOREACH(private_id, &authctxt->keys, next) {
if (private_id->key == NULL &&
id_filename_matches(id, private_id)) {
id = private_id;
matched = 1;
break;
}
}
}
if (matched) {
debug2("%s: using private key \"%s\"%s for "
"certificate", __func__, id->filename,
@ -1186,7 +1223,7 @@ send_pubkey_test(Authctxt *authctxt, Identity *id)
packet_put_cstring(authctxt->method->name);
packet_put_char(have_sig);
if (!(datafellows & SSH_BUG_PKAUTH))
packet_put_cstring(identity_sign_encode(id));
packet_put_cstring(key_sign_encode(id->key));
packet_put_string(blob, bloblen);
free(blob);
packet_send();