1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-10-31 23:30:25 +03:00

channel: Detect bad usage of libssh2_channel_process_startup

A common novice programmer error (at least among those using the
wrapping Perl module Net::SSH2), is to try to reuse channels.

This patchs detects that incorrect usage and fails with a
LIBSSH2_ERROR_BAD_USE error instead of hanging.

Signed-off-by: Salvador Fandino <sfandino-/E1597aS9LQAvxtiuMwx3w@public.gmane.org>
This commit is contained in:
Salvador Fandino
2015-08-26 14:21:44 +02:00
committed by Daniel Stenberg
parent fc4a969a05
commit fb432f3f78
2 changed files with 10 additions and 4 deletions

View File

@@ -1252,6 +1252,11 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
{ SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
int rc; int rc;
if (channel->process_state == libssh2_NB_state_end) {
return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
"Channel can not be reused");
}
if (channel->process_state == libssh2_NB_state_idle) { if (channel->process_state == libssh2_NB_state_idle) {
/* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */ /* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */
channel->process_packet_len = request_len + 10; channel->process_packet_len = request_len + 10;
@@ -1298,7 +1303,7 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
else if (rc) { else if (rc) {
LIBSSH2_FREE(session, channel->process_packet); LIBSSH2_FREE(session, channel->process_packet);
channel->process_packet = NULL; channel->process_packet = NULL;
channel->process_state = libssh2_NB_state_idle; channel->process_state = libssh2_NB_state_end;
return _libssh2_error(session, rc, return _libssh2_error(session, rc,
"Unable to send channel request"); "Unable to send channel request");
} }
@@ -1320,14 +1325,14 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
if (rc == LIBSSH2_ERROR_EAGAIN) { if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc) { } else if (rc) {
channel->process_state = libssh2_NB_state_idle; channel->process_state = libssh2_NB_state_end;
return _libssh2_error(session, rc, return _libssh2_error(session, rc,
"Failed waiting for channel success"); "Failed waiting for channel success");
} }
code = data[0]; code = data[0];
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
channel->process_state = libssh2_NB_state_idle; channel->process_state = libssh2_NB_state_end;
if (code == SSH_MSG_CHANNEL_SUCCESS) if (code == SSH_MSG_CHANNEL_SUCCESS)
return 0; return 0;

View File

@@ -216,7 +216,8 @@ typedef enum
libssh2_NB_state_jump2, libssh2_NB_state_jump2,
libssh2_NB_state_jump3, libssh2_NB_state_jump3,
libssh2_NB_state_jump4, libssh2_NB_state_jump4,
libssh2_NB_state_jump5 libssh2_NB_state_jump5,
libssh2_NB_state_end
} libssh2_nonblocking_states; } libssh2_nonblocking_states;
typedef struct packet_require_state_t typedef struct packet_require_state_t