diff options
author | Dirkjan Bussink <d.bussink@gmail.com> | 2020-12-10 13:20:34 +0000 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2020-12-11 13:29:46 +0100 |
commit | f6a2f6190c2aa047d901547720ae6d1729e1e2c0 (patch) | |
tree | 760e9a91c992ee55f49adb79dbecce07ccc2f559 /src | |
parent | 3c33c3945523a9d07c541c77017ac2639305e13a (diff) | |
download | libssh-f6a2f6190c2aa047d901547720ae6d1729e1e2c0.tar.gz libssh-f6a2f6190c2aa047d901547720ae6d1729e1e2c0.tar.xz libssh-f6a2f6190c2aa047d901547720ae6d1729e1e2c0.zip |
Ignore request success and failure message if they are not expected
In https://gitlab.com/libssh/libssh-mirror/-/merge_requests/145#note_463232084
behavior in libssh was identified where it diverges from how for example
OpenSSH behaves. In OpenSSH if a request success of failure message is
received, apart from it being treated as a keepalive message, it is
ignored otherwise.
Libssh does handle the unexpected message and triggers an error
condition internally. This means that with the Dropbear behavior where
it replies to a hostkeys-00@openssh.com message even with a want_reply
= 0 (arguably a bug), libssh enters an error state.
This change makes the libssh behavior match OpenSSH to ignore these
messages. The spec is a bit unclear on whether Dropbear is buggy here or
not, but let's be liberal with the input accepted here in libssh.
Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/packet.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/src/packet.c b/src/packet.c index f14731c9..2d376620 100644 --- a/src/packet.c +++ b/src/packet.c @@ -688,10 +688,12 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se /* * States required: * - session_state == SSH_SESSION_STATE_AUTHENTICATED - * - session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING * * Transitions: - * - session->global_req_state == SSH_CHANNEL_REQ_STATE_ACCEPTED + * - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING + * - To channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED + * + * If not in a pending state, message is ignored in the callback handler. * */ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { @@ -699,21 +701,18 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se break; } - if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING) { - rc = SSH_PACKET_DENIED; - break; - } - rc = SSH_PACKET_ALLOWED; break; case SSH2_MSG_REQUEST_FAILURE: // 82 /* * States required: * - session_state == SSH_SESSION_STATE_AUTHENTICATED - * - session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING * * Transitions: - * - session->global_req_state == SSH_CHANNEL_REQ_STATE_DENIED + * - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING + * - To channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED + * + * If not in a pending state, message is ignored in the callback handler. * */ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { @@ -721,11 +720,6 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se break; } - if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING) { - rc = SSH_PACKET_DENIED; - break; - } - rc = SSH_PACKET_ALLOWED; break; case SSH2_MSG_CHANNEL_OPEN: // 90 @@ -878,10 +872,12 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se /* * States required: * - session_state == SSH_SESSION_STATE_AUTHENTICATED - * - channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING * * Transitions: - * - channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED + * - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING + * - To channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED + * + * If not in a pending state, message is ignored in the callback handler. * */ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { @@ -895,10 +891,12 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se /* * States required: * - session_state == SSH_SESSION_STATE_AUTHENTICATED - * - channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING * * Transitions: - * - channel->request_state = SSH_CHANNEL_REQ_STATE_DENIED + * - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING + * - To channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED + * + * If not in a pending state, message is ignored in the callback handler. * */ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { |