version 1.338, 2014/12/11 08:20:09 |
version 1.339, 2015/01/19 20:07:45 |
|
|
/* -- protocol input */ |
/* -- protocol input */ |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_data(int type, u_int32_t seq, void *ctxt) |
channel_input_data(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
int id; |
int id; |
|
|
/* Ignore any data for non-open channels (might happen on close) */ |
/* Ignore any data for non-open channels (might happen on close) */ |
if (c->type != SSH_CHANNEL_OPEN && |
if (c->type != SSH_CHANNEL_OPEN && |
c->type != SSH_CHANNEL_X11_OPEN) |
c->type != SSH_CHANNEL_X11_OPEN) |
return; |
return 0; |
|
|
/* Get the data. */ |
/* Get the data. */ |
data = packet_get_string_ptr(&data_len); |
data = packet_get_string_ptr(&data_len); |
|
|
c->local_window -= win_len; |
c->local_window -= win_len; |
c->local_consumed += win_len; |
c->local_consumed += win_len; |
} |
} |
return; |
return 0; |
} |
} |
|
|
if (compat20) { |
if (compat20) { |
|
|
if (win_len > c->local_window) { |
if (win_len > c->local_window) { |
logit("channel %d: rcvd too much data %d, win %d", |
logit("channel %d: rcvd too much data %d, win %d", |
c->self, win_len, c->local_window); |
c->self, win_len, c->local_window); |
return; |
return 0; |
} |
} |
c->local_window -= win_len; |
c->local_window -= win_len; |
} |
} |
|
|
else |
else |
buffer_append(&c->output, data, data_len); |
buffer_append(&c->output, data, data_len); |
packet_check_eom(); |
packet_check_eom(); |
|
return 0; |
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_extended_data(int type, u_int32_t seq, void *ctxt) |
channel_input_extended_data(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
int id; |
int id; |
|
|
packet_disconnect("Received extended_data for bad channel %d.", id); |
packet_disconnect("Received extended_data for bad channel %d.", id); |
if (c->type != SSH_CHANNEL_OPEN) { |
if (c->type != SSH_CHANNEL_OPEN) { |
logit("channel %d: ext data for non open", id); |
logit("channel %d: ext data for non open", id); |
return; |
return 0; |
} |
} |
if (c->flags & CHAN_EOF_RCVD) { |
if (c->flags & CHAN_EOF_RCVD) { |
if (datafellows & SSH_BUG_EXTEOF) |
if (datafellows & SSH_BUG_EXTEOF) |
|
|
c->extended_usage != CHAN_EXTENDED_WRITE || |
c->extended_usage != CHAN_EXTENDED_WRITE || |
tcode != SSH2_EXTENDED_DATA_STDERR) { |
tcode != SSH2_EXTENDED_DATA_STDERR) { |
logit("channel %d: bad ext data", c->self); |
logit("channel %d: bad ext data", c->self); |
return; |
return 0; |
} |
} |
data = packet_get_string(&data_len); |
data = packet_get_string(&data_len); |
packet_check_eom(); |
packet_check_eom(); |
|
|
logit("channel %d: rcvd too much extended_data %d, win %d", |
logit("channel %d: rcvd too much extended_data %d, win %d", |
c->self, data_len, c->local_window); |
c->self, data_len, c->local_window); |
free(data); |
free(data); |
return; |
return 0; |
} |
} |
debug2("channel %d: rcvd ext data %d", c->self, data_len); |
debug2("channel %d: rcvd ext data %d", c->self, data_len); |
c->local_window -= data_len; |
c->local_window -= data_len; |
buffer_append(&c->extended, data, data_len); |
buffer_append(&c->extended, data, data_len); |
free(data); |
free(data); |
|
return 0; |
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_ieof(int type, u_int32_t seq, void *ctxt) |
channel_input_ieof(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
int id; |
int id; |
|
|
if (buffer_len(&c->input) == 0) |
if (buffer_len(&c->input) == 0) |
chan_ibuf_empty(c); |
chan_ibuf_empty(c); |
} |
} |
|
return 0; |
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_close(int type, u_int32_t seq, void *ctxt) |
channel_input_close(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
int id; |
int id; |
|
|
buffer_clear(&c->input); |
buffer_clear(&c->input); |
c->type = SSH_CHANNEL_OUTPUT_DRAINING; |
c->type = SSH_CHANNEL_OUTPUT_DRAINING; |
} |
} |
|
return 0; |
} |
} |
|
|
/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ |
/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ |
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_oclose(int type, u_int32_t seq, void *ctxt) |
channel_input_oclose(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
int id = packet_get_int(); |
int id = packet_get_int(); |
|
|
if (c == NULL) |
if (c == NULL) |
packet_disconnect("Received oclose for nonexistent channel %d.", id); |
packet_disconnect("Received oclose for nonexistent channel %d.", id); |
chan_rcvd_oclose(c); |
chan_rcvd_oclose(c); |
|
return 0; |
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt) |
channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
int id = packet_get_int(); |
int id = packet_get_int(); |
|
|
packet_disconnect("Received close confirmation for " |
packet_disconnect("Received close confirmation for " |
"non-closed channel %d (type %d).", id, c->type); |
"non-closed channel %d (type %d).", id, c->type); |
channel_free(c); |
channel_free(c); |
|
return 0; |
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) |
channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
int id, remote_id; |
int id, remote_id; |
|
|
c->remote_window, c->remote_maxpacket); |
c->remote_window, c->remote_maxpacket); |
} |
} |
packet_check_eom(); |
packet_check_eom(); |
|
return 0; |
} |
} |
|
|
static char * |
static char * |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_open_failure(int type, u_int32_t seq, void *ctxt) |
channel_input_open_failure(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
int id, reason; |
int id, reason; |
|
|
packet_check_eom(); |
packet_check_eom(); |
/* Schedule the channel for cleanup/deletion. */ |
/* Schedule the channel for cleanup/deletion. */ |
chan_mark_dead(c); |
chan_mark_dead(c); |
|
return 0; |
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) |
channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
Channel *c; |
Channel *c; |
|
|
u_int adjust; |
u_int adjust; |
|
|
if (!compat20) |
if (!compat20) |
return; |
return 0; |
|
|
/* Get the channel number and verify it. */ |
/* Get the channel number and verify it. */ |
id = packet_get_int(); |
id = packet_get_int(); |
|
|
|
|
if (c == NULL) { |
if (c == NULL) { |
logit("Received window adjust for non-open channel %d.", id); |
logit("Received window adjust for non-open channel %d.", id); |
return; |
return 0; |
} |
} |
adjust = packet_get_int(); |
adjust = packet_get_int(); |
packet_check_eom(); |
packet_check_eom(); |
debug2("channel %d: rcvd adjust %u", id, adjust); |
debug2("channel %d: rcvd adjust %u", id, adjust); |
c->remote_window += adjust; |
c->remote_window += adjust; |
|
return 0; |
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_port_open(int type, u_int32_t seq, void *ctxt) |
channel_input_port_open(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
Channel *c = NULL; |
Channel *c = NULL; |
|
|
packet_send(); |
packet_send(); |
} else |
} else |
c->remote_id = remote_id; |
c->remote_id = remote_id; |
|
return 0; |
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) |
channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
Channel *c; |
Channel *c; |
|
|
|
|
if ((c = channel_lookup(id)) == NULL) { |
if ((c = channel_lookup(id)) == NULL) { |
logit("channel_input_status_confirm: %d: unknown", id); |
logit("channel_input_status_confirm: %d: unknown", id); |
return; |
return 0; |
} |
} |
; |
|
if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) |
if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) |
return; |
return 0; |
cc->cb(type, c, cc->ctx); |
cc->cb(type, c, cc->ctx); |
TAILQ_REMOVE(&c->status_confirms, cc, entry); |
TAILQ_REMOVE(&c->status_confirms, cc, entry); |
explicit_bzero(cc, sizeof(*cc)); |
explicit_bzero(cc, sizeof(*cc)); |
free(cc); |
free(cc); |
|
return 0; |
} |
} |
|
|
/* -- tcp forwarding */ |
/* -- tcp forwarding */ |
|
|
*/ |
*/ |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
x11_input_open(int type, u_int32_t seq, void *ctxt) |
x11_input_open(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
Channel *c = NULL; |
Channel *c = NULL; |
|
|
packet_put_int(c->self); |
packet_put_int(c->self); |
} |
} |
packet_send(); |
packet_send(); |
|
return 0; |
} |
} |
|
|
/* dummy protocol handler that denies SSH-1 requests (agent/x11) */ |
/* dummy protocol handler that denies SSH-1 requests (agent/x11) */ |
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
int |
deny_input_open(int type, u_int32_t seq, void *ctxt) |
deny_input_open(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
int rchan = packet_get_int(); |
int rchan = packet_get_int(); |
|
|
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
packet_put_int(rchan); |
packet_put_int(rchan); |
packet_send(); |
packet_send(); |
|
return 0; |
} |
} |
|
|
/* |
/* |