aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2013-10-20 12:21:58 +0200
committerAndreas Schneider <asn@cryptomilk.org>2013-10-20 12:46:57 +0200
commite30acdb58a86937e8bece57ce47e272f1106ca55 (patch)
tree8539fa42acbd231ba78fd8df8ff07d1d45bc83af
parentb0cbe88b0b680ae04281963f8a14248eaa2d183d (diff)
downloadlibssh-e30acdb58a86937e8bece57ce47e272f1106ca55.tar.gz
libssh-e30acdb58a86937e8bece57ce47e272f1106ca55.tar.xz
libssh-e30acdb58a86937e8bece57ce47e272f1106ca55.zip
channel: Reinit the buffer and reset the state on error.
BUG: https://red.libssh.org/issues/126
-rw-r--r--src/channels.c69
1 files changed, 46 insertions, 23 deletions
diff --git a/src/channels.c b/src/channels.c
index 14cfb5f8..a006ab36 100644
--- a/src/channels.c
+++ b/src/channels.c
@@ -2117,43 +2117,66 @@ static int ssh_global_request_termination(void *s){
static int global_request(ssh_session session, const char *request,
ssh_buffer buffer, int reply) {
ssh_string req = NULL;
- int rc = SSH_ERROR;
+ int rc;
- if(session->global_req_state != SSH_CHANNEL_REQ_STATE_NONE)
+ switch (session->global_req_state) {
+ case SSH_CHANNEL_REQ_STATE_NONE:
+ break;
+ default:
goto pending;
+ }
+
+ rc = buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST);
+ if (rc < 0) {
+ goto error;
+ }
+
req = ssh_string_from_char(request);
if (req == NULL) {
- ssh_set_error_oom(session);
- goto error;
+ ssh_set_error_oom(session);
+ rc = SSH_ERROR;
+ goto error;
}
- if (buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST) < 0 ||
- buffer_add_ssh_string(session->out_buffer, req) < 0 ||
- buffer_add_u8(session->out_buffer, reply == 0 ? 0 : 1) < 0) {
- ssh_set_error_oom(session);
- goto error;
- }
+ rc = buffer_add_ssh_string(session->out_buffer, req);
ssh_string_free(req);
- req=NULL;
+ if (rc < 0) {
+ ssh_set_error_oom(session);
+ rc = SSH_ERROR;
+ goto error;
+ }
- if (buffer != NULL) {
- if (buffer_add_data(session->out_buffer, buffer_get_rest(buffer),
- buffer_get_rest_len(buffer)) < 0) {
+ rc = buffer_add_u8(session->out_buffer, reply == 0 ? 0 : 1);
+ if (rc < 0) {
ssh_set_error_oom(session);
+ rc = SSH_ERROR;
goto error;
- }
}
+
+ if (buffer != NULL) {
+ rc = buffer_add_data(session->out_buffer,
+ buffer_get_rest(buffer),
+ buffer_get_rest_len(buffer));
+ if (rc < 0) {
+ ssh_set_error_oom(session);
+ rc = SSH_ERROR;
+ goto error;
+ }
+ }
+
session->global_req_state = SSH_CHANNEL_REQ_STATE_PENDING;
- if (packet_send(session) == SSH_ERROR) {
- return rc;
+ rc = packet_send(session);
+ if (rc == SSH_ERROR) {
+ return rc;
}
SSH_LOG(SSH_LOG_PACKET,
"Sent a SSH_MSG_GLOBAL_REQUEST %s", request);
+
if (reply == 0) {
- session->global_req_state=SSH_CHANNEL_REQ_STATE_NONE;
+ session->global_req_state = SSH_CHANNEL_REQ_STATE_NONE;
- return SSH_OK;
+ return SSH_OK;
}
pending:
rc = ssh_handle_packets_termination(session,
@@ -2178,16 +2201,16 @@ pending:
break;
case SSH_CHANNEL_REQ_STATE_ERROR:
case SSH_CHANNEL_REQ_STATE_NONE:
- rc=SSH_ERROR;
+ rc = SSH_ERROR;
break;
case SSH_CHANNEL_REQ_STATE_PENDING:
- rc=SSH_AGAIN;
- break;
+ return SSH_AGAIN;
}
+ session->global_req_state = SSH_CHANNEL_REQ_STATE_NONE;
return rc;
error:
- ssh_string_free(req);
+ buffer_reinit(session->out_buffer);
return rc;
}