packet: Implement missing packet filter for DH GEX

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Jakub Jelen
2025-05-16 19:09:30 +02:00
committed by Andreas Schneider
parent a9d8a3d448
commit 160fc7df10

View File

@@ -366,7 +366,7 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
* - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
* */
if (!session->server) {
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
@@ -389,6 +389,8 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
// SSH2_MSG_ECMQV_REPLY: // 31
// SSH2_MSG_KEX_DH_GEX_GROUP: // 31
/* Client only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
@@ -399,6 +401,11 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
* - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->server) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
@@ -413,15 +420,98 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_INIT: // 32
/* TODO Not filtered */
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_GROUP_SENT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_GROUP_SENT
* then calls ssh_packet_server_dhgex_init which triggers:
* - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
/* Only allowed if dh_handshake_state is in initial state */
if (session->dh_handshake_state != DH_STATE_GROUP_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_REPLY: // 33
/* TODO Not filtered */
/* Client only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_INIT_SENT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->server) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_INIT_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_REQUEST: // 34
/* TODO Not filtered */
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_INIT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_INIT_SENT
* then calls ssh_packet_server_dhgex_request which triggers:
* - session->dh_handshake_state = DH_STATE_GROUP_SENT
* */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
/* Only allowed if dh_handshake_state is in initial state */
if (session->dh_handshake_state != DH_STATE_INIT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_REQUEST: // 50