From 4509b5d4a4fa645a022635bfa7e86d09b285001f Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 30 Jan 2015 01:13:33 +0000 Subject: [PATCH] upstream commit avoid more fatal/exit in the packet.c paths that ssh-keyscan uses; feedback and "looks good" markus@ --- dispatch.c | 8 +- opacket.c | 49 +++++++---- opacket.h | 9 +-- packet.c | 220 ++++++++++++++++++++++++++++++++------------------ packet.h | 12 +-- ssh-keyscan.c | 5 +- ssh_api.c | 5 +- ssherr.c | 6 +- ssherr.h | 4 +- 9 files changed, 204 insertions(+), 114 deletions(-) diff --git a/dispatch.c b/dispatch.c index 9ff5e3daf..900a2c10c 100644 --- a/dispatch.c +++ b/dispatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.c,v 1.24 2015/01/28 22:05:31 djm Exp $ */ +/* $OpenBSD: dispatch.c,v 1.25 2015/01/30 01:13:33 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -49,9 +49,9 @@ dispatch_protocol_error(int type, u_int32_t seq, void *ctx) fatal("protocol error"); if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || (r = sshpkt_put_u32(ssh, seq)) != 0 || - (r = sshpkt_send(ssh)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); - ssh_packet_write_wait(ssh); + (r = sshpkt_send(ssh)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + sshpkt_fatal(ssh, __func__, r); return 0; } diff --git a/opacket.c b/opacket.c index a137b5a8a..7618eae48 100644 --- a/opacket.c +++ b/opacket.c @@ -223,6 +223,8 @@ void packet_set_connection(int fd_in, int fd_out) { active_state = ssh_packet_set_connection(active_state, fd_in, fd_out); + if (active_state == NULL) + fatal("%s: ssh_packet_set_connection failed", __func__); } void @@ -255,20 +257,8 @@ packet_read_seqnr(u_int32_t *seqnr) u_char type; int r; - if ((r = ssh_packet_read_seqnr(active_state, &type, seqnr)) != 0) { - switch (r) { - case SSH_ERR_CONN_CLOSED: - logit("Connection closed by %.200s", - ssh_remote_ipaddr(active_state)); - cleanup_exit(255); - case SSH_ERR_CONN_TIMEOUT: - logit("Connection to %.200s timed out while " - "waiting to read", ssh_remote_ipaddr(active_state)); - cleanup_exit(255); - default: - fatal("%s: %s", __func__, ssh_err(r)); - } - } + if ((r = ssh_packet_read_seqnr(active_state, &type, seqnr)) != 0) + sshpkt_fatal(active_state, __func__, r); return type; } @@ -279,7 +269,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr) int r; if ((r = ssh_packet_read_poll_seqnr(active_state, &type, seqnr))) - fatal("%s: %s", __func__, ssh_err(r)); + sshpkt_fatal(active_state, __func__, r); return type; } @@ -296,5 +286,32 @@ packet_process_incoming(const char *buf, u_int len) int r; if ((r = ssh_packet_process_incoming(active_state, buf, len)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); + sshpkt_fatal(active_state, __func__, r); +} + +void +packet_write_wait(void) +{ + int r; + + if ((r = ssh_packet_write_wait(active_state)) != 0) + sshpkt_fatal(active_state, __func__, r); +} + +void +packet_write_poll(void) +{ + int r; + + if ((r = ssh_packet_write_poll(active_state)) != 0) + sshpkt_fatal(active_state, __func__, r); +} + +void +packet_read_expect(int expected_type) +{ + int r; + + if ((r = ssh_packet_read_expect(active_state, expected_type)) != 0) + sshpkt_fatal(active_state, __func__, r); } diff --git a/opacket.h b/opacket.h index 261ed1f81..e563d8d3b 100644 --- a/opacket.h +++ b/opacket.h @@ -45,6 +45,9 @@ void packet_set_connection(int, int); int packet_read_seqnr(u_int32_t *); int packet_read_poll_seqnr(u_int32_t *); void packet_process_incoming(const char *buf, u_int len); +void packet_write_wait(void); +void packet_write_poll(void); +void packet_read_expect(int expected_type); #define packet_set_timeout(timeout, count) \ ssh_packet_set_timeout(active_state, (timeout), (count)) #define packet_connection_is_on_socket() \ @@ -85,8 +88,6 @@ void packet_process_incoming(const char *buf, u_int len); ssh_packet_send(active_state) #define packet_read() \ ssh_packet_read(active_state) -#define packet_read_expect(expected_type) \ - ssh_packet_read_expect(active_state, (expected_type)) #define packet_get_int64() \ ssh_packet_get_int64(active_state) #define packet_get_bignum(value) \ @@ -105,10 +106,6 @@ void packet_process_incoming(const char *buf, u_int len); ssh_packet_send_debug(active_state, (fmt), ##args) #define packet_disconnect(fmt, args...) \ ssh_packet_disconnect(active_state, (fmt), ##args) -#define packet_write_poll() \ - ssh_packet_write_poll(active_state) -#define packet_write_wait() \ - ssh_packet_write_wait(active_state) #define packet_have_data_to_write() \ ssh_packet_have_data_to_write(active_state) #define packet_not_very_much_data_to_write() \ diff --git a/packet.c b/packet.c index eb178f149..f9ce08412 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.204 2015/01/28 21:15:47 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.205 2015/01/30 01:13:33 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -272,20 +272,26 @@ ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out) const struct sshcipher *none = cipher_by_name("none"); int r; - if (none == NULL) - fatal("%s: cannot load cipher 'none'", __func__); + if (none == NULL) { + error("%s: cannot load cipher 'none'", __func__); + return NULL; + } if (ssh == NULL) ssh = ssh_alloc_session_state(); - if (ssh == NULL) - fatal("%s: cound not allocate state", __func__); + if (ssh == NULL) { + error("%s: cound not allocate state", __func__); + return NULL; + } state = ssh->state; state->connection_in = fd_in; state->connection_out = fd_out; if ((r = cipher_init(&state->send_context, none, (const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 || (r = cipher_init(&state->receive_context, none, - (const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) - fatal("%s: cipher_init failed: %s", __func__, ssh_err(r)); + (const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) { + error("%s: cipher_init failed: %s", __func__, ssh_err(r)); + return NULL; + } state->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL; deattack_init(&state->deattack); return ssh; @@ -893,8 +899,8 @@ ssh_packet_send1(struct ssh *ssh) /* * Note that the packet is now only buffered in output. It won't be - * actually sent until packet_write_wait or packet_write_poll is - * called. + * actually sent until ssh_packet_write_wait or ssh_packet_write_poll + * is called. */ r = 0; out: @@ -1263,8 +1269,12 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) if (setp == NULL) return SSH_ERR_ALLOC_FAIL; - /* Since we are blocking, ensure that all written packets have been sent. */ - ssh_packet_write_wait(ssh); + /* + * Since we are blocking, ensure that all written packets have + * been sent. + */ + if ((r = ssh_packet_write_wait(ssh)) != 0) + return r; /* Stay in the loop until we have received a complete packet. */ for (;;) { @@ -1351,16 +1361,22 @@ ssh_packet_read(struct ssh *ssh) * that given, and gives a fatal error and exits if there is a mismatch. */ -void -ssh_packet_read_expect(struct ssh *ssh, int expected_type) +int +ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) { - int type; + int r; + u_char type; - type = ssh_packet_read(ssh); - if (type != expected_type) - ssh_packet_disconnect(ssh, + if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) + return r; + if (type != expected_type) { + if ((r = sshpkt_disconnect(ssh, "Protocol error: expected packet type %d, got %d", - expected_type, type); + expected_type, type)) != 0) + return r; + return SSH_ERR_PROTOCOL_ERROR; + } + return 0; } /* Checks if a full packet is available in the data received so far via @@ -1377,6 +1393,7 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) { struct session_state *state = ssh->state; u_int len, padded_len; + const char *emsg; const u_char *cp; u_char *p; u_int checksum, stored_checksum; @@ -1389,9 +1406,12 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) return 0; /* Get length of incoming packet. */ len = PEEK_U32(sshbuf_ptr(state->input)); - if (len < 1 + 2 + 2 || len > 256 * 1024) - ssh_packet_disconnect(ssh, "Bad packet length %u.", - len); + if (len < 1 + 2 + 2 || len > 256 * 1024) { + if ((r = sshpkt_disconnect(ssh, "Bad packet length %u", + len)) != 0) + return r; + return SSH_ERR_CONN_CORRUPT; + } padded_len = (len + 8) & ~7; /* Check if the packet has been entirely received. */ @@ -1410,19 +1430,27 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) * Ariel Futoransky(futo@core-sdi.com) */ if (!state->receive_context.plaintext) { + emsg = NULL; switch (detect_attack(&state->deattack, sshbuf_ptr(state->input), padded_len)) { case DEATTACK_OK: break; case DEATTACK_DETECTED: - ssh_packet_disconnect(ssh, - "crc32 compensation attack: network attack detected" - ); + emsg = "crc32 compensation attack detected"; + break; case DEATTACK_DOS_DETECTED: - ssh_packet_disconnect(ssh, - "deattack denial of service detected"); + emsg = "deattack denial of service detected"; + break; default: - ssh_packet_disconnect(ssh, "deattack error"); + emsg = "deattack error"; + break; + } + if (emsg != NULL) { + error("%s", emsg); + if ((r = sshpkt_disconnect(ssh, "%s", emsg)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_CONN_CORRUPT; } } @@ -1451,16 +1479,24 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) goto out; /* Test check bytes. */ - if (len != sshbuf_len(state->incoming_packet)) - ssh_packet_disconnect(ssh, - "packet_read_poll1: len %d != sshbuf_len %zd.", + if (len != sshbuf_len(state->incoming_packet)) { + error("%s: len %d != sshbuf_len %zd", __func__, len, sshbuf_len(state->incoming_packet)); + if ((r = sshpkt_disconnect(ssh, "invalid packet length")) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_CONN_CORRUPT; + } cp = sshbuf_ptr(state->incoming_packet) + len - 4; stored_checksum = PEEK_U32(cp); - if (checksum != stored_checksum) - ssh_packet_disconnect(ssh, - "Corrupted check bytes on input."); + if (checksum != stored_checksum) { + error("Corrupted check bytes on input"); + if ((r = sshpkt_disconnect(ssh, "connection corrupted")) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_CONN_CORRUPT; + } if ((r = sshbuf_consume_end(state->incoming_packet, 4)) < 0) goto out; @@ -1478,9 +1514,13 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) state->p_read.bytes += padded_len + 4; if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) goto out; - if (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) - ssh_packet_disconnect(ssh, - "Invalid ssh1 packet type: %d", *typep); + if (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) { + error("Invalid ssh1 packet type: %d", *typep); + if ((r = sshpkt_disconnect(ssh, "invalid packet type")) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_PROTOCOL_ERROR; + } r = 0; out: return r; @@ -1634,7 +1674,6 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0) goto out; } - /* XXX now it's safe to use fatal/packet_disconnect */ if (seqnr_p != NULL) *seqnr_p = state->p_read.seqnr; if (++state->p_read.seqnr == 0) @@ -1648,9 +1687,13 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) /* get padlen */ padlen = sshbuf_ptr(state->incoming_packet)[4]; DBG(debug("input: padlen %d", padlen)); - if (padlen < 4) - ssh_packet_disconnect(ssh, - "Corrupted padlen %d on input.", padlen); + if (padlen < 4) { + if ((r = sshpkt_disconnect(ssh, + "Corrupted padlen %d on input.", padlen)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_CONN_CORRUPT; + } /* skip packet size + padlen, discard padding */ if ((r = sshbuf_consume(state->incoming_packet, 4 + 1)) != 0 || @@ -1677,9 +1720,13 @@ 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 (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) - ssh_packet_disconnect(ssh, - "Invalid ssh2 packet type: %d", *typep); + if (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) { + if ((r = sshpkt_disconnect(ssh, + "Invalid ssh2 packet type: %d", *typep)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_PROTOCOL_ERROR; + } if (*typep == SSH2_MSG_NEWKEYS) r = ssh_set_newkeys(ssh, MODE_IN); else if (*typep == SSH2_MSG_USERAUTH_SUCCESS && !state->server_side) @@ -1816,9 +1863,8 @@ ssh_packet_remaining(struct ssh *ssh) * message is printed immediately, but only if the client is being executed * in verbose mode. These messages are primarily intended to ease debugging * authentication problems. The length of the formatted message must not - * exceed 1024 bytes. This will automatically call packet_write_wait. + * exceed 1024 bytes. This will automatically call ssh_packet_write_wait. */ - void ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...) { @@ -1846,7 +1892,29 @@ ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...) (r = sshpkt_send(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } - ssh_packet_write_wait(ssh); + if ((r = ssh_packet_write_wait(ssh)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +/* + * Pretty-print connection-terminating errors and exit. + */ +void +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)); + cleanup_exit(255); + case SSH_ERR_CONN_TIMEOUT: + logit("Connection to %.200s timed out while " + "waiting to write", ssh_remote_ipaddr(ssh)); + cleanup_exit(255); + default: + fatal("%s%sConnection to %.200s: %s", + tag != NULL ? tag : "", tag != NULL ? ": " : "", + ssh_remote_ipaddr(ssh), ssh_err(r)); + } } /* @@ -1855,7 +1923,6 @@ ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...) * should not contain a newline. The length of the formatted message must * not exceed 1024 bytes. */ - void ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...) { @@ -1879,30 +1946,26 @@ ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...) /* Display the error locally */ logit("Disconnecting: %.100s", buf); - /* Send the disconnect message to the other side, and wait for it to get sent. */ - if (compat20) { - if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || - (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || - (r = sshpkt_put_cstring(ssh, buf)) != 0 || - (r = sshpkt_put_cstring(ssh, "")) != 0 || - (r = sshpkt_send(ssh)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); - } else { - if ((r = sshpkt_start(ssh, SSH_MSG_DISCONNECT)) != 0 || - (r = sshpkt_put_cstring(ssh, buf)) != 0 || - (r = sshpkt_send(ssh)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); - } - ssh_packet_write_wait(ssh); + /* + * Send the disconnect message to the other side, and wait + * for it to get sent. + */ + if ((r = sshpkt_disconnect(ssh, "%s", buf)) != 0) + sshpkt_fatal(ssh, __func__, r); + + if ((r = ssh_packet_write_wait(ssh)) != 0) + sshpkt_fatal(ssh, __func__, r); /* Close the connection. */ ssh_packet_close(ssh); cleanup_exit(255); } -/* Checks if there is any buffered output, and tries to write some of the output. */ - -void +/* + * Checks if there is any buffered output, and tries to write some of + * the output. + */ +int ssh_packet_write_poll(struct ssh *ssh) { struct session_state *state = ssh->state; @@ -1916,33 +1979,33 @@ ssh_packet_write_poll(struct ssh *ssh) if (len == -1) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) - return; - fatal("Write failed: %.100s", strerror(errno)); + return 0; + return SSH_ERR_SYSTEM_ERROR; } if (len == 0 && !cont) - fatal("Write connection closed"); + return SSH_ERR_CONN_CLOSED; if ((r = sshbuf_consume(state->output, len)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); + return r; } + return 0; } /* * Calls packet_write_poll repeatedly until all pending output data has been * written. */ - -void +int ssh_packet_write_wait(struct ssh *ssh) { fd_set *setp; - int ret, ms_remain = 0; + int ret, r, ms_remain = 0; struct timeval start, timeout, *timeoutp = NULL; struct session_state *state = ssh->state; setp = (fd_set *)calloc(howmany(state->connection_out + 1, NFDBITS), sizeof(fd_mask)); if (setp == NULL) - fatal("%s: calloc failed", __func__); + return SSH_ERR_ALLOC_FAIL; ssh_packet_write_poll(ssh); while (ssh_packet_have_data_to_write(ssh)) { memset(setp, 0, howmany(state->connection_out + 1, @@ -1973,13 +2036,16 @@ ssh_packet_write_wait(struct ssh *ssh) } } if (ret == 0) { - logit("Connection to %.200s timed out while " - "waiting to write", ssh_remote_ipaddr(ssh)); - cleanup_exit(255); + free(setp); + return SSH_ERR_CONN_TIMEOUT; + } + if ((r = ssh_packet_write_poll(ssh)) != 0) { + free(setp); + return r; } - ssh_packet_write_poll(ssh); } free(setp); + return 0; } /* Returns true if there is buffered data to write to the connection. */ diff --git a/packet.h b/packet.h index 8a9d0f6c6..01df9f413 100644 --- a/packet.h +++ b/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.65 2015/01/28 21:15:47 djm Exp $ */ +/* $OpenBSD: packet.h,v 1.66 2015/01/30 01:13:33 djm Exp $ */ /* * Author: Tatu Ylonen @@ -90,7 +90,7 @@ int ssh_packet_send2_wrapped(struct ssh *); int ssh_packet_send2(struct ssh *); int ssh_packet_read(struct ssh *); -void ssh_packet_read_expect(struct ssh *, int type); +int ssh_packet_read_expect(struct ssh *, u_int type); int ssh_packet_read_poll(struct ssh *); int ssh_packet_read_poll1(struct ssh *, u_char *); int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); @@ -112,8 +112,8 @@ typedef void (ssh_packet_comp_free_func)(void *, void *); void ssh_packet_set_compress_hooks(struct ssh *, void *, ssh_packet_comp_alloc_func *, ssh_packet_comp_free_func *); -void ssh_packet_write_poll(struct ssh *); -void ssh_packet_write_wait(struct ssh *); +int ssh_packet_write_poll(struct ssh *); +int ssh_packet_write_wait(struct ssh *); int ssh_packet_have_data_to_write(struct ssh *); int ssh_packet_not_very_much_data_to_write(struct ssh *); @@ -148,8 +148,10 @@ void *ssh_packet_get_output(struct ssh *); /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); int sshpkt_send(struct ssh *ssh); -int sshpkt_disconnect(struct ssh *, const char *fmt, ...) __attribute__((format(printf, 2, 3))); +int sshpkt_disconnect(struct ssh *, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); int sshpkt_add_padding(struct ssh *, u_char); +void sshpkt_fatal(struct ssh *ssh, const char *tag, int r); int sshpkt_put(struct ssh *ssh, const void *v, size_t len); int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b); diff --git a/ssh-keyscan.c b/ssh-keyscan.c index e59eacace..989f7ecce 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.97 2015/01/28 21:15:47 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.98 2015/01/30 01:13:33 djm Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -466,7 +466,8 @@ congreet(int s) return; } *cp = '\0'; - c->c_ssh = ssh_packet_set_connection(NULL, s, s); + if ((c->c_ssh = ssh_packet_set_connection(NULL, s, s)) == NULL) + fatal("ssh_packet_set_connection failed"); ssh_set_app_data(c->c_ssh, c); /* back link */ if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) == 3) diff --git a/ssh_api.c b/ssh_api.c index 9794e0e57..7097c063c 100644 --- a/ssh_api.c +++ b/ssh_api.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh_api.c,v 1.2 2015/01/26 06:10:03 djm Exp $ */ +/* $OpenBSD: ssh_api.c,v 1.3 2015/01/30 01:13:33 djm Exp $ */ /* * Copyright (c) 2012 Markus Friedl. All rights reserved. * @@ -85,7 +85,8 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) called = 1; } - ssh = ssh_packet_set_connection(NULL, -1, -1); + if ((ssh = ssh_packet_set_connection(NULL, -1, -1)) == NULL) + return SSH_ERR_ALLOC_FAIL; if (is_server) ssh_packet_set_server(ssh); diff --git a/ssherr.c b/ssherr.c index 0b79fbb00..5c29c467c 100644 --- a/ssherr.c +++ b/ssherr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssherr.c,v 1.2 2015/01/28 21:15:47 djm Exp $ */ +/* $OpenBSD: ssherr.c,v 1.3 2015/01/30 01:13:33 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -129,6 +129,10 @@ ssh_err(int n) return "Connection closed"; case SSH_ERR_CONN_TIMEOUT: return "Connection timed out"; + case SSH_ERR_CONN_CORRUPT: + return "Connection corrupted"; + case SSH_ERR_PROTOCOL_ERROR: + return "Protocol error"; default: return "unknown error"; } diff --git a/ssherr.h b/ssherr.h index ac5cd159a..6f771b4b7 100644 --- a/ssherr.h +++ b/ssherr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssherr.h,v 1.2 2015/01/28 21:15:47 djm Exp $ */ +/* $OpenBSD: ssherr.h,v 1.3 2015/01/30 01:13:33 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -75,6 +75,8 @@ #define SSH_ERR_KEY_REVOKED -51 #define SSH_ERR_CONN_CLOSED -52 #define SSH_ERR_CONN_TIMEOUT -53 +#define SSH_ERR_CONN_CORRUPT -54 +#define SSH_ERR_PROTOCOL_ERROR -55 /* Translate a numeric error code to a human-readable error string */ const char *ssh_err(int n);