View | Details | Raw Unified | Return to bug 1664 | Differences between
and this patch

Collapse All | Expand All

(-)a/channels.c (+14 lines)
Lines 184-189 channel_by_id(int id) Link Here
184
	return c;
184
	return c;
185
}
185
}
186
186
187
/* Iterate over channels
188
 * Use as: for (c = NULL; c = next_channel(c); ) ...
189
 */
190
Channel *
191
channel_next(Channel *current)
192
{
193
	int id = (current ? current->self + 1 : 0);
194
	for (; id < channels_alloc; id++) {
195
		Channel *c = channels[id];
196
		if (c) return c;
197
	}
198
	return NULL;
199
}
200
187
/*
201
/*
188
 * Returns the channel if it is allowed to receive protocol messages.
202
 * Returns the channel if it is allowed to receive protocol messages.
189
 * Private channels, like listening sockets, may not receive messages.
203
 * Private channels, like listening sockets, may not receive messages.
(-)a/channels.h (+1 lines)
Lines 186-191 struct Channel { Link Here
186
/* channel management */
186
/* channel management */
187
187
188
Channel	*channel_by_id(int);
188
Channel	*channel_by_id(int);
189
Channel *channel_next(Channel *);
189
Channel	*channel_lookup(int);
190
Channel	*channel_lookup(int);
190
Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int);
191
Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int);
191
void	 channel_set_fds(int, int, int, int, int, int, int, u_int);
192
void	 channel_set_fds(int, int, int, int, int, int, int, u_int);
(-)a/clientloop.h (-1 / +2 lines)
Lines 56-67 typedef void global_confirm_cb(int, u_int32_t seq, void *); Link Here
56
void	 client_register_global_confirm(global_confirm_cb *, void *);
56
void	 client_register_global_confirm(global_confirm_cb *, void *);
57
57
58
/* Multiplexing protocol version */
58
/* Multiplexing protocol version */
59
#define SSHMUX_VER			2
59
#define SSHMUX_VER			3
60
60
61
/* Multiplexing control protocol flags */
61
/* Multiplexing control protocol flags */
62
#define SSHMUX_COMMAND_OPEN		1	/* Open new connection */
62
#define SSHMUX_COMMAND_OPEN		1	/* Open new connection */
63
#define SSHMUX_COMMAND_ALIVE_CHECK	2	/* Check master is alive */
63
#define SSHMUX_COMMAND_ALIVE_CHECK	2	/* Check master is alive */
64
#define SSHMUX_COMMAND_TERMINATE	3	/* Ask master to exit */
64
#define SSHMUX_COMMAND_TERMINATE	3	/* Ask master to exit */
65
#define SSHMUX_COMMAND_PS               4       /* Get list of slaves */
65
66
66
#define SSHMUX_FLAG_TTY			(1)	/* Request tty on open */
67
#define SSHMUX_FLAG_TTY			(1)	/* Request tty on open */
67
#define SSHMUX_FLAG_SUBSYS		(1<<1)	/* Subsystem request on open */
68
#define SSHMUX_FLAG_SUBSYS		(1<<1)	/* Subsystem request on open */
(-)a/mux.c (-4 / +38 lines)
Lines 208-218 muxserver_accept_control(void) Link Here
208
{
208
{
209
	Buffer m;
209
	Buffer m;
210
	Channel *c;
210
	Channel *c;
211
	int client_fd, new_fd[3], ver, allowed, window, packetmax, ask;
211
	int client_fd, new_fd[3], ver, allowed, window, packetmax, ask, count;
212
	socklen_t addrlen;
212
	socklen_t addrlen;
213
	struct sockaddr_storage addr;
213
	struct sockaddr_storage addr;
214
	struct mux_session_confirm_ctx *cctx;
214
	struct mux_session_confirm_ctx *cctx;
215
	char *cmd;
215
	char *cmd, *tag;
216
	u_int i, j, len, env_len, mux_command, flags, escape_char;
216
	u_int i, j, len, env_len, mux_command, flags, escape_char;
217
	uid_t euid;
217
	uid_t euid;
218
	gid_t egid;
218
	gid_t egid;
Lines 293-298 muxserver_accept_control(void) Link Here
293
		if (allowed)
293
		if (allowed)
294
 			start_close = 1;
294
 			start_close = 1;
295
		break;
295
		break;
296
297
	case SSHMUX_COMMAND_PS:
298
		count = 0;
299
		c = NULL;
300
		while (c = channel_next(c))
301
			if (c->tag)
302
				count ++;
303
		buffer_put_int(&m, count);
304
		while (c = channel_next(c))
305
			if (c->tag)
306
				buffer_put_cstring(&m, c->tag);
307
		break;
296
	default:
308
	default:
297
		error("Unsupported command %d", mux_command);
309
		error("Unsupported command %d", mux_command);
298
		goto cleanup;
310
		goto cleanup;
Lines 335-340 muxserver_accept_control(void) Link Here
335
	cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
347
	cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
336
	cctx->term = buffer_get_string(&m, &len);
348
	cctx->term = buffer_get_string(&m, &len);
337
	escape_char = buffer_get_int(&m);
349
	escape_char = buffer_get_int(&m);
350
	tag = buffer_get_string(&m, &len);
338
351
339
	cmd = buffer_get_string(&m, &len);
352
	cmd = buffer_get_string(&m, &len);
340
	buffer_init(&cctx->cmd);
353
	buffer_init(&cctx->cmd);
Lines 369-374 muxserver_accept_control(void) Link Here
369
			buffer_free(&cctx->cmd);
382
			buffer_free(&cctx->cmd);
370
			close(client_fd);
383
			close(client_fd);
371
			xfree(cctx);
384
			xfree(cctx);
385
			xfree(tag);
372
			return 0;
386
			return 0;
373
		}
387
		}
374
	}
388
	}
Lines 395-400 muxserver_accept_control(void) Link Here
395
				xfree(cctx->env[i]);
409
				xfree(cctx->env[i]);
396
			xfree(cctx->env);
410
			xfree(cctx->env);
397
		}
411
		}
412
		xfree(cctx);
413
		xfree(tag);
398
		return 0;
414
		return 0;
399
	}
415
	}
400
	buffer_free(&m);
416
	buffer_free(&m);
Lines 421-426 muxserver_accept_control(void) Link Here
421
	    CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
437
	    CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
422
438
423
	c->ctl_fd = client_fd;
439
	c->ctl_fd = client_fd;
440
	c->tag = tag;
424
	if (cctx->want_tty && escape_char != 0xffffffff) {
441
	if (cctx->want_tty && escape_char != 0xffffffff) {
425
		channel_register_filter(c->self,
442
		channel_register_filter(c->self,
426
		    client_simple_escape_filter, NULL,
443
		    client_simple_escape_filter, NULL,
Lines 484-492 void Link Here
484
muxclient(const char *path, int ac, char **av)
501
muxclient(const char *path, int ac, char **av)
485
{
502
{
486
	struct sockaddr_un addr;
503
	struct sockaddr_un addr;
487
	int i, r, fd, sock, exitval[2], num_env;
504
	int i, r, fd, sock, exitval[2], num_env, count, len;
488
	Buffer m;
505
	Buffer m;
489
	char *term;
506
	char *term, *tag = NULL;
490
	extern char **environ;
507
	extern char **environ;
491
	u_int allowed, flags;
508
	u_int allowed, flags;
492
509
Lines 617-622 muxclient(const char *path, int ac, char **av) Link Here
617
	case SSHMUX_COMMAND_TERMINATE:
634
	case SSHMUX_COMMAND_TERMINATE:
618
		fprintf(stderr, "Exit request sent.\r\n");
635
		fprintf(stderr, "Exit request sent.\r\n");
619
		exit(0);
636
		exit(0);
637
	case SSHMUX_COMMAND_PS:
638
		if (buffer_get_int_ret(&count, &m) != 0) {
639
			error("%s: bad server reply", __func__);
640
			goto muxerr;
641
		}
642
		for (i = 0; i < count; i++) {
643
			tag = buffer_get_string(&m, &len);
644
			if (!tag) {
645
				error("%s: bad server reply", __func__);
646
				goto muxerr;
647
			}
648
			printf("%s\n", tag);
649
			xfree(tag);
650
		}
651
		exit(0);
620
	case SSHMUX_COMMAND_OPEN:
652
	case SSHMUX_COMMAND_OPEN:
621
		buffer_clear(&m);
653
		buffer_clear(&m);
622
		buffer_put_cstring(&m, term ? term : "");
654
		buffer_put_cstring(&m, term ? term : "");
Lines 624-629 muxclient(const char *path, int ac, char **av) Link Here
624
			buffer_put_int(&m, 0xffffffff);
656
			buffer_put_int(&m, 0xffffffff);
625
		else
657
		else
626
			buffer_put_int(&m, options.escape_char);
658
			buffer_put_int(&m, options.escape_char);
659
		xasprintf(&tag, "%ld", (long)getpid());
660
		buffer_put_cstring(&m, tag);
627
		buffer_append(&command, "\0", 1);
661
		buffer_append(&command, "\0", 1);
628
		buffer_put_cstring(&m, buffer_ptr(&command));
662
		buffer_put_cstring(&m, buffer_ptr(&command));
629
663
(-)a/ssh.c (+2 lines)
Lines 305-310 main(int ac, char **av) Link Here
305
				muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
305
				muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
306
			else if (strcmp(optarg, "exit") == 0)
306
			else if (strcmp(optarg, "exit") == 0)
307
				muxclient_command = SSHMUX_COMMAND_TERMINATE;
307
				muxclient_command = SSHMUX_COMMAND_TERMINATE;
308
			else if (strcmp(optarg, "ps") == 0)
309
				muxclient_command = SSHMUX_COMMAND_PS;
308
			else
310
			else
309
				fatal("Invalid multiplex command.");
311
				fatal("Invalid multiplex command.");
310
			break;
312
			break;

Return to bug 1664