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) { diff --git a/tests/unittests/torture_packet_filter.c b/tests/unittests/torture_packet_filter.c index 85fb5c1b..ffa49602 100644 --- a/tests/unittests/torture_packet_filter.c +++ b/tests/unittests/torture_packet_filter.c @@ -517,12 +517,108 @@ static void torture_packet_filter_check_channel_open(void **state) assert_int_equal(rc, 0); } +static void torture_packet_filter_check_channel_success(void **state) +{ + int rc; + + /* The only condition to accept a CHANNEL_SUCCESS is to be authenticated */ + global_state accepted[] = { + { + .flags = COMPARE_SESSION_STATE, + .session = SSH_SESSION_STATE_AUTHENTICATED, + } + }; + + int accepted_count = 1; + + /* Unused */ + (void) state; + + rc = check_message_in_all_states(accepted, accepted_count, + SSH2_MSG_CHANNEL_SUCCESS); + + assert_int_equal(rc, 0); +} + +static void torture_packet_filter_check_channel_failure(void **state) +{ + int rc; + + /* The only condition to accept a CHANNEL_FAILURE is to be authenticated */ + global_state accepted[] = { + { + .flags = COMPARE_SESSION_STATE, + .session = SSH_SESSION_STATE_AUTHENTICATED, + } + }; + + int accepted_count = 1; + + /* Unused */ + (void) state; + + rc = check_message_in_all_states(accepted, accepted_count, + SSH2_MSG_CHANNEL_FAILURE); + + assert_int_equal(rc, 0); +} + +static void torture_packet_filter_check_request_success(void **state) +{ + int rc; + + /* The only condition to accept a REQUEST_SUCCESS is to be authenticated */ + global_state accepted[] = { + { + .flags = COMPARE_SESSION_STATE, + .session = SSH_SESSION_STATE_AUTHENTICATED, + } + }; + + int accepted_count = 1; + + /* Unused */ + (void) state; + + rc = check_message_in_all_states(accepted, accepted_count, + SSH2_MSG_REQUEST_SUCCESS); + + assert_int_equal(rc, 0); +} + +static void torture_packet_filter_check_request_failure(void **state) +{ + int rc; + + /* The only condition to accept a REQUEST_FAILURE is to be authenticated */ + global_state accepted[] = { + { + .flags = COMPARE_SESSION_STATE, + .session = SSH_SESSION_STATE_AUTHENTICATED, + } + }; + + int accepted_count = 1; + + /* Unused */ + (void) state; + + rc = check_message_in_all_states(accepted, accepted_count, + SSH2_MSG_REQUEST_FAILURE); + + assert_int_equal(rc, 0); +} + int torture_run_tests(void) { int rc; struct CMUnitTest tests[] = { cmocka_unit_test(torture_packet_filter_check_auth_success), cmocka_unit_test(torture_packet_filter_check_channel_open), + cmocka_unit_test(torture_packet_filter_check_channel_success), + cmocka_unit_test(torture_packet_filter_check_channel_failure), + cmocka_unit_test(torture_packet_filter_check_request_success), + cmocka_unit_test(torture_packet_filter_check_request_failure), cmocka_unit_test(torture_packet_filter_check_unfiltered), cmocka_unit_test(torture_packet_filter_check_msg_ext_info) };