version 1.16, 2010/04/23 22:27:38 |
version 1.17, 2010/05/14 23:29:23 |
|
|
char *term; |
char *term; |
struct termios tio; |
struct termios tio; |
char **env; |
char **env; |
|
u_int rid; |
}; |
}; |
|
|
/* fd to control socket */ |
/* fd to control socket */ |
|
|
#define MUX_FWD_REMOTE 2 |
#define MUX_FWD_REMOTE 2 |
#define MUX_FWD_DYNAMIC 3 |
#define MUX_FWD_DYNAMIC 3 |
|
|
static void mux_session_confirm(int, void *); |
static void mux_session_confirm(int, int, void *); |
|
|
static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); |
static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); |
static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); |
static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); |
|
|
/* Reply for SSHMUX_COMMAND_OPEN */ |
/* Reply for SSHMUX_COMMAND_OPEN */ |
cctx = xcalloc(1, sizeof(*cctx)); |
cctx = xcalloc(1, sizeof(*cctx)); |
cctx->term = NULL; |
cctx->term = NULL; |
|
cctx->rid = rid; |
cmd = reserved = NULL; |
cmd = reserved = NULL; |
if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || |
if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || |
buffer_get_int_ret(&cctx->want_tty, m) != 0 || |
buffer_get_int_ret(&cctx->want_tty, m) != 0 || |
|
|
|
|
channel_send_open(nc->self); |
channel_send_open(nc->self); |
channel_register_open_confirm(nc->self, mux_session_confirm, cctx); |
channel_register_open_confirm(nc->self, mux_session_confirm, cctx); |
|
c->mux_pause = 1; /* stop handling messages until open_confirm done */ |
channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); |
channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); |
|
|
/* prepare reply */ |
/* reply is deferred, sent by mux_session_confirm */ |
/* XXX defer until mux_session_confirm() fires */ |
|
buffer_put_int(r, MUX_S_SESSION_OPENED); |
|
buffer_put_int(r, rid); |
|
buffer_put_int(r, nc->self); |
|
|
|
return 0; |
return 0; |
} |
} |
|
|
|
|
|
|
/* Callback on open confirmation in mux master for a mux client session. */ |
/* Callback on open confirmation in mux master for a mux client session. */ |
static void |
static void |
mux_session_confirm(int id, void *arg) |
mux_session_confirm(int id, int success, void *arg) |
{ |
{ |
struct mux_session_confirm_ctx *cctx = arg; |
struct mux_session_confirm_ctx *cctx = arg; |
const char *display; |
const char *display; |
Channel *c; |
Channel *c, *cc; |
int i; |
int i; |
|
Buffer reply; |
|
|
if (cctx == NULL) |
if (cctx == NULL) |
fatal("%s: cctx == NULL", __func__); |
fatal("%s: cctx == NULL", __func__); |
if ((c = channel_by_id(id)) == NULL) |
if ((c = channel_by_id(id)) == NULL) |
fatal("%s: no channel for id %d", __func__, id); |
fatal("%s: no channel for id %d", __func__, id); |
|
if ((cc = channel_by_id(c->ctl_chan)) == NULL) |
|
fatal("%s: channel %d lacks control channel %d", __func__, |
|
id, c->ctl_chan); |
|
|
|
if (!success) { |
|
debug3("%s: sending failure reply", __func__); |
|
/* prepare reply */ |
|
buffer_init(&reply); |
|
buffer_put_int(&reply, MUX_S_FAILURE); |
|
buffer_put_int(&reply, cctx->rid); |
|
buffer_put_cstring(&reply, "Session open refused by peer"); |
|
goto done; |
|
} |
|
|
display = getenv("DISPLAY"); |
display = getenv("DISPLAY"); |
if (cctx->want_x_fwd && options.forward_x11 && display != NULL) { |
if (cctx->want_x_fwd && options.forward_x11 && display != NULL) { |
char *proto, *data; |
char *proto, *data; |
|
|
client_session2_setup(id, cctx->want_tty, cctx->want_subsys, |
client_session2_setup(id, cctx->want_tty, cctx->want_subsys, |
cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); |
cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); |
|
|
|
debug3("%s: sending success reply", __func__); |
|
/* prepare reply */ |
|
buffer_init(&reply); |
|
buffer_put_int(&reply, MUX_S_SESSION_OPENED); |
|
buffer_put_int(&reply, cctx->rid); |
|
buffer_put_int(&reply, c->self); |
|
|
|
done: |
|
/* Send reply */ |
|
buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); |
|
buffer_free(&reply); |
|
|
|
if (cc->mux_pause <= 0) |
|
fatal("%s: mux_pause %d", __func__, cc->mux_pause); |
|
cc->mux_pause = 0; /* start processing messages again */ |
c->open_confirm_ctx = NULL; |
c->open_confirm_ctx = NULL; |
buffer_free(&cctx->cmd); |
buffer_free(&cctx->cmd); |
xfree(cctx->term); |
xfree(cctx->term); |