[openssh-commits] [openssh] 05/06: upstream commit
git+noreply at mindrot.org
git+noreply at mindrot.org
Thu Oct 13 18:55:43 AEDT 2016
This is an automated email from the git hooks/post-receive script.
djm pushed a commit to branch master
in repository openssh.
commit 1723ec92eb485ce06b4cbf49712d21975d873909
Author: djm at openbsd.org <djm at openbsd.org>
Date: Tue Oct 11 21:49:54 2016 +0000
upstream commit
fix the KEX fuzzer - the previous method of obtaining the
packet contents was broken. This now uses the new per-packet input hook, so
it sees exact post-decrypt packets and doesn't have to pass packet integrity
checks. ok markus@
Upstream-Regress-ID: 402fb6ffabd97de590e8e57b25788949dce8d2fd
---
regress/misc/kexfuzz/kexfuzz.c | 162 ++++++++++++++++++++++++++---------------
1 file changed, 103 insertions(+), 59 deletions(-)
diff --git a/regress/misc/kexfuzz/kexfuzz.c b/regress/misc/kexfuzz/kexfuzz.c
index 8535980..6705802 100644
--- a/regress/misc/kexfuzz/kexfuzz.c
+++ b/regress/misc/kexfuzz/kexfuzz.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexfuzz.c,v 1.2 2016/09/16 01:01:41 djm Exp $ */
+/* $OpenBSD: kexfuzz.c,v 1.3 2016/10/11 21:49:54 djm Exp $ */
/*
* Fuzz harness for KEX code
*
@@ -27,6 +27,7 @@
#include "packet.h"
#include "myproposal.h"
#include "authfile.h"
+#include "log.h"
struct ssh *active_state = NULL; /* XXX - needed for linking */
@@ -35,61 +36,93 @@ static int do_debug = 0;
enum direction { S2C, C2S };
+struct hook_ctx {
+ struct ssh *client, *server, *server2;
+ int *c2s, *s2c;
+ int trigger_direction, packet_index;
+ const char *dump_path;
+ struct sshbuf *replace_data;
+};
+
static int
-do_send_and_receive(struct ssh *from, struct ssh *to, int mydirection,
- int *packet_count, int trigger_direction, int packet_index,
- const char *dump_path, struct sshbuf *replace_data)
+packet_hook(struct ssh *ssh, struct sshbuf *packet, u_char *typep, void *_ctx)
+{
+ struct hook_ctx *ctx = (struct hook_ctx *)_ctx;
+ int mydirection = ssh == ctx->client ? S2C : C2S;
+ int *packet_count = mydirection == S2C ? ctx->s2c : ctx->c2s;
+ FILE *dumpfile;
+ int r;
+
+ if (do_debug) {
+ printf("%s packet %d type %u:\n",
+ mydirection == S2C ? "s2c" : "c2s",
+ *packet_count, *typep);
+ sshbuf_dump(packet, stdout);
+ }
+ if (mydirection == ctx->trigger_direction &&
+ ctx->packet_index == *packet_count) {
+ if (ctx->replace_data != NULL) {
+ sshbuf_reset(packet);
+ /* Type is first byte of packet */
+ if ((r = sshbuf_get_u8(ctx->replace_data,
+ typep)) != 0 ||
+ (r = sshbuf_putb(packet, ctx->replace_data)) != 0)
+ return r;
+ if (do_debug) {
+ printf("***** replaced packet type %u\n",
+ *typep);
+ sshbuf_dump(packet, stdout);
+ }
+ } else if (ctx->dump_path != NULL) {
+ if ((dumpfile = fopen(ctx->dump_path, "w+")) == NULL)
+ err(1, "fopen %s", ctx->dump_path);
+ /* Write { type, packet } */
+ if (fwrite(typep, 1, 1, dumpfile) != 1)
+ err(1, "fwrite type %s", ctx->dump_path);
+ if (sshbuf_len(packet) != 0 &&
+ fwrite(sshbuf_ptr(packet), sshbuf_len(packet),
+ 1, dumpfile) != 1)
+ err(1, "fwrite body %s", ctx->dump_path);
+ if (do_debug) {
+ printf("***** dumped packet type %u len %zu\n",
+ *typep, sshbuf_len(packet));
+ }
+ fclose(dumpfile);
+ /* No point in continuing */
+ exit(0);
+ }
+ }
+ (*packet_count)++;
+ return 0;
+}
+
+static int
+do_send_and_receive(struct ssh *from, struct ssh *to)
{
u_char type;
- size_t len, olen;
+ size_t len;
const u_char *buf;
int r;
- FILE *dumpfile;
for (;;) {
if ((r = ssh_packet_next(from, &type)) != 0) {
fprintf(stderr, "ssh_packet_next: %s\n", ssh_err(r));
return r;
}
+
if (type != 0)
return 0;
buf = ssh_output_ptr(from, &len);
- olen = len;
- if (do_debug) {
- printf("%s packet %d type %u len %zu:\n",
- mydirection == S2C ? "s2c" : "c2s",
- *packet_count, type, len);
- sshbuf_dump_data(buf, len, stdout);
- }
- if (mydirection == trigger_direction &&
- packet_index == *packet_count) {
- if (replace_data != NULL) {
- buf = sshbuf_ptr(replace_data);
- len = sshbuf_len(replace_data);
- if (do_debug) {
- printf("***** replaced packet "
- "len %zu\n", len);
- sshbuf_dump_data(buf, len, stdout);
- }
- } else if (dump_path != NULL) {
- if ((dumpfile = fopen(dump_path, "w+")) == NULL)
- err(1, "fopen %s", dump_path);
- if (len != 0 &&
- fwrite(buf, len, 1, dumpfile) != 1)
- err(1, "fwrite %s", dump_path);
- if (do_debug)
- printf("***** dumped packet "
- "len %zu\n", len);
- fclose(dumpfile);
- exit(0);
- }
- }
- (*packet_count)++;
if (len == 0)
return 0;
- if ((r = ssh_input_append(to, buf, len)) != 0 ||
- (r = ssh_output_consume(from, olen)) != 0)
+ if ((r = ssh_input_append(to, buf, len)) != 0) {
+ debug("ssh_input_append: %s", ssh_err(r));
return r;
+ }
+ if ((r = ssh_output_consume(from, len)) != 0) {
+ debug("ssh_output_consume: %s", ssh_err(r));
+ return r;
+ }
}
}
@@ -141,19 +174,19 @@ const char *in_test = NULL;
static void
-run_kex(struct ssh *client, struct ssh *server, int *s2c, int *c2s,
- int direction, int packet_index,
- const char *dump_path, struct sshbuf *replace_data)
+run_kex(struct ssh *client, struct ssh *server)
{
int r = 0;
while (!server->kex->done || !client->kex->done) {
- if ((r = do_send_and_receive(server, client, S2C, s2c,
- direction, packet_index, dump_path, replace_data)))
+ if ((r = do_send_and_receive(server, client)) != 0) {
+ debug("do_send_and_receive S2C: %s", ssh_err(r));
break;
- if ((r = do_send_and_receive(client, server, C2S, c2s,
- direction, packet_index, dump_path, replace_data)))
+ }
+ if ((r = do_send_and_receive(client, server)) != 0) {
+ debug("do_send_and_receive C2S: %s", ssh_err(r));
break;
+ }
}
if (do_debug)
printf("done: %s\n", ssh_err(r));
@@ -173,6 +206,7 @@ do_kex_with_key(const char *kex, struct sshkey *prvkey, int *c2s, int *s2c,
struct kex_params kex_params;
char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
char *keyname = NULL;
+ struct hook_ctx hook_ctx;
TEST_START("sshkey_from_private");
ASSERT_INT_EQ(sshkey_from_private(prvkey, &pubkey), 0);
@@ -187,30 +221,42 @@ do_kex_with_key(const char *kex, struct sshkey *prvkey, int *c2s, int *s2c,
kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname;
ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0);
ASSERT_INT_EQ(ssh_init(&server, 1, &kex_params), 0);
+ ASSERT_INT_EQ(ssh_init(&server2, 1, NULL), 0);
ASSERT_PTR_NE(client, NULL);
ASSERT_PTR_NE(server, NULL);
+ ASSERT_PTR_NE(server2, NULL);
TEST_DONE();
+ hook_ctx.c2s = c2s;
+ hook_ctx.s2c = s2c;
+ hook_ctx.trigger_direction = direction;
+ hook_ctx.packet_index = packet_index;
+ hook_ctx.dump_path = dump_path;
+ hook_ctx.replace_data = replace_data;
+ hook_ctx.client = client;
+ hook_ctx.server = server;
+ hook_ctx.server2 = server2;
+ ssh_packet_set_input_hook(client, packet_hook, &hook_ctx);
+ ssh_packet_set_input_hook(server, packet_hook, &hook_ctx);
+ ssh_packet_set_input_hook(server2, packet_hook, &hook_ctx);
+
TEST_START("ssh_add_hostkey");
ASSERT_INT_EQ(ssh_add_hostkey(server, prvkey), 0);
ASSERT_INT_EQ(ssh_add_hostkey(client, pubkey), 0);
TEST_DONE();
TEST_START("kex");
- run_kex(client, server, s2c, c2s, direction, packet_index,
- dump_path, replace_data);
+ run_kex(client, server);
TEST_DONE();
TEST_START("rekeying client");
ASSERT_INT_EQ(kex_send_kexinit(client), 0);
- run_kex(client, server, s2c, c2s, direction, packet_index,
- dump_path, replace_data);
+ run_kex(client, server);
TEST_DONE();
TEST_START("rekeying server");
ASSERT_INT_EQ(kex_send_kexinit(server), 0);
- run_kex(client, server, s2c, c2s, direction, packet_index,
- dump_path, replace_data);
+ run_kex(client, server);
TEST_DONE();
TEST_START("ssh_packet_get_state");
@@ -221,9 +267,6 @@ do_kex_with_key(const char *kex, struct sshkey *prvkey, int *c2s, int *s2c,
TEST_DONE();
TEST_START("ssh_packet_set_state");
- server2 = NULL;
- ASSERT_INT_EQ(ssh_init(&server2, 1, NULL), 0);
- ASSERT_PTR_NE(server2, NULL);
ASSERT_INT_EQ(ssh_add_hostkey(server2, prvkey), 0);
kex_free(server2->kex); /* XXX or should ssh_packet_set_state()? */
ASSERT_INT_EQ(ssh_packet_set_state(server2, state), 0);
@@ -251,11 +294,9 @@ do_kex_with_key(const char *kex, struct sshkey *prvkey, int *c2s, int *s2c,
TEST_START("rekeying server2");
ASSERT_INT_EQ(kex_send_kexinit(server2), 0);
- run_kex(client, server2, s2c, c2s, direction, packet_index,
- dump_path, replace_data);
+ run_kex(client, server2);
ASSERT_INT_EQ(kex_send_kexinit(client), 0);
- run_kex(client, server2, s2c, c2s, direction, packet_index,
- dump_path, replace_data);
+ run_kex(client, server2);
TEST_DONE();
TEST_START("cleanup");
@@ -357,6 +398,9 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
+ log_init(argv[0], do_debug ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO,
+ SYSLOG_FACILITY_USER, 1);
+
/* Must select a single mode */
if ((count_flag + dump_flag + replace_flag) != 1)
badusage("Must select one mode: -c, -d or -r");
--
To stop receiving notification emails like this one, please contact
djm at mindrot.org.
More information about the openssh-commits
mailing list