summaryrefslogtreecommitdiffstats
path: root/libssh/channels.c
diff options
context:
space:
mode:
Diffstat (limited to 'libssh/channels.c')
-rw-r--r--libssh/channels.c308
1 files changed, 159 insertions, 149 deletions
diff --git a/libssh/channels.c b/libssh/channels.c
index 13ea25f..8af3a03 100644
--- a/libssh/channels.c
+++ b/libssh/channels.c
@@ -314,11 +314,13 @@ static ssh_channel channel_from_msg(ssh_session session) {
return channel;
}
-static void channel_rcv_change_window(ssh_session session) {
+int channel_rcv_change_window(ssh_session session, void *user, u_int8_t type, ssh_buffer packet) {
ssh_channel channel;
uint32_t bytes;
int rc;
-
+ (void)user;
+ (void)type;
+ (void)packet;
enter_function();
channel = channel_from_msg(session);
@@ -331,7 +333,7 @@ static void channel_rcv_change_window(ssh_session session) {
ssh_log(session, SSH_LOG_PACKET,
"Error getting a window adjust message: invalid packet");
leave_function();
- return;
+ return SSH_PACKET_USED;
}
bytes = ntohl(bytes);
@@ -345,22 +347,29 @@ static void channel_rcv_change_window(ssh_session session) {
channel->remote_window += bytes;
leave_function();
+ return SSH_PACKET_USED;
}
/* is_stderr is set to 1 if the data are extended, ie stderr */
-static void channel_rcv_data(ssh_session session,int is_stderr) {
+int channel_rcv_data(ssh_session session, void *user, u_int8_t type, ssh_buffer packet) {
ssh_channel channel;
ssh_string str;
size_t len;
-
+ int is_stderr;
+ (void)user;
+ (void)packet;
enter_function();
+ if(type==SSH2_MSG_CHANNEL_DATA)
+ is_stderr=0;
+ else
+ is_stderr=1;
channel = channel_from_msg(session);
if (channel == NULL) {
ssh_log(session, SSH_LOG_FUNCTIONS,
"%s", ssh_get_error(session));
leave_function();
- return;
+ return SSH_PACKET_USED;
}
if (is_stderr) {
@@ -373,7 +382,7 @@ static void channel_rcv_data(ssh_session session,int is_stderr) {
if (str == NULL) {
ssh_log(session, SSH_LOG_PACKET, "Invalid data packet!");
leave_function();
- return;
+ return SSH_PACKET_USED;
}
len = string_len(str);
@@ -396,7 +405,7 @@ static void channel_rcv_data(ssh_session session,int is_stderr) {
is_stderr) < 0) {
string_free(str);
leave_function();
- return;
+ return SSH_PACKET_USED;
}
if (len <= channel->local_window) {
@@ -412,18 +421,21 @@ static void channel_rcv_data(ssh_session session,int is_stderr) {
string_free(str);
leave_function();
+ return SSH_PACKET_USED;
}
-static void channel_rcv_eof(ssh_session session) {
+int channel_rcv_eof(ssh_session session, void *user, u_int8_t type, ssh_buffer packet) {
ssh_channel channel;
-
+ (void)user;
+ (void)type;
+ (void)packet;
enter_function();
channel = channel_from_msg(session);
if (channel == NULL) {
ssh_log(session, SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
leave_function();
- return;
+ return SSH_PACKET_USED;
}
ssh_log(session, SSH_LOG_PACKET,
@@ -434,134 +446,142 @@ static void channel_rcv_eof(ssh_session session) {
channel->remote_eof = 1;
leave_function();
+ return SSH_PACKET_USED;
}
-static void channel_rcv_close(ssh_session session) {
- ssh_channel channel;
-
- enter_function();
-
- channel = channel_from_msg(session);
- if (channel == NULL) {
- ssh_log(session, SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
- leave_function();
- return;
- }
-
- ssh_log(session, SSH_LOG_PACKET,
- "Received close on channel (%d:%d)",
- channel->local_channel,
- channel->remote_channel);
-
- if ((channel->stdout_buffer &&
- buffer_get_rest_len(channel->stdout_buffer) > 0) ||
- (channel->stderr_buffer &&
- buffer_get_rest_len(channel->stderr_buffer) > 0)) {
- channel->delayed_close = 1;
- } else {
- channel->open = 0;
- }
-
- if (channel->remote_eof == 0) {
- ssh_log(session, SSH_LOG_PACKET,
- "Remote host not polite enough to send an eof before close");
- }
- channel->remote_eof = 1;
- /*
- * The remote eof doesn't break things if there was still data into read
- * buffer because the eof is ignored until the buffer is empty.
- */
-
- leave_function();
+int channel_rcv_close(ssh_session session, void *user, u_int8_t type, ssh_buffer packet) {
+ ssh_channel channel;
+ (void)user;
+ (void)type;
+ (void)packet;
+ enter_function();
+
+ channel = channel_from_msg(session);
+ if (channel == NULL) {
+ ssh_log(session, SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
+ leave_function();
+ return SSH_PACKET_USED;
+ }
+
+ ssh_log(session, SSH_LOG_PACKET,
+ "Received close on channel (%d:%d)",
+ channel->local_channel,
+ channel->remote_channel);
+
+ if ((channel->stdout_buffer &&
+ buffer_get_rest_len(channel->stdout_buffer) > 0) ||
+ (channel->stderr_buffer &&
+ buffer_get_rest_len(channel->stderr_buffer) > 0)) {
+ channel->delayed_close = 1;
+ } else {
+ channel->open = 0;
+ }
+
+ if (channel->remote_eof == 0) {
+ ssh_log(session, SSH_LOG_PACKET,
+ "Remote host not polite enough to send an eof before close");
+ }
+ channel->remote_eof = 1;
+ /*
+ * The remote eof doesn't break things if there was still data into read
+ * buffer because the eof is ignored until the buffer is empty.
+ */
+
+ leave_function();
+ return SSH_PACKET_USED;
}
-static void channel_rcv_request(ssh_session session) {
- ssh_channel channel;
- ssh_string request_s;
- char *request;
- uint32_t status;
- uint32_t startpos = session->in_buffer->pos;
-
- enter_function();
-
- channel = channel_from_msg(session);
- if (channel == NULL) {
- ssh_log(session, SSH_LOG_FUNCTIONS,"%s", ssh_get_error(session));
- leave_function();
- return;
- }
-
- request_s = buffer_get_ssh_string(session->in_buffer);
- if (request_s == NULL) {
- ssh_log(session, SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST");
- leave_function();
- return;
- }
-
- request = string_to_char(request_s);
- string_free(request_s);
- if (request == NULL) {
- leave_function();
- return;
- }
-
- buffer_get_u8(session->in_buffer, (uint8_t *) &status);
-
- if (strcmp(request,"exit-status") == 0) {
- SAFE_FREE(request);
- ssh_log(session, SSH_LOG_PACKET, "received exit-status");
- buffer_get_u32(session->in_buffer, &status);
- channel->exit_status = ntohl(status);
-
- leave_function();
- return ;
- }
-
- if (strcmp(request, "exit-signal") == 0) {
- const char *core = "(core dumped)";
- ssh_string signal_s;
- char *signal;
- uint8_t i;
-
- SAFE_FREE(request);
-
- signal_s = buffer_get_ssh_string(session->in_buffer);
- if (signal_s == NULL) {
- ssh_log(session, SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST");
- leave_function();
- return;
- }
-
- signal = string_to_char(signal_s);
- string_free(signal_s);
- if (signal == NULL) {
- leave_function();
- return;
- }
-
- buffer_get_u8(session->in_buffer, &i);
- if (i == 0) {
- core = "";
- }
-
- ssh_log(session, SSH_LOG_PACKET,
- "Remote connection closed by signal SIG %s %s", signal, core);
- SAFE_FREE(signal);
-
- leave_function();
- return;
- }
-
- /* TODO call message_handle since it handles channel requests as messages */
- /* *but* reset buffer before !! */
-
- session->in_buffer->pos = startpos;
- message_handle(session, SSH2_MSG_CHANNEL_REQUEST);
-
- ssh_log(session, SSH_LOG_PACKET, "Unknown request %s", request);
- SAFE_FREE(request);
-
- leave_function();
+int channel_rcv_request(ssh_session session, void *user, u_int8_t type, ssh_buffer packet) {
+ ssh_channel channel;
+ ssh_string request_s;
+ char *request;
+ uint32_t status;
+ uint32_t startpos = session->in_buffer->pos;
+ (void)user;
+ (void)type;
+ (void)packet;
+
+ enter_function();
+
+ channel = channel_from_msg(session);
+ if (channel == NULL) {
+ ssh_log(session, SSH_LOG_FUNCTIONS,"%s", ssh_get_error(session));
+ leave_function();
+ return SSH_PACKET_USED;
+ }
+
+ request_s = buffer_get_ssh_string(session->in_buffer);
+ if (request_s == NULL) {
+ ssh_log(session, SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST");
+ leave_function();
+ return SSH_PACKET_USED;
+ }
+
+ request = string_to_char(request_s);
+ string_free(request_s);
+ if (request == NULL) {
+ leave_function();
+ return SSH_PACKET_USED;
+ }
+
+ buffer_get_u8(session->in_buffer, (uint8_t *) &status);
+
+ if (strcmp(request,"exit-status") == 0) {
+ SAFE_FREE(request);
+ ssh_log(session, SSH_LOG_PACKET, "received exit-status");
+ buffer_get_u32(session->in_buffer, &status);
+ channel->exit_status = ntohl(status);
+
+ leave_function();
+ return SSH_PACKET_USED;
+ }
+
+ if (strcmp(request, "exit-signal") == 0) {
+ const char *core = "(core dumped)";
+ ssh_string signal_s;
+ char *signal;
+ uint8_t i;
+
+ SAFE_FREE(request);
+
+ signal_s = buffer_get_ssh_string(session->in_buffer);
+ if (signal_s == NULL) {
+ ssh_log(session, SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST");
+ leave_function();
+ return SSH_PACKET_USED;
+ }
+
+ signal = string_to_char(signal_s);
+ string_free(signal_s);
+ if (signal == NULL) {
+ leave_function();
+ return SSH_PACKET_USED;
+ }
+
+ buffer_get_u8(session->in_buffer, &i);
+ if (i == 0) {
+ core = "";
+ }
+
+ ssh_log(session, SSH_LOG_PACKET,
+ "Remote connection closed by signal SIG %s %s", signal, core);
+ SAFE_FREE(signal);
+
+ leave_function();
+ return SSH_PACKET_USED;
+ }
+
+ /* TODO call message_handle since it handles channel requests as messages */
+ /* *but* reset buffer before !! */
+
+ session->in_buffer->pos = startpos;
+ message_handle(session, NULL, SSH2_MSG_CHANNEL_REQUEST, session->in_buffer);
+
+ ssh_log(session, SSH_LOG_PACKET, "Unknown request %s", request);
+ SAFE_FREE(request);
+
+ leave_function();
+ return SSH_PACKET_USED;
}
/*
@@ -575,22 +595,12 @@ void channel_handle(ssh_session session, int type){
switch(type) {
case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
- channel_rcv_change_window(session);
- break;
+ case SSH2_MSG_CHANNEL_REQUEST:
+ case SSH2_MSG_CHANNEL_CLOSE:
+ case SSH2_MSG_CHANNEL_EOF:
case SSH2_MSG_CHANNEL_DATA:
- channel_rcv_data(session,0);
- break;
case SSH2_MSG_CHANNEL_EXTENDED_DATA:
- channel_rcv_data(session,1);
- break;
- case SSH2_MSG_CHANNEL_EOF:
- channel_rcv_eof(session);
- break;
- case SSH2_MSG_CHANNEL_CLOSE:
- channel_rcv_close(session);
- break;
- case SSH2_MSG_CHANNEL_REQUEST:
- channel_rcv_request(session);
+ ssh_packet_process(session, type);
break;
default:
ssh_log(session, SSH_LOG_FUNCTIONS,