1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Connection sharing: handle reply to cancel-tcpip-forward.

This is another bug that must have been around since connection
sharing was introduced, and nobody noticed until I did some unusually
thorough testing yesterday.

When a sharing downstream asks to set up a remote port forwarding, we
pass through the "tcpip-forward" global request, and we also intercept
the reply so that we know that the forwarding has been set up (and
hence that we should be passing "forwarded-tcpip" channel opens for
that port to this downstream). To do that, we set the want-reply flag
in the version of the packet we pass to the server, even if it was
clear in downstream's version; and we also put an item on a queue
local to sshshare.c which reminds us what to do about the reply when
it comes back.

But when the downstream _cancels_ one of those forwardings, I wrote
the code for all parts of that process except adding that queue item.
I even wrote the code to _consume_ the queue item, but somehow I
completely forgot to generate one in the first place! So the enum
value GLOBREQ_CANCEL_TCPIP_FORWARD was declared, tested for, but never
actually assigned to anything.
This commit is contained in:
Simon Tatham 2018-06-03 07:37:45 +01:00
parent 2b54c86e7e
commit 314c8f5270

View File

@ -1146,6 +1146,7 @@ void share_got_pkt_from_server(void *csv, int type,
case SSH2_MSG_REQUEST_SUCCESS:
case SSH2_MSG_REQUEST_FAILURE:
globreq = cs->globreq_head;
assert(globreq); /* should match the queue in ssh.c */
if (globreq->type == GLOBREQ_TCPIP_FORWARD) {
if (type == SSH2_MSG_REQUEST_FAILURE) {
share_remove_forwarding(cs, globreq->fwd);
@ -1402,6 +1403,20 @@ static void share_got_pkt_from_downstream(struct ssh_sharing_connstate *cs,
(cs->parent->ssh, cs->id, type, pkt, pktlen,
orig_wantreply ? NULL : "upstream added want_reply flag");
ssh_sharing_queue_global_request(cs->parent->ssh, cs);
/*
* And queue a globreq so that when the reply comes
* back we know to cancel it.
*/
globreq = snew(struct share_globreq);
globreq->next = NULL;
if (cs->globreq_tail)
cs->globreq_tail->next = globreq;
else
cs->globreq_head = globreq;
globreq->fwd = fwd;
globreq->want_reply = orig_wantreply;
globreq->type = GLOBREQ_CANCEL_TCPIP_FORWARD;
}
sfree(host);