mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-07-22 05:21:51 +03:00
channels: Reformat
Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Andreas Schneider
parent
babd891e82
commit
c799a18d89
269
src/channels.c
269
src/channels.c
@ -166,29 +166,32 @@ uint32_t ssh_channel_new_id(ssh_session session)
|
|||||||
*
|
*
|
||||||
* Constructs the channel object.
|
* Constructs the channel object.
|
||||||
*/
|
*/
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){
|
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf)
|
||||||
uint32_t channelid=0;
|
{
|
||||||
|
uint32_t channelid = 0;
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
int rc;
|
int rc;
|
||||||
(void)type;
|
(void)type;
|
||||||
(void)user;
|
(void)user;
|
||||||
|
|
||||||
SSH_LOG(SSH_LOG_PACKET,"Received SSH2_MSG_CHANNEL_OPEN_CONFIRMATION");
|
SSH_LOG(SSH_LOG_PACKET, "Received SSH2_MSG_CHANNEL_OPEN_CONFIRMATION");
|
||||||
|
|
||||||
rc = ssh_buffer_unpack(packet, "d", &channelid);
|
rc = ssh_buffer_unpack(packet, "d", &channelid);
|
||||||
if (rc != SSH_OK)
|
if (rc != SSH_OK)
|
||||||
goto error;
|
goto error;
|
||||||
channel=ssh_channel_from_local(session,channelid);
|
channel = ssh_channel_from_local(session, channelid);
|
||||||
if(channel==NULL){
|
if (channel == NULL) {
|
||||||
ssh_set_error(session, SSH_FATAL,
|
ssh_set_error(session,
|
||||||
|
SSH_FATAL,
|
||||||
"Unknown channel id %" PRIu32,
|
"Unknown channel id %" PRIu32,
|
||||||
(uint32_t) channelid);
|
(uint32_t)channelid);
|
||||||
/* TODO: Set error marking in channel object */
|
/* TODO: Set error marking in channel object */
|
||||||
|
|
||||||
return SSH_PACKET_USED;
|
return SSH_PACKET_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ssh_buffer_unpack(packet, "ddd",
|
rc = ssh_buffer_unpack(packet,
|
||||||
|
"ddd",
|
||||||
&channel->remote_channel,
|
&channel->remote_channel,
|
||||||
&channel->remote_window,
|
&channel->remote_window,
|
||||||
&channel->remote_maxpacket);
|
&channel->remote_maxpacket);
|
||||||
@ -196,7 +199,8 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
SSH_LOG(SSH_LOG_DEBUG,
|
SSH_LOG(SSH_LOG_DEBUG,
|
||||||
"Received a CHANNEL_OPEN_CONFIRMATION for channel %" PRIu32 ":%" PRIu32,
|
"Received a CHANNEL_OPEN_CONFIRMATION for channel %" PRIu32
|
||||||
|
":%" PRIu32,
|
||||||
channel->local_channel,
|
channel->local_channel,
|
||||||
channel->remote_channel);
|
channel->remote_channel);
|
||||||
|
|
||||||
@ -235,8 +239,8 @@ error:
|
|||||||
*
|
*
|
||||||
* @brief Handle a SSH_CHANNEL_OPEN_FAILURE and set the state of the channel.
|
* @brief Handle a SSH_CHANNEL_OPEN_FAILURE and set the state of the channel.
|
||||||
*/
|
*/
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
|
SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail)
|
||||||
|
{
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
char *error = NULL;
|
char *error = NULL;
|
||||||
uint32_t code;
|
uint32_t code;
|
||||||
@ -244,14 +248,14 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
|
|||||||
(void)user;
|
(void)user;
|
||||||
(void)type;
|
(void)type;
|
||||||
|
|
||||||
channel=channel_from_msg(session,packet);
|
channel = channel_from_msg(session, packet);
|
||||||
if(channel==NULL){
|
if (channel == NULL) {
|
||||||
SSH_LOG(SSH_LOG_RARE,"Invalid channel in packet");
|
SSH_LOG(SSH_LOG_RARE, "Invalid channel in packet");
|
||||||
return SSH_PACKET_USED;
|
return SSH_PACKET_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ssh_buffer_unpack(packet, "ds", &code, &error);
|
rc = ssh_buffer_unpack(packet, "ds", &code, &error);
|
||||||
if (rc != SSH_OK){
|
if (rc != SSH_OK) {
|
||||||
ssh_set_error(session, SSH_FATAL, "Invalid packet");
|
ssh_set_error(session, SSH_FATAL, "Invalid packet");
|
||||||
return SSH_PACKET_USED;
|
return SSH_PACKET_USED;
|
||||||
}
|
}
|
||||||
@ -265,13 +269,15 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
ssh_set_error(session,
|
||||||
"Channel opening failure: channel %" PRIu32 " error (%" PRIu32 ") %s",
|
SSH_REQUEST_DENIED,
|
||||||
|
"Channel opening failure: channel %" PRIu32 " error (%" PRIu32
|
||||||
|
") %s",
|
||||||
channel->local_channel,
|
channel->local_channel,
|
||||||
code,
|
code,
|
||||||
error);
|
error);
|
||||||
SAFE_FREE(error);
|
SAFE_FREE(error);
|
||||||
channel->state=SSH_CHANNEL_STATE_OPEN_DENIED;
|
channel->state = SSH_CHANNEL_STATE_OPEN_DENIED;
|
||||||
|
|
||||||
ssh_callbacks_execute_list(channel->callbacks,
|
ssh_callbacks_execute_list(channel->callbacks,
|
||||||
ssh_channel_callbacks,
|
ssh_channel_callbacks,
|
||||||
@ -403,11 +409,13 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* return channel with corresponding local id, or NULL if not found */
|
/* return channel with corresponding local id, or NULL if not found */
|
||||||
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id) {
|
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id)
|
||||||
|
{
|
||||||
struct ssh_iterator *it;
|
struct ssh_iterator *it;
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
|
|
||||||
for (it = ssh_list_get_iterator(session->channels); it != NULL ; it=it->next) {
|
for (it = ssh_list_get_iterator(session->channels); it != NULL;
|
||||||
|
it = it->next) {
|
||||||
channel = ssh_iterator_value(ssh_channel, it);
|
channel = ssh_iterator_value(ssh_channel, it);
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
continue;
|
continue;
|
||||||
@ -505,24 +513,27 @@ static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet)
|
|||||||
uint32_t chan;
|
uint32_t chan;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ssh_buffer_unpack(packet,"d",&chan);
|
rc = ssh_buffer_unpack(packet, "d", &chan);
|
||||||
if (rc != SSH_OK) {
|
if (rc != SSH_OK) {
|
||||||
ssh_set_error(session, SSH_FATAL,
|
ssh_set_error(session,
|
||||||
|
SSH_FATAL,
|
||||||
"Getting channel from message: short read");
|
"Getting channel from message: short read");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = ssh_channel_from_local(session, chan);
|
channel = ssh_channel_from_local(session, chan);
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
ssh_set_error(session, SSH_FATAL,
|
ssh_set_error(session,
|
||||||
|
SSH_FATAL,
|
||||||
"Server specified invalid channel %" PRIu32,
|
"Server specified invalid channel %" PRIu32,
|
||||||
(uint32_t) chan);
|
(uint32_t)chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(channel_rcv_change_window) {
|
SSH_PACKET_CALLBACK(channel_rcv_change_window)
|
||||||
|
{
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
uint32_t bytes;
|
uint32_t bytes;
|
||||||
int rc;
|
int rc;
|
||||||
@ -531,7 +542,7 @@ SSH_PACKET_CALLBACK(channel_rcv_change_window) {
|
|||||||
(void)user;
|
(void)user;
|
||||||
(void)type;
|
(void)type;
|
||||||
|
|
||||||
channel = channel_from_msg(session,packet);
|
channel = channel_from_msg(session, packet);
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
||||||
}
|
}
|
||||||
@ -545,7 +556,8 @@ SSH_PACKET_CALLBACK(channel_rcv_change_window) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SSH_LOG(SSH_LOG_DEBUG,
|
SSH_LOG(SSH_LOG_DEBUG,
|
||||||
"Adding %" PRIu32 " bytes to channel (%" PRIu32 ":%" PRIu32 ") (from %" PRIu32 " bytes)",
|
"Adding %" PRIu32 " bytes to channel (%" PRIu32 ":%" PRIu32
|
||||||
|
") (from %" PRIu32 " bytes)",
|
||||||
bytes,
|
bytes,
|
||||||
channel->local_channel,
|
channel->local_channel,
|
||||||
channel->remote_channel,
|
channel->remote_channel,
|
||||||
@ -556,7 +568,8 @@ SSH_PACKET_CALLBACK(channel_rcv_change_window) {
|
|||||||
channel->remote_window += bytes;
|
channel->remote_window += bytes;
|
||||||
|
|
||||||
/* Writing to the channel is non-blocking until the receive window is empty.
|
/* Writing to the channel is non-blocking until the receive window is empty.
|
||||||
When the receive window becomes non-zero again, call channel_write_wontblock_function. */
|
* When the receive window becomes non-zero again, call
|
||||||
|
* channel_write_wontblock_function. */
|
||||||
if (was_empty && bytes > 0) {
|
if (was_empty && bytes > 0) {
|
||||||
ssh_callbacks_execute_list(channel->callbacks,
|
ssh_callbacks_execute_list(channel->callbacks,
|
||||||
ssh_channel_callbacks,
|
ssh_channel_callbacks,
|
||||||
@ -694,12 +707,13 @@ SSH_PACKET_CALLBACK(channel_rcv_data)
|
|||||||
return SSH_PACKET_USED;
|
return SSH_PACKET_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(channel_rcv_eof) {
|
SSH_PACKET_CALLBACK(channel_rcv_eof)
|
||||||
|
{
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
(void)user;
|
(void)user;
|
||||||
(void)type;
|
(void)type;
|
||||||
|
|
||||||
channel = channel_from_msg(session,packet);
|
channel = channel_from_msg(session, packet);
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
||||||
|
|
||||||
@ -983,13 +997,13 @@ int channel_default_bufferize(ssh_channel channel,
|
|||||||
{
|
{
|
||||||
ssh_session session;
|
ssh_session session;
|
||||||
|
|
||||||
if(channel == NULL) {
|
if (channel == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
session = channel->session;
|
session = channel->session;
|
||||||
|
|
||||||
if(data == NULL) {
|
if (data == NULL) {
|
||||||
ssh_set_error_invalid(session);
|
ssh_set_error_invalid(session);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1131,7 +1145,7 @@ int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
|
|||||||
|
|
||||||
session = channel->session;
|
session = channel->session;
|
||||||
|
|
||||||
if(remotehost == NULL || sourcehost == NULL) {
|
if (remotehost == NULL || sourcehost == NULL) {
|
||||||
ssh_set_error_invalid(session);
|
ssh_set_error_invalid(session);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -1527,30 +1541,34 @@ static int channel_write_common(ssh_channel channel,
|
|||||||
uint32_t effectivelen;
|
uint32_t effectivelen;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if(channel == NULL) {
|
if (channel == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
session = channel->session;
|
session = channel->session;
|
||||||
if(data == NULL) {
|
if (data == NULL) {
|
||||||
ssh_set_error_invalid(session);
|
ssh_set_error_invalid(session);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > INT_MAX) {
|
if (len > INT_MAX) {
|
||||||
SSH_LOG(SSH_LOG_TRACE,
|
SSH_LOG(SSH_LOG_TRACE,
|
||||||
"Length (%" PRIu32 ") is bigger than INT_MAX", len);
|
"Length (%" PRIu32 ") is bigger than INT_MAX",
|
||||||
|
len);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->local_eof) {
|
if (channel->local_eof) {
|
||||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
ssh_set_error(session,
|
||||||
"Can't write to channel %" PRIu32 ":%" PRIu32 " after EOF was sent",
|
SSH_REQUEST_DENIED,
|
||||||
|
"Can't write to channel %" PRIu32 ":%" PRIu32
|
||||||
|
" after EOF was sent",
|
||||||
channel->local_channel,
|
channel->local_channel,
|
||||||
channel->remote_channel);
|
channel->remote_channel);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->state != SSH_CHANNEL_STATE_OPEN || channel->delayed_close != 0) {
|
if (channel->state != SSH_CHANNEL_STATE_OPEN ||
|
||||||
|
channel->delayed_close != 0) {
|
||||||
ssh_set_error(session, SSH_REQUEST_DENIED, "Remote channel is closed");
|
ssh_set_error(session, SSH_REQUEST_DENIED, "Remote channel is closed");
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -1560,25 +1578,30 @@ static int channel_write_common(ssh_channel channel,
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ssh_waitsession_unblocked(session) == 0){
|
if (ssh_waitsession_unblocked(session) == 0) {
|
||||||
rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_DEFAULT,
|
rc = ssh_handle_packets_termination(session,
|
||||||
ssh_waitsession_unblocked, session);
|
SSH_TIMEOUT_DEFAULT,
|
||||||
|
ssh_waitsession_unblocked,
|
||||||
|
session);
|
||||||
if (rc == SSH_ERROR || !ssh_waitsession_unblocked(session))
|
if (rc == SSH_ERROR || !ssh_waitsession_unblocked(session))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
if (channel->remote_window < len) {
|
if (channel->remote_window < len) {
|
||||||
SSH_LOG(SSH_LOG_DEBUG,
|
SSH_LOG(SSH_LOG_DEBUG,
|
||||||
"Remote window is %" PRIu32 " bytes. going to write %" PRIu32 " bytes",
|
"Remote window is %" PRIu32
|
||||||
|
" bytes. going to write %" PRIu32 " bytes",
|
||||||
channel->remote_window,
|
channel->remote_window,
|
||||||
len);
|
len);
|
||||||
/* When the window is zero, wait for it to grow */
|
/* When the window is zero, wait for it to grow */
|
||||||
if(channel->remote_window == 0) {
|
if (channel->remote_window == 0) {
|
||||||
/* nothing can be written */
|
/* nothing can be written */
|
||||||
SSH_LOG(SSH_LOG_DEBUG,
|
SSH_LOG(SSH_LOG_DEBUG, "Wait for a growing window message...");
|
||||||
"Wait for a growing window message...");
|
rc = ssh_handle_packets_termination(
|
||||||
rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_DEFAULT,
|
session,
|
||||||
ssh_channel_waitwindow_termination,channel);
|
SSH_TIMEOUT_DEFAULT,
|
||||||
|
ssh_channel_waitwindow_termination,
|
||||||
|
channel);
|
||||||
if (rc == SSH_ERROR ||
|
if (rc == SSH_ERROR ||
|
||||||
!ssh_channel_waitwindow_termination(channel) ||
|
!ssh_channel_waitwindow_termination(channel) ||
|
||||||
session->session_state == SSH_SESSION_STATE_ERROR ||
|
session->session_state == SSH_SESSION_STATE_ERROR ||
|
||||||
@ -1600,7 +1623,8 @@ static int channel_write_common(ssh_channel channel,
|
|||||||
|
|
||||||
rc = ssh_buffer_pack(session->out_buffer,
|
rc = ssh_buffer_pack(session->out_buffer,
|
||||||
"bd",
|
"bd",
|
||||||
is_stderr ? SSH2_MSG_CHANNEL_EXTENDED_DATA : SSH2_MSG_CHANNEL_DATA,
|
is_stderr ? SSH2_MSG_CHANNEL_EXTENDED_DATA
|
||||||
|
: SSH2_MSG_CHANNEL_DATA,
|
||||||
channel->remote_channel);
|
channel->remote_channel);
|
||||||
if (rc != SSH_OK) {
|
if (rc != SSH_OK) {
|
||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
@ -1640,7 +1664,7 @@ static int channel_write_common(ssh_channel channel,
|
|||||||
|
|
||||||
channel->remote_window -= effectivelen;
|
channel->remote_window -= effectivelen;
|
||||||
len -= effectivelen;
|
len -= effectivelen;
|
||||||
data = ((uint8_t*)data + effectivelen);
|
data = ((uint8_t *)data + effectivelen);
|
||||||
if (channel->counter != NULL) {
|
if (channel->counter != NULL) {
|
||||||
channel->counter->out_bytes += effectivelen;
|
channel->counter->out_bytes += effectivelen;
|
||||||
}
|
}
|
||||||
@ -1778,12 +1802,13 @@ void ssh_channel_set_blocking(ssh_channel channel, int blocking)
|
|||||||
*
|
*
|
||||||
* @brief handle a SSH_CHANNEL_SUCCESS packet and set the channel state.
|
* @brief handle a SSH_CHANNEL_SUCCESS packet and set the channel state.
|
||||||
*/
|
*/
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_channel_success){
|
SSH_PACKET_CALLBACK(ssh_packet_channel_success)
|
||||||
|
{
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
(void)type;
|
(void)type;
|
||||||
(void)user;
|
(void)user;
|
||||||
|
|
||||||
channel=channel_from_msg(session,packet);
|
channel = channel_from_msg(session, packet);
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
||||||
return SSH_PACKET_USED;
|
return SSH_PACKET_USED;
|
||||||
@ -1793,11 +1818,12 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_success){
|
|||||||
"Received SSH_CHANNEL_SUCCESS on channel (%" PRIu32 ":%" PRIu32 ")",
|
"Received SSH_CHANNEL_SUCCESS on channel (%" PRIu32 ":%" PRIu32 ")",
|
||||||
channel->local_channel,
|
channel->local_channel,
|
||||||
channel->remote_channel);
|
channel->remote_channel);
|
||||||
if(channel->request_state != SSH_CHANNEL_REQ_STATE_PENDING){
|
if (channel->request_state != SSH_CHANNEL_REQ_STATE_PENDING) {
|
||||||
SSH_LOG(SSH_LOG_RARE, "SSH_CHANNEL_SUCCESS received in incorrect state %d",
|
SSH_LOG(SSH_LOG_RARE,
|
||||||
|
"SSH_CHANNEL_SUCCESS received in incorrect state %d",
|
||||||
channel->request_state);
|
channel->request_state);
|
||||||
} else {
|
} else {
|
||||||
channel->request_state=SSH_CHANNEL_REQ_STATE_ACCEPTED;
|
channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED;
|
||||||
|
|
||||||
ssh_callbacks_execute_list(channel->callbacks,
|
ssh_callbacks_execute_list(channel->callbacks,
|
||||||
ssh_channel_callbacks,
|
ssh_channel_callbacks,
|
||||||
@ -1814,12 +1840,13 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_success){
|
|||||||
*
|
*
|
||||||
* @brief Handle a SSH_CHANNEL_FAILURE packet and set the channel state.
|
* @brief Handle a SSH_CHANNEL_FAILURE packet and set the channel state.
|
||||||
*/
|
*/
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_channel_failure){
|
SSH_PACKET_CALLBACK(ssh_packet_channel_failure)
|
||||||
|
{
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
(void)type;
|
(void)type;
|
||||||
(void)user;
|
(void)user;
|
||||||
|
|
||||||
channel=channel_from_msg(session,packet);
|
channel = channel_from_msg(session, packet);
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
||||||
|
|
||||||
@ -1830,11 +1857,12 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_failure){
|
|||||||
"Received SSH_CHANNEL_FAILURE on channel (%" PRIu32 ":%" PRIu32 ")",
|
"Received SSH_CHANNEL_FAILURE on channel (%" PRIu32 ":%" PRIu32 ")",
|
||||||
channel->local_channel,
|
channel->local_channel,
|
||||||
channel->remote_channel);
|
channel->remote_channel);
|
||||||
if(channel->request_state != SSH_CHANNEL_REQ_STATE_PENDING){
|
if (channel->request_state != SSH_CHANNEL_REQ_STATE_PENDING) {
|
||||||
SSH_LOG(SSH_LOG_RARE, "SSH_CHANNEL_FAILURE received in incorrect state %d",
|
SSH_LOG(SSH_LOG_RARE,
|
||||||
|
"SSH_CHANNEL_FAILURE received in incorrect state %d",
|
||||||
channel->request_state);
|
channel->request_state);
|
||||||
} else {
|
} else {
|
||||||
channel->request_state=SSH_CHANNEL_REQ_STATE_DENIED;
|
channel->request_state = SSH_CHANNEL_REQ_STATE_DENIED;
|
||||||
|
|
||||||
ssh_callbacks_execute_list(channel->callbacks,
|
ssh_callbacks_execute_list(channel->callbacks,
|
||||||
ssh_channel_callbacks,
|
ssh_channel_callbacks,
|
||||||
@ -1968,17 +1996,17 @@ int ssh_channel_request_pty_size_modes(ssh_channel channel, const char *terminal
|
|||||||
ssh_buffer buffer = NULL;
|
ssh_buffer buffer = NULL;
|
||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
|
|
||||||
if(channel == NULL) {
|
if (channel == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
session = channel->session;
|
session = channel->session;
|
||||||
|
|
||||||
if(terminal == NULL) {
|
if (terminal == NULL) {
|
||||||
ssh_set_error_invalid(channel->session);
|
ssh_set_error_invalid(channel->session);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(channel->request_state){
|
switch (channel->request_state) {
|
||||||
case SSH_CHANNEL_REQ_STATE_NONE:
|
case SSH_CHANNEL_REQ_STATE_NONE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2965,34 +2993,34 @@ int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
|
|||||||
ssh_session session;
|
ssh_session session;
|
||||||
char *buffer_tmp = NULL;
|
char *buffer_tmp = NULL;
|
||||||
int r;
|
int r;
|
||||||
uint32_t total=0;
|
uint32_t total = 0;
|
||||||
|
|
||||||
if(channel == NULL) {
|
if (channel == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
session = channel->session;
|
session = channel->session;
|
||||||
|
|
||||||
if(buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
ssh_set_error_invalid(channel->session);
|
ssh_set_error_invalid(channel->session);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_buffer_reinit(buffer);
|
ssh_buffer_reinit(buffer);
|
||||||
if(count==0){
|
if (count == 0) {
|
||||||
do {
|
do {
|
||||||
r=ssh_channel_poll(channel, is_stderr);
|
r = ssh_channel_poll(channel, is_stderr);
|
||||||
if(r < 0){
|
if (r < 0) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if(r > 0){
|
if (r > 0) {
|
||||||
count = r;
|
count = r;
|
||||||
buffer_tmp = ssh_buffer_allocate(buffer, count);
|
buffer_tmp = ssh_buffer_allocate(buffer, count);
|
||||||
if (buffer_tmp == NULL) {
|
if (buffer_tmp == NULL) {
|
||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
r=ssh_channel_read(channel, buffer_tmp, r, is_stderr);
|
r = ssh_channel_read(channel, buffer_tmp, r, is_stderr);
|
||||||
if(r < 0){
|
if (r < 0) {
|
||||||
ssh_buffer_pass_bytes_end(buffer, count);
|
ssh_buffer_pass_bytes_end(buffer, count);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -3001,7 +3029,7 @@ int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if(ssh_channel_is_eof(channel)){
|
if (ssh_channel_is_eof(channel)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ssh_handle_packets(channel->session, SSH_TIMEOUT_INFINITE);
|
ssh_handle_packets(channel->session, SSH_TIMEOUT_INFINITE);
|
||||||
@ -3013,13 +3041,13 @@ int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
|
|||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
while(total < count){
|
while (total < count) {
|
||||||
r=ssh_channel_read(channel, buffer_tmp, count - total, is_stderr);
|
r = ssh_channel_read(channel, buffer_tmp, count - total, is_stderr);
|
||||||
if(r<0){
|
if (r < 0) {
|
||||||
ssh_buffer_pass_bytes_end(buffer, count);
|
ssh_buffer_pass_bytes_end(buffer, count);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if(r==0){
|
if (r == 0) {
|
||||||
/* Rollback the unused space */
|
/* Rollback the unused space */
|
||||||
ssh_buffer_pass_bytes_end(buffer, count - total);
|
ssh_buffer_pass_bytes_end(buffer, count - total);
|
||||||
return total;
|
return total;
|
||||||
@ -3104,10 +3132,10 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
|||||||
struct ssh_channel_read_termination_struct ctx;
|
struct ssh_channel_read_termination_struct ctx;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if(channel == NULL) {
|
if (channel == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if(dest == NULL) {
|
if (dest == NULL) {
|
||||||
ssh_set_error_invalid(channel->session);
|
ssh_set_error_invalid(channel->session);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
@ -3120,7 +3148,7 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_stderr) {
|
if (is_stderr) {
|
||||||
stdbuf=channel->stderr_buffer;
|
stdbuf = channel->stderr_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSH_LOG(SSH_LOG_PACKET,
|
SSH_LOG(SSH_LOG_PACKET,
|
||||||
@ -3148,7 +3176,8 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the channel is closed or in an error state, reading from it is an error
|
* If the channel is closed or in an error state, reading from it is an
|
||||||
|
* error
|
||||||
*/
|
*/
|
||||||
if (session->session_state == SSH_SESSION_STATE_ERROR) {
|
if (session->session_state == SSH_SESSION_STATE_ERROR) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
@ -3158,16 +3187,14 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (channel->state == SSH_CHANNEL_STATE_CLOSED) {
|
if (channel->state == SSH_CHANNEL_STATE_CLOSED) {
|
||||||
ssh_set_error(session,
|
ssh_set_error(session, SSH_FATAL, "Remote channel is closed.");
|
||||||
SSH_FATAL,
|
|
||||||
"Remote channel is closed.");
|
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
len = ssh_buffer_get_len(stdbuf);
|
len = ssh_buffer_get_len(stdbuf);
|
||||||
/* Read count bytes if len is greater, everything otherwise */
|
/* Read count bytes if len is greater, everything otherwise */
|
||||||
len = (len > count ? count : len);
|
len = (len > count ? count : len);
|
||||||
memcpy(dest, ssh_buffer_get(stdbuf), len);
|
memcpy(dest, ssh_buffer_get(stdbuf), len);
|
||||||
ssh_buffer_pass_bytes(stdbuf,len);
|
ssh_buffer_pass_bytes(stdbuf, len);
|
||||||
if (channel->counter != NULL) {
|
if (channel->counter != NULL) {
|
||||||
channel->counter->in_bytes += len;
|
channel->counter->in_bytes += len;
|
||||||
}
|
}
|
||||||
@ -3530,12 +3557,15 @@ channel_protocol_select(ssh_channel *rchans, ssh_channel *wchans,
|
|||||||
for (i = 0; rchans[i] != NULL; i++) {
|
for (i = 0; rchans[i] != NULL; i++) {
|
||||||
chan = rchans[i];
|
chan = rchans[i];
|
||||||
|
|
||||||
while (ssh_channel_is_open(chan) && ssh_socket_data_available(chan->session->socket)) {
|
while (ssh_channel_is_open(chan) &&
|
||||||
|
ssh_socket_data_available(chan->session->socket)) {
|
||||||
ssh_handle_packets(chan->session, SSH_TIMEOUT_NONBLOCKING);
|
ssh_handle_packets(chan->session, SSH_TIMEOUT_NONBLOCKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((chan->stdout_buffer && ssh_buffer_get_len(chan->stdout_buffer) > 0) ||
|
if ((chan->stdout_buffer &&
|
||||||
(chan->stderr_buffer && ssh_buffer_get_len(chan->stderr_buffer) > 0) ||
|
ssh_buffer_get_len(chan->stdout_buffer) > 0) ||
|
||||||
|
(chan->stderr_buffer &&
|
||||||
|
ssh_buffer_get_len(chan->stderr_buffer) > 0) ||
|
||||||
chan->remote_eof) {
|
chan->remote_eof) {
|
||||||
rout[j] = chan;
|
rout[j] = chan;
|
||||||
j++;
|
j++;
|
||||||
@ -3544,7 +3574,7 @@ channel_protocol_select(ssh_channel *rchans, ssh_channel *wchans,
|
|||||||
rout[j] = NULL;
|
rout[j] = NULL;
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
for(i = 0; wchans[i] != NULL; i++) {
|
for (i = 0; wchans[i] != NULL; i++) {
|
||||||
chan = wchans[i];
|
chan = wchans[i];
|
||||||
/* It's not our business to seek if the file descriptor is writable */
|
/* It's not our business to seek if the file descriptor is writable */
|
||||||
if (ssh_socket_data_writable(chan->session->socket) &&
|
if (ssh_socket_data_writable(chan->session->socket) &&
|
||||||
@ -3559,7 +3589,8 @@ channel_protocol_select(ssh_channel *rchans, ssh_channel *wchans,
|
|||||||
for (i = 0; echans[i] != NULL; i++) {
|
for (i = 0; echans[i] != NULL; i++) {
|
||||||
chan = echans[i];
|
chan = echans[i];
|
||||||
|
|
||||||
if (!ssh_socket_is_open(chan->session->socket) || ssh_channel_is_closed(chan)) {
|
if (!ssh_socket_is_open(chan->session->socket) ||
|
||||||
|
ssh_channel_is_closed(chan)) {
|
||||||
eout[j] = chan;
|
eout[j] = chan;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
@ -3610,11 +3641,11 @@ int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
|||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
int tm, tm_base;
|
int tm, tm_base;
|
||||||
int firstround=1;
|
int firstround = 1;
|
||||||
struct ssh_timestamp ts;
|
struct ssh_timestamp ts;
|
||||||
|
|
||||||
if (timeout != NULL)
|
if (timeout != NULL)
|
||||||
tm_base = timeout->tv_sec * 1000 + timeout->tv_usec/1000;
|
tm_base = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
|
||||||
else
|
else
|
||||||
tm_base = SSH_TIMEOUT_INFINITE;
|
tm_base = SSH_TIMEOUT_INFINITE;
|
||||||
ssh_timestamp_init(&ts);
|
ssh_timestamp_init(&ts);
|
||||||
@ -3632,7 +3663,8 @@ int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
|||||||
exceptchans = &dummy;
|
exceptchans = &dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readchans[0] == NULL && writechans[0] == NULL && exceptchans[0] == NULL) {
|
if (readchans[0] == NULL && writechans[0] == NULL &&
|
||||||
|
exceptchans[0] == NULL) {
|
||||||
/* No channel to poll?? Go away! */
|
/* No channel to poll?? Go away! */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3661,8 +3693,12 @@ int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
|||||||
* infrastructure to poll on all sessions.
|
* infrastructure to poll on all sessions.
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
channel_protocol_select(readchans, writechans, exceptchans,
|
channel_protocol_select(readchans,
|
||||||
rchans, wchans, echans);
|
writechans,
|
||||||
|
exceptchans,
|
||||||
|
rchans,
|
||||||
|
wchans,
|
||||||
|
echans);
|
||||||
if (rchans[0] != NULL || wchans[0] != NULL || echans[0] != NULL) {
|
if (rchans[0] != NULL || wchans[0] != NULL || echans[0] != NULL) {
|
||||||
/* At least one channel has an event */
|
/* At least one channel has an event */
|
||||||
break;
|
break;
|
||||||
@ -3691,12 +3727,12 @@ int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Get out if the timeout has elapsed */
|
/* Get out if the timeout has elapsed */
|
||||||
if (!firstround && ssh_timeout_elapsed(&ts, tm_base)){
|
if (!firstround && ssh_timeout_elapsed(&ts, tm_base)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Here we go */
|
/* Here we go */
|
||||||
rc = ssh_event_dopoll(event,tm);
|
rc = ssh_event_dopoll(event, tm);
|
||||||
if (rc != SSH_OK){
|
if (rc != SSH_OK) {
|
||||||
SAFE_FREE(rchans);
|
SAFE_FREE(rchans);
|
||||||
SAFE_FREE(wchans);
|
SAFE_FREE(wchans);
|
||||||
SAFE_FREE(echans);
|
SAFE_FREE(echans);
|
||||||
@ -3704,22 +3740,28 @@ int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
tm = ssh_timeout_update(&ts, tm_base);
|
tm = ssh_timeout_update(&ts, tm_base);
|
||||||
firstround=0;
|
firstround = 0;
|
||||||
} while(1);
|
} while (1);
|
||||||
|
|
||||||
if (readchans != &dummy) {
|
if (readchans != &dummy) {
|
||||||
memcpy(readchans, rchans, (count_ptrs(rchans) + 1) * sizeof(ssh_channel));
|
memcpy(readchans,
|
||||||
|
rchans,
|
||||||
|
(count_ptrs(rchans) + 1) * sizeof(ssh_channel));
|
||||||
}
|
}
|
||||||
if (writechans != &dummy) {
|
if (writechans != &dummy) {
|
||||||
memcpy(writechans, wchans, (count_ptrs(wchans) + 1) * sizeof(ssh_channel));
|
memcpy(writechans,
|
||||||
|
wchans,
|
||||||
|
(count_ptrs(wchans) + 1) * sizeof(ssh_channel));
|
||||||
}
|
}
|
||||||
if (exceptchans != &dummy) {
|
if (exceptchans != &dummy) {
|
||||||
memcpy(exceptchans, echans, (count_ptrs(echans) + 1) * sizeof(ssh_channel));
|
memcpy(exceptchans,
|
||||||
|
echans,
|
||||||
|
(count_ptrs(echans) + 1) * sizeof(ssh_channel));
|
||||||
}
|
}
|
||||||
SAFE_FREE(rchans);
|
SAFE_FREE(rchans);
|
||||||
SAFE_FREE(wchans);
|
SAFE_FREE(wchans);
|
||||||
SAFE_FREE(echans);
|
SAFE_FREE(echans);
|
||||||
if(event)
|
if (event)
|
||||||
ssh_event_free(event);
|
ssh_event_free(event);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3801,17 +3843,17 @@ int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost
|
|||||||
ssh_buffer payload = NULL;
|
ssh_buffer payload = NULL;
|
||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
|
|
||||||
if(channel == NULL) {
|
if (channel == NULL) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if(remotehost == NULL || sourcehost == NULL) {
|
if (remotehost == NULL || sourcehost == NULL) {
|
||||||
ssh_set_error_invalid(channel->session);
|
ssh_set_error_invalid(channel->session);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
session = channel->session;
|
session = channel->session;
|
||||||
|
|
||||||
if(channel->state != SSH_CHANNEL_STATE_NOT_OPEN)
|
if (channel->state != SSH_CHANNEL_STATE_NOT_OPEN)
|
||||||
goto pending;
|
goto pending;
|
||||||
payload = ssh_buffer_new();
|
payload = ssh_buffer_new();
|
||||||
if (payload == NULL) {
|
if (payload == NULL) {
|
||||||
@ -3824,7 +3866,7 @@ int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost
|
|||||||
remoteport,
|
remoteport,
|
||||||
sourcehost,
|
sourcehost,
|
||||||
localport);
|
localport);
|
||||||
if (rc != SSH_OK){
|
if (rc != SSH_OK) {
|
||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -3865,16 +3907,16 @@ int ssh_channel_open_x11(ssh_channel channel,
|
|||||||
ssh_buffer payload = NULL;
|
ssh_buffer payload = NULL;
|
||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
|
|
||||||
if(channel == NULL) {
|
if (channel == NULL) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if(orig_addr == NULL) {
|
if (orig_addr == NULL) {
|
||||||
ssh_set_error_invalid(channel->session);
|
ssh_set_error_invalid(channel->session);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
session = channel->session;
|
session = channel->session;
|
||||||
|
|
||||||
if(channel->state != SSH_CHANNEL_STATE_NOT_OPEN)
|
if (channel->state != SSH_CHANNEL_STATE_NOT_OPEN)
|
||||||
goto pending;
|
goto pending;
|
||||||
|
|
||||||
payload = ssh_buffer_new();
|
payload = ssh_buffer_new();
|
||||||
@ -3883,10 +3925,7 @@ int ssh_channel_open_x11(ssh_channel channel,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ssh_buffer_pack(payload,
|
rc = ssh_buffer_pack(payload, "sd", orig_addr, orig_port);
|
||||||
"sd",
|
|
||||||
orig_addr,
|
|
||||||
orig_port);
|
|
||||||
if (rc != SSH_OK) {
|
if (rc != SSH_OK) {
|
||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
goto error;
|
goto error;
|
||||||
|
Reference in New Issue
Block a user