diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2001-05-08 19:17:32 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2001-05-08 19:17:32 +0000 |
commit | 67259808c37c95cc1a910555aac915cdd08ff241 (patch) | |
tree | 5aa0455ef5a6291b29d3932ea43ad39e276ac682 | |
parent | a3e0598e6d2ed14810f2d1fc8b9ed360ee7be8ec (diff) |
adds correct error reporting to async connect()s
fixes the server-discards-data-before-connected-bug found by onoe@sm.sony.co.jp
-rw-r--r-- | usr.bin/ssh/channels.c | 80 | ||||
-rw-r--r-- | usr.bin/ssh/clientloop.c | 19 | ||||
-rw-r--r-- | usr.bin/ssh/serverloop.c | 19 |
3 files changed, 78 insertions, 40 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c index 23ebea5445a..3c6bdef9aa8 100644 --- a/usr.bin/ssh/channels.c +++ b/usr.bin/ssh/channels.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.113 2001/05/04 23:47:33 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.114 2001/05/08 19:17:30 markus Exp $"); #include <openssl/rsa.h> #include <openssl/dsa.h> @@ -842,22 +842,47 @@ channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) void channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset) { + int err = 0; + int sz = sizeof(err); + if (FD_ISSET(c->sock, writeset)) { - int err = 0; - int sz = sizeof(err); - c->type = SSH_CHANNEL_OPEN; - if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, (char *)&err, &sz) < 0) { - debug("getsockopt SO_ERROR failed"); + if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, (char *)&err, + &sz) < 0) { + err = errno; + error("getsockopt SO_ERROR failed"); + } + if (err == 0) { + debug("channel %d: connected", c->self); + c->type = SSH_CHANNEL_OPEN; + if (compat20) { + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + } else { + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + } } else { - if (err == 0) { - debug("channel %d: connected", c->self); + debug("channel %d: not connected: %s", + c->self, strerror(err)); + if (compat20) { + packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(c->remote_id); + packet_put_int(SSH2_OPEN_CONNECT_FAILED); + if (!(datafellows & SSH_BUG_OPENFAILURE)) { + packet_put_cstring(strerror(err)); + packet_put_cstring(""); + } } else { - debug("channel %d: not connected: %s", - c->self, strerror(err)); - chan_read_failed(c); - chan_write_failed(c); + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(c->remote_id); } + chan_mark_dead(c); } + packet_send(); } } @@ -1521,6 +1546,22 @@ channel_input_open_confirmation(int type, int plen, void *ctxt) } } +char * +reason2txt(int reason) +{ + switch(reason) { + case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED: + return "administratively prohibited"; + case SSH2_OPEN_CONNECT_FAILED: + return "connect failed"; + case SSH2_OPEN_UNKNOWN_CHANNEL_TYPE: + return "unknown channel type"; + case SSH2_OPEN_RESOURCE_SHORTAGE: + return "resource shortage"; + } + return "unkown reason"; +} + void channel_input_open_failure(int type, int plen, void *ctxt) { @@ -1544,8 +1585,8 @@ channel_input_open_failure(int type, int plen, void *ctxt) lang = packet_get_string(NULL); } packet_done(); - log("channel_open_failure: %d: reason %d %s", id, - reason, msg ? msg : "<no additional info>"); + log("channel %d: open failed: %s%s%s", id, + reason2txt(reason), msg ? ": ": "", msg ? msg : ""); if (msg != NULL) xfree(msg); if (lang != NULL) @@ -1671,7 +1712,7 @@ channel_still_open() case SSH_CHANNEL_CLOSED: case SSH_CHANNEL_AUTH_SOCKET: case SSH_CHANNEL_DYNAMIC: - case SSH_CHANNEL_CONNECTING: /* XXX ??? */ + case SSH_CHANNEL_CONNECTING: continue; case SSH_CHANNEL_LARVAL: if (!compat20) @@ -1713,10 +1754,10 @@ channel_find_open() case SSH_CHANNEL_PORT_LISTENER: case SSH_CHANNEL_RPORT_LISTENER: case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_CONNECTING: continue; case SSH_CHANNEL_LARVAL: case SSH_CHANNEL_AUTH_SOCKET: - case SSH_CHANNEL_CONNECTING: /* XXX ??? */ case SSH_CHANNEL_OPEN: case SSH_CHANNEL_X11_OPEN: return i; @@ -2162,13 +2203,8 @@ channel_input_port_open(int type, int plen, void *ctxt) if (c == NULL) { packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(remote_id); - } else { - /*XXX delay answer? */ - packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(remote_id); - packet_put_int(c->self); + packet_send(); } - packet_send(); xfree(host); } diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index 3294b0cfe4a..b2b7debc8f4 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.68 2001/05/06 21:45:14 markus Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.69 2001/05/08 19:17:31 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1150,20 +1150,21 @@ client_input_channel_open(int type, int plen, void *ctxt) c->remote_id = rchan; c->remote_window = rwindow; c->remote_maxpacket = rmaxpack; - - packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(c->remote_id); - packet_put_int(c->self); - packet_put_int(c->local_window); - packet_put_int(c->local_maxpacket); - packet_send(); + if (c->type != SSH_CHANNEL_CONNECTING) { + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } } else { debug("failure %s", ctype); packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(rchan); packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); if (!(datafellows & SSH_BUG_OPENFAILURE)) { - packet_put_cstring("bla bla"); + packet_put_cstring("open failed"); packet_put_cstring(""); } packet_send(); diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c index 128df0c494e..832f9a8e940 100644 --- a/usr.bin/ssh/serverloop.c +++ b/usr.bin/ssh/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.64 2001/05/04 23:47:34 markus Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.65 2001/05/08 19:17:31 markus Exp $"); #include "xmalloc.h" #include "packet.h" @@ -890,20 +890,21 @@ server_input_channel_open(int type, int plen, void *ctxt) c->remote_id = rchan; c->remote_window = rwindow; c->remote_maxpacket = rmaxpack; - - packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(c->remote_id); - packet_put_int(c->self); - packet_put_int(c->local_window); - packet_put_int(c->local_maxpacket); - packet_send(); + if (c->type != SSH_CHANNEL_CONNECTING) { + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } } else { debug("server_input_channel_open: failure %s", ctype); packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(rchan); packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); if (!(datafellows & SSH_BUG_OPENFAILURE)) { - packet_put_cstring("bla bla"); + packet_put_cstring("open failed"); packet_put_cstring(""); } packet_send(); |