diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2013-10-20 12:21:58 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2013-10-20 12:46:57 +0200 |
commit | e30acdb58a86937e8bece57ce47e272f1106ca55 (patch) | |
tree | 8539fa42acbd231ba78fd8df8ff07d1d45bc83af | |
parent | b0cbe88b0b680ae04281963f8a14248eaa2d183d (diff) | |
download | libssh-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.c | 69 |
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; } |