[PATCH/RFC 3/6] generate unique ids for forwardings to be used for identification

Bert Wesarg bert.wesarg at googlemail.com
Thu May 3 21:33:49 EST 2012


---
 mux.c      |   21 +++++++++++----------
 readconf.c |    6 +++++-
 readconf.h |    3 ++-
 ssh.c      |   23 ++++++++++++++++++++---
 4 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/mux.c b/mux.c
index d57c1de..337ef54 100644
--- a/mux.c
+++ b/mux.c
@@ -113,7 +113,7 @@ struct mux_session_confirm_ctx {
 struct mux_channel_confirm_ctx {
 	u_int cid;	/* channel id */
 	u_int rid;	/* request id */
-	int fid;	/* forward id */
+	u_int fid;	/* forward id */
 };
 
 /* fd to control socket */
@@ -574,9 +574,10 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
 {
 	struct mux_channel_confirm_ctx *fctx = ctxt;
 	char *failmsg = NULL;
-	Forward *rfwd;
+	Forward *rfwd = NULL;
 	Channel *c;
 	Buffer out;
+	int i;
 
 	if ((c = channel_by_id(fctx->cid)) == NULL) {
 		/* no channel for reply */
@@ -584,13 +585,14 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
 		return;
 	}
 	buffer_init(&out);
-	if (fctx->fid >= options.num_forwards) {
-		xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid);
-		goto fail;
+	for (i = 0; i < options.num_forwards; i++) {
+		if (options.forwards[i].id == fctx->fid) {
+			rfwd = &options.forwards[i];
+			break;
+		}
 	}
-	rfwd = &options.forwards[fctx->fid];
-	if (rfwd->type != SSH_FWD_REMOTE) {
-		xasprintf(&failmsg, "non-remote forwarding id %d", fctx->fid);
+	if (rfwd == NULL || rfwd->type != MUX_FWD_REMOTE) {
+		xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid);
 		goto fail;
 	}
 	debug("%s: %s for: listen %d, connect %s:%d", __func__,
@@ -742,11 +744,10 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 		    fwd.listen_port, fwd.connect_host, fwd.connect_port);
 		if (fwd.handle < 0)
 			goto fail;
-		add_forward(&options, &fwd);
 		fctx = xcalloc(1, sizeof(*fctx));
 		fctx->cid = c->self;
 		fctx->rid = rid;
-		fctx->fid = options.num_forwards - 1;
+		fctx->fid = add_forward(&options, &fwd);
 		client_register_global_confirm(mux_confirm_remote_forward,
 		    fctx);
 		freefwd = 0;
diff --git a/readconf.c b/readconf.c
index d0687af..a89b07a 100644
--- a/readconf.c
+++ b/readconf.c
@@ -255,9 +255,10 @@ static struct {
  * error.
  */
 
-void
+u_int
 add_forward(Options *options, const Forward *newfwd)
 {
+	static u_int fid_sequence;
 	Forward *fwd;
 #ifndef NO_IPPORT_RESERVED_CONCEPT
 	if (newfwd->type != SSH_FWD_REMOTE) {
@@ -271,6 +272,7 @@ add_forward(Options *options, const Forward *newfwd)
 	    sizeof(*options->forwards));
 	fwd = &options->forwards[options->num_forwards++];
 
+	fwd->id = fid_sequence++;
 	fwd->type = newfwd->type;
 	fwd->listen_host = newfwd->listen_host;
 	fwd->listen_port = newfwd->listen_port;
@@ -280,6 +282,8 @@ add_forward(Options *options, const Forward *newfwd)
 		fwd->handle = newfwd->handle;
 		fwd->allocated_port = 0;
 	}
+
+	return fwd->id;
 }
 
 static void
diff --git a/readconf.h b/readconf.h
index c4ce149..d44946b 100644
--- a/readconf.h
+++ b/readconf.h
@@ -24,6 +24,7 @@
 #define SSH_FWD_DYNAMIC 3
 
 typedef struct {
+	u_int	  id;			/* sequential id of this forward */
 	u_int	  type;			/* Type of forwarding [1, 2, 3] */
 	char	 *listen_host;		/* Host (address) to listen on. */
 	int	  listen_port;		/* Port to forward. */
@@ -158,6 +159,6 @@ int
 process_config_line(Options *, const char *, char *, const char *, int, int *);
 
 int	 parse_forward(Forward *, const char *, u_int);
-void	 add_forward(Options *, const Forward *);
+u_int	 add_forward(Options *, const Forward *);
 
 #endif				/* READCONF_H */
diff --git a/ssh.c b/ssh.c
index c29f522..999fc6a 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1018,8 +1018,23 @@ fork_postauth(void)
 static void
 ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
 {
-	Forward *rfwd = (Forward *)ctxt;
+	u_int fid = *(u_int *)ctxt;
+	Forward *rfwd = NULL;
+	int i;
+
+	xfree(ctxt);
+
 	remote_forward_confirms_pending--;
+	for (i = 0; i < options.num_forwards; i++) {
+		if (options.forwards[i].id == fid) {
+			rfwd = &options.forwards[i];
+			break;
+		}
+	}
+	if (rfwd == NULL) {
+		debug("remote forwarding not found: %u", fid);
+		return;
+	}
 
 	/* XXX verbose() on failure? */
 	debug("remote forward %s for: listen %d, connect %s:%d",
@@ -1141,8 +1156,10 @@ ssh_init_forwarding(void)
 				    "forwarding.");
 		} else {
 			remote_forward_confirms_pending++;
+			u_int *idcp = xmalloc(sizeof(*idcp));
+			*idcp = options.forwards[i].id;
 			client_register_global_confirm(ssh_confirm_remote_forward,
-			    &options.forwards[i]);
+			    idcp);
 		}
 	}
 
@@ -1155,7 +1172,7 @@ ssh_init_forwarding(void)
 			else
 				error("Could not request tunnel forwarding.");
 		}
-	}			
+	}
 }
 
 static void
-- 
1.7.9.rc0.542.g07ca1



More information about the openssh-unix-dev mailing list