summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2015-01-28 21:15:47 +0000
committerDamien Miller <djm@mindrot.org>2015-01-29 09:08:07 +1100
commitfae7bbe544cba7a9e5e4ab47ff6faa3d978646eb (patch)
treea27a07031b600a1925a128bc0f5258a4b3ab2e8c
parent1a3d14f6b44a494037c7deab485abe6496bf2c60 (diff)
upstream commit
avoid fatal() calls in packet code makes ssh-keyscan more reliable against server failures ok dtucker@ markus@
-rw-r--r--opacket.c25
-rw-r--r--opacket.h3
-rw-r--r--packet.c33
-rw-r--r--packet.h4
-rw-r--r--ssh-keyscan.c8
-rw-r--r--ssherr.c6
-rw-r--r--ssherr.h4
7 files changed, 54 insertions, 29 deletions
diff --git a/opacket.c b/opacket.c
index 63b419d5c..a137b5a8a 100644
--- a/opacket.c
+++ b/opacket.c
@@ -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
293void
294packet_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}
diff --git a/opacket.h b/opacket.h
index 1e15626eb..261ed1f81 100644
--- a/opacket.h
+++ b/opacket.h
@@ -44,6 +44,7 @@ void packet_restore_state(void);
44void packet_set_connection(int, int); 44void packet_set_connection(int, int);
45int packet_read_seqnr(u_int32_t *); 45int packet_read_seqnr(u_int32_t *);
46int packet_read_poll_seqnr(u_int32_t *); 46int packet_read_poll_seqnr(u_int32_t *);
47void 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) \
diff --git a/packet.c b/packet.c
index 2c8d8aa9b..eb178f149 100644
--- a/packet.c
+++ b/packet.c
@@ -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
1790void 1786int
1791ssh_packet_process_incoming(struct ssh *ssh, const char *buf, u_int len) 1787ssh_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
1810int 1807int
diff --git a/packet.h b/packet.h
index 069af2eae..8a9d0f6c6 100644
--- a/packet.h
+++ b/packet.h
@@ -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);
94int ssh_packet_read_poll(struct ssh *); 94int ssh_packet_read_poll(struct ssh *);
95int ssh_packet_read_poll1(struct ssh *, u_char *); 95int ssh_packet_read_poll1(struct ssh *, u_char *);
96int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); 96int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p);
97void ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); 97int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len);
98int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); 98int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p);
99int ssh_packet_read_poll_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); 99int 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) {
diff --git a/ssherr.c b/ssherr.c
index 49fbb71de..0b79fbb00 100644
--- a/ssherr.c
+++ b/ssherr.c
@@ -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 }
diff --git a/ssherr.h b/ssherr.h
index 106f786ea..ac5cd159a 100644
--- a/ssherr.h
+++ b/ssherr.h
@@ -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 */
78const char *ssh_err(int n); 80const char *ssh_err(int n);