summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2001-05-08 19:17:32 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2001-05-08 19:17:32 +0000
commit67259808c37c95cc1a910555aac915cdd08ff241 (patch)
tree5aa0455ef5a6291b29d3932ea43ad39e276ac682
parenta3e0598e6d2ed14810f2d1fc8b9ed360ee7be8ec (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.c80
-rw-r--r--usr.bin/ssh/clientloop.c19
-rw-r--r--usr.bin/ssh/serverloop.c19
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();