version 1.233, 2011/05/06 21:34:32 |
version 1.234, 2011/05/08 12:52:01 |
|
|
}; |
}; |
|
|
/* Context for channel confirmation replies */ |
/* Context for channel confirmation replies */ |
|
enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY }; |
struct channel_reply_ctx { |
struct channel_reply_ctx { |
const char *request_type; |
const char *request_type; |
int id, do_close; |
int id; |
|
enum confirm_action action; |
}; |
}; |
|
|
/* Global request success/failure callbacks */ |
/* Global request success/failure callbacks */ |
|
|
char errmsg[256]; |
char errmsg[256]; |
int tochan; |
int tochan; |
|
|
|
/* |
|
* If a TTY was explicitly requested, then a failure to allocate |
|
* one is fatal. |
|
*/ |
|
if (cr->action == CONFIRM_TTY && |
|
(options.request_tty == REQUEST_TTY_FORCE || |
|
options.request_tty == REQUEST_TTY_YES)) |
|
cr->action = CONFIRM_CLOSE; |
|
|
/* XXX supress on mux _client_ quietmode */ |
/* XXX supress on mux _client_ quietmode */ |
tochan = options.log_level >= SYSLOG_LEVEL_ERROR && |
tochan = options.log_level >= SYSLOG_LEVEL_ERROR && |
c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; |
c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; |
|
|
cr->request_type, c->self); |
cr->request_type, c->self); |
} |
} |
/* If error occurred on primary session channel, then exit */ |
/* If error occurred on primary session channel, then exit */ |
if (cr->do_close && c->self == session_ident) |
if (cr->action == CONFIRM_CLOSE && c->self == session_ident) |
fatal("%s", errmsg); |
fatal("%s", errmsg); |
/* If error occurred on mux client, append to their stderr */ |
/* |
if (tochan) |
* If error occurred on mux client, append to |
buffer_append(&c->extended, errmsg, strlen(errmsg)); |
* their stderr. |
else |
*/ |
|
if (tochan) { |
|
buffer_append(&c->extended, errmsg, |
|
strlen(errmsg)); |
|
} else |
error("%s", errmsg); |
error("%s", errmsg); |
if (cr->do_close) { |
if (cr->action == CONFIRM_TTY) { |
|
/* |
|
* If a TTY allocation error occurred, then arrange |
|
* for the correct TTY to leave raw mode. |
|
*/ |
|
if (c->self == session_ident) |
|
leave_raw_mode(0); |
|
else |
|
mux_tty_alloc_failed(c); |
|
} else if (cr->action == CONFIRM_CLOSE) { |
chan_read_failed(c); |
chan_read_failed(c); |
chan_write_failed(c); |
chan_write_failed(c); |
} |
} |
|
|
} |
} |
|
|
static void |
static void |
client_expect_confirm(int id, const char *request, int do_close) |
client_expect_confirm(int id, const char *request, |
|
enum confirm_action action) |
{ |
{ |
struct channel_reply_ctx *cr = xmalloc(sizeof(*cr)); |
struct channel_reply_ctx *cr = xmalloc(sizeof(*cr)); |
|
|
cr->request_type = request; |
cr->request_type = request; |
cr->do_close = do_close; |
cr->action = action; |
|
|
channel_register_status_confirm(id, client_status_confirm, |
channel_register_status_confirm(id, client_status_confirm, |
client_abandon_status_confirm, cr); |
client_abandon_status_confirm, cr); |
|
|
memset(&ws, 0, sizeof(ws)); |
memset(&ws, 0, sizeof(ws)); |
|
|
channel_request_start(id, "pty-req", 1); |
channel_request_start(id, "pty-req", 1); |
client_expect_confirm(id, "PTY allocation", 1); |
client_expect_confirm(id, "PTY allocation", CONFIRM_TTY); |
packet_put_cstring(term != NULL ? term : ""); |
packet_put_cstring(term != NULL ? term : ""); |
packet_put_int((u_int)ws.ws_col); |
packet_put_int((u_int)ws.ws_col); |
packet_put_int((u_int)ws.ws_row); |
packet_put_int((u_int)ws.ws_row); |
|
|
debug("Sending subsystem: %.*s", |
debug("Sending subsystem: %.*s", |
len, (u_char*)buffer_ptr(cmd)); |
len, (u_char*)buffer_ptr(cmd)); |
channel_request_start(id, "subsystem", 1); |
channel_request_start(id, "subsystem", 1); |
client_expect_confirm(id, "subsystem", 1); |
client_expect_confirm(id, "subsystem", CONFIRM_CLOSE); |
} else { |
} else { |
debug("Sending command: %.*s", |
debug("Sending command: %.*s", |
len, (u_char*)buffer_ptr(cmd)); |
len, (u_char*)buffer_ptr(cmd)); |
channel_request_start(id, "exec", 1); |
channel_request_start(id, "exec", 1); |
client_expect_confirm(id, "exec", 1); |
client_expect_confirm(id, "exec", CONFIRM_CLOSE); |
} |
} |
packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); |
packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); |
packet_send(); |
packet_send(); |
} else { |
} else { |
channel_request_start(id, "shell", 1); |
channel_request_start(id, "shell", 1); |
client_expect_confirm(id, "shell", 1); |
client_expect_confirm(id, "shell", CONFIRM_CLOSE); |
packet_send(); |
packet_send(); |
} |
} |
} |
} |