diff options
author | djm@openbsd.org <djm@openbsd.org> | 2015-01-28 21:15:47 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2015-01-29 09:08:07 +1100 |
commit | fae7bbe544cba7a9e5e4ab47ff6faa3d978646eb (patch) | |
tree | a27a07031b600a1925a128bc0f5258a4b3ab2e8c | |
parent | 1a3d14f6b44a494037c7deab485abe6496bf2c60 (diff) |
upstream commit
avoid fatal() calls in packet code makes ssh-keyscan more
reliable against server failures ok dtucker@ markus@
-rw-r--r-- | opacket.c | 25 | ||||
-rw-r--r-- | opacket.h | 3 | ||||
-rw-r--r-- | packet.c | 33 | ||||
-rw-r--r-- | packet.h | 4 | ||||
-rw-r--r-- | ssh-keyscan.c | 8 | ||||
-rw-r--r-- | ssherr.c | 6 | ||||
-rw-r--r-- | ssherr.h | 4 |
7 files changed, 54 insertions, 29 deletions
@@ -255,8 +255,20 @@ packet_read_seqnr(u_int32_t *seqnr) | |||
255 | u_char type; | 255 | u_char type; |
256 | int r; | 256 | int r; |
257 | 257 | ||
258 | if ((r = ssh_packet_read_seqnr(active_state, &type, seqnr))) | 258 | if ((r = ssh_packet_read_seqnr(active_state, &type, seqnr)) != 0) { |
259 | fatal("%s: %s", __func__, ssh_err(r)); | 259 | switch (r) { |
260 | case SSH_ERR_CONN_CLOSED: | ||
261 | logit("Connection closed by %.200s", | ||
262 | ssh_remote_ipaddr(active_state)); | ||
263 | cleanup_exit(255); | ||
264 | case SSH_ERR_CONN_TIMEOUT: | ||
265 | logit("Connection to %.200s timed out while " | ||
266 | "waiting to read", ssh_remote_ipaddr(active_state)); | ||
267 | cleanup_exit(255); | ||
268 | default: | ||
269 | fatal("%s: %s", __func__, ssh_err(r)); | ||
270 | } | ||
271 | } | ||
260 | return type; | 272 | return type; |
261 | } | 273 | } |
262 | 274 | ||
@@ -277,3 +289,12 @@ packet_close(void) | |||
277 | ssh_packet_close(active_state); | 289 | ssh_packet_close(active_state); |
278 | active_state = NULL; | 290 | active_state = NULL; |
279 | } | 291 | } |
292 | |||
293 | void | ||
294 | packet_process_incoming(const char *buf, u_int len) | ||
295 | { | ||
296 | int r; | ||
297 | |||
298 | if ((r = ssh_packet_process_incoming(active_state, buf, len)) != 0) | ||
299 | fatal("%s: %s", __func__, ssh_err(r)); | ||
300 | } | ||
@@ -44,6 +44,7 @@ void packet_restore_state(void); | |||
44 | void packet_set_connection(int, int); | 44 | void packet_set_connection(int, int); |
45 | int packet_read_seqnr(u_int32_t *); | 45 | int packet_read_seqnr(u_int32_t *); |
46 | int packet_read_poll_seqnr(u_int32_t *); | 46 | int packet_read_poll_seqnr(u_int32_t *); |
47 | void packet_process_incoming(const char *buf, u_int len); | ||
47 | #define packet_set_timeout(timeout, count) \ | 48 | #define packet_set_timeout(timeout, count) \ |
48 | ssh_packet_set_timeout(active_state, (timeout), (count)) | 49 | ssh_packet_set_timeout(active_state, (timeout), (count)) |
49 | #define packet_connection_is_on_socket() \ | 50 | #define packet_connection_is_on_socket() \ |
@@ -86,8 +87,6 @@ int packet_read_poll_seqnr(u_int32_t *); | |||
86 | ssh_packet_read(active_state) | 87 | ssh_packet_read(active_state) |
87 | #define packet_read_expect(expected_type) \ | 88 | #define packet_read_expect(expected_type) \ |
88 | ssh_packet_read_expect(active_state, (expected_type)) | 89 | ssh_packet_read_expect(active_state, (expected_type)) |
89 | #define packet_process_incoming(buf, len) \ | ||
90 | ssh_packet_process_incoming(active_state, (buf), (len)) | ||
91 | #define packet_get_int64() \ | 90 | #define packet_get_int64() \ |
92 | ssh_packet_get_int64(active_state) | 91 | ssh_packet_get_int64(active_state) |
93 | #define packet_get_bignum(value) \ | 92 | #define packet_get_bignum(value) \ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.203 2015/01/20 23:14:00 deraadt Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.204 2015/01/28 21:15:47 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1314,26 +1314,22 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1314 | break; | 1314 | break; |
1315 | } | 1315 | } |
1316 | } | 1316 | } |
1317 | if (r == 0) { | 1317 | if (r == 0) |
1318 | logit("Connection to %.200s timed out while " | 1318 | return SSH_ERR_CONN_TIMEOUT; |
1319 | "waiting to read", ssh_remote_ipaddr(ssh)); | ||
1320 | cleanup_exit(255); | ||
1321 | } | ||
1322 | /* Read data from the socket. */ | 1319 | /* Read data from the socket. */ |
1323 | do { | 1320 | do { |
1324 | cont = 0; | 1321 | cont = 0; |
1325 | len = roaming_read(state->connection_in, buf, | 1322 | len = roaming_read(state->connection_in, buf, |
1326 | sizeof(buf), &cont); | 1323 | sizeof(buf), &cont); |
1327 | } while (len == 0 && cont); | 1324 | } while (len == 0 && cont); |
1328 | if (len == 0) { | 1325 | if (len == 0) |
1329 | logit("Connection closed by %.200s", | 1326 | return SSH_ERR_CONN_CLOSED; |
1330 | ssh_remote_ipaddr(ssh)); | ||
1331 | cleanup_exit(255); | ||
1332 | } | ||
1333 | if (len < 0) | 1327 | if (len < 0) |
1334 | fatal("Read from socket failed: %.100s", strerror(errno)); | 1328 | return SSH_ERR_SYSTEM_ERROR; |
1329 | |||
1335 | /* Append it to the buffer. */ | 1330 | /* Append it to the buffer. */ |
1336 | ssh_packet_process_incoming(ssh, buf, len); | 1331 | if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0) |
1332 | return r; | ||
1337 | } | 1333 | } |
1338 | free(setp); | 1334 | free(setp); |
1339 | return r; | 1335 | return r; |
@@ -1787,7 +1783,7 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1787 | * together with packet_read_poll. | 1783 | * together with packet_read_poll. |
1788 | */ | 1784 | */ |
1789 | 1785 | ||
1790 | void | 1786 | int |
1791 | ssh_packet_process_incoming(struct ssh *ssh, const char *buf, u_int len) | 1787 | ssh_packet_process_incoming(struct ssh *ssh, const char *buf, u_int len) |
1792 | { | 1788 | { |
1793 | struct session_state *state = ssh->state; | 1789 | struct session_state *state = ssh->state; |
@@ -1797,14 +1793,15 @@ ssh_packet_process_incoming(struct ssh *ssh, const char *buf, u_int len) | |||
1797 | state->keep_alive_timeouts = 0; /* ?? */ | 1793 | state->keep_alive_timeouts = 0; /* ?? */ |
1798 | if (len >= state->packet_discard) { | 1794 | if (len >= state->packet_discard) { |
1799 | if ((r = ssh_packet_stop_discard(ssh)) != 0) | 1795 | if ((r = ssh_packet_stop_discard(ssh)) != 0) |
1800 | fatal("%s: %s", __func__, ssh_err(r)); | 1796 | return r; |
1801 | cleanup_exit(255); | ||
1802 | } | 1797 | } |
1803 | state->packet_discard -= len; | 1798 | state->packet_discard -= len; |
1804 | return; | 1799 | return 0; |
1805 | } | 1800 | } |
1806 | if ((r = sshbuf_put(ssh->state->input, buf, len)) != 0) | 1801 | if ((r = sshbuf_put(ssh->state->input, buf, len)) != 0) |
1807 | fatal("%s: %s", __func__, ssh_err(r)); | 1802 | return r; |
1803 | |||
1804 | return 0; | ||
1808 | } | 1805 | } |
1809 | 1806 | ||
1810 | int | 1807 | int |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.h,v 1.64 2015/01/19 20:30:23 markus Exp $ */ | 1 | /* $OpenBSD: packet.h,v 1.65 2015/01/28 21:15:47 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -94,7 +94,7 @@ void ssh_packet_read_expect(struct ssh *, int type); | |||
94 | int ssh_packet_read_poll(struct ssh *); | 94 | int ssh_packet_read_poll(struct ssh *); |
95 | int ssh_packet_read_poll1(struct ssh *, u_char *); | 95 | int ssh_packet_read_poll1(struct ssh *, u_char *); |
96 | int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); | 96 | int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); |
97 | void ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); | 97 | int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); |
98 | int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); | 98 | int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); |
99 | int ssh_packet_read_poll_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); | 99 | int ssh_packet_read_poll_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); |
100 | 100 | ||
diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 25a257cc2..e59eacace 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keyscan.c,v 1.96 2015/01/20 23:14:00 deraadt Exp $ */ | 1 | /* $OpenBSD: ssh-keyscan.c,v 1.97 2015/01/28 21:15:47 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. | 3 | * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. |
4 | * | 4 | * |
@@ -319,8 +319,10 @@ tcpconnect(char *host) | |||
319 | memset(&hints, 0, sizeof(hints)); | 319 | memset(&hints, 0, sizeof(hints)); |
320 | hints.ai_family = IPv4or6; | 320 | hints.ai_family = IPv4or6; |
321 | hints.ai_socktype = SOCK_STREAM; | 321 | hints.ai_socktype = SOCK_STREAM; |
322 | if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) | 322 | if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { |
323 | fatal("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr)); | 323 | error("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr)); |
324 | return -1; | ||
325 | } | ||
324 | for (ai = aitop; ai; ai = ai->ai_next) { | 326 | for (ai = aitop; ai; ai = ai->ai_next) { |
325 | s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | 327 | s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
326 | if (s < 0) { | 328 | if (s < 0) { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssherr.c,v 1.1 2014/04/30 05:29:56 djm Exp $ */ | 1 | /* $OpenBSD: ssherr.c,v 1.2 2015/01/28 21:15:47 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Damien Miller | 3 | * Copyright (c) 2011 Damien Miller |
4 | * | 4 | * |
@@ -125,6 +125,10 @@ ssh_err(int n) | |||
125 | return "KRL file has invalid magic number"; | 125 | return "KRL file has invalid magic number"; |
126 | case SSH_ERR_KEY_REVOKED: | 126 | case SSH_ERR_KEY_REVOKED: |
127 | return "Key is revoked"; | 127 | return "Key is revoked"; |
128 | case SSH_ERR_CONN_CLOSED: | ||
129 | return "Connection closed"; | ||
130 | case SSH_ERR_CONN_TIMEOUT: | ||
131 | return "Connection timed out"; | ||
128 | default: | 132 | default: |
129 | return "unknown error"; | 133 | return "unknown error"; |
130 | } | 134 | } |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssherr.h,v 1.1 2014/04/30 05:29:56 djm Exp $ */ | 1 | /* $OpenBSD: ssherr.h,v 1.2 2015/01/28 21:15:47 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Damien Miller | 3 | * Copyright (c) 2011 Damien Miller |
4 | * | 4 | * |
@@ -73,6 +73,8 @@ | |||
73 | #define SSH_ERR_BUFFER_READ_ONLY -49 | 73 | #define SSH_ERR_BUFFER_READ_ONLY -49 |
74 | #define SSH_ERR_KRL_BAD_MAGIC -50 | 74 | #define SSH_ERR_KRL_BAD_MAGIC -50 |
75 | #define SSH_ERR_KEY_REVOKED -51 | 75 | #define SSH_ERR_KEY_REVOKED -51 |
76 | #define SSH_ERR_CONN_CLOSED -52 | ||
77 | #define SSH_ERR_CONN_TIMEOUT -53 | ||
76 | 78 | ||
77 | /* Translate a numeric error code to a human-readable error string */ | 79 | /* Translate a numeric error code to a human-readable error string */ |
78 | const char *ssh_err(int n); | 80 | const char *ssh_err(int n); |