summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cli-runopts.c1
-rw-r--r--cli-session.c4
-rw-r--r--cli-tcpfwd.c38
-rw-r--r--tcpfwd.h4
4 files changed, 46 insertions, 1 deletions
diff --git a/cli-runopts.c b/cli-runopts.c
index be449a3..13d6b45 100644
--- a/cli-runopts.c
+++ b/cli-runopts.c
@@ -609,6 +609,7 @@ static void addforward(const char* origstr, struct TCPFwdList** fwdlist) {
goto badport;
}
+ newfwd->have_reply = 0;
newfwd->next = *fwdlist;
*fwdlist = newfwd;
diff --git a/cli-session.c b/cli-session.c
index d0a7361..c153f4f 100644
--- a/cli-session.c
+++ b/cli-session.c
@@ -64,6 +64,10 @@ static const packettype cli_packettypes[] = {
{SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure},
{SSH_MSG_USERAUTH_BANNER, recv_msg_userauth_banner}, /* client */
{SSH_MSG_USERAUTH_SPECIFIC_60, recv_msg_userauth_specific_60}, /* client */
+#ifdef ENABLE_CLI_REMOTETCPFWD
+ {SSH_MSG_REQUEST_SUCCESS, cli_recv_msg_request_success}, /* client */
+ {SSH_MSG_REQUEST_FAILURE, cli_recv_msg_request_failure}, /* client */
+#endif
{0, 0} /* End */
};
diff --git a/cli-tcpfwd.c b/cli-tcpfwd.c
index c3bfd4d..0e60090 100644
--- a/cli-tcpfwd.c
+++ b/cli-tcpfwd.c
@@ -128,7 +128,7 @@ static void send_msg_global_request_remotetcp(int port) {
CHECKCLEARTOWRITE();
buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
buf_putstring(ses.writepayload, "tcpip-forward", 13);
- buf_putbyte(ses.writepayload, 0);
+ buf_putbyte(ses.writepayload, 1); /* want_reply */
if (opts.listen_fwd_all) {
listenspec = "";
} else {
@@ -143,6 +143,42 @@ static void send_msg_global_request_remotetcp(int port) {
TRACE(("leave send_msg_global_request_remotetcp"))
}
+/* The only global success/failure messages are for remotetcp.
+ * Since there isn't any identifier in these messages, we have to rely on them
+ * being in the same order as we sent the requests. This is the ordering
+ * of the cli_opts.remotefwds list */
+void cli_recv_msg_request_success() {
+
+ /* Nothing in the packet. We just mark off that we have received the reply,
+ * so that we can report failure for later ones. */
+ struct TCPFwdList * iter = NULL;
+
+ iter = cli_opts.remotefwds;
+ while (iter != NULL) {
+ if (!iter->have_reply)
+ {
+ iter->have_reply = 1;
+ return;
+ }
+ iter = iter->next;
+ }
+}
+
+void cli_recv_msg_request_failure() {
+ struct TCPFwdList * iter = NULL;
+
+ iter = cli_opts.remotefwds;
+ while (iter != NULL) {
+ if (!iter->have_reply)
+ {
+ iter->have_reply = 1;
+ dropbear_log(LOG_WARNING, "Remote TCP forward request failed (port %d -> %s:%d)", iter->listenport, iter->connectaddr, iter->connectport);
+ return;
+ }
+ iter = iter->next;
+ }
+}
+
void setup_remotetcp() {
struct TCPFwdList * iter = NULL;
diff --git a/tcpfwd.h b/tcpfwd.h
index f50515c..251612e 100644
--- a/tcpfwd.h
+++ b/tcpfwd.h
@@ -49,6 +49,8 @@ struct TCPFwdList {
const unsigned char* connectaddr;
unsigned int connectport;
unsigned int listenport;
+ unsigned int have_reply; /* is set to 1 after a reply has been received
+ when setting up the forwarding */
struct TCPFwdList * next;
};
@@ -62,6 +64,8 @@ extern const struct ChanType svr_chan_tcpdirect;
void setup_localtcp();
void setup_remotetcp();
extern const struct ChanType cli_chan_tcpremote;
+void cli_recv_msg_request_success();
+void cli_recv_msg_request_failure();
/* Common */
int listen_tcpfwd(struct TCPListener* tcpinfo);