Change SSH version field to be &optional.

In 3769ed6c66 we added handling for SSH version 1.99 which unsed a SSH
version of 0 to indicate weird cases where no version could be
determined.

This patch is a fixup for that patch. Instead of using a magic version
of 0 we now use an `&optional` version value. If no SSH version can be
extracted the version will be unset; additionally a `conn_weird` event
will be raised.

Closes #1590.
This commit is contained in:
Benjamin Bannier 2021-06-16 09:01:19 +02:00
parent e6e30240ec
commit daa9537f92
3 changed files with 162 additions and 8 deletions

View file

@ -20,8 +20,12 @@ export {
uid: string &log;
## The connection's 4-tuple of endpoint addresses/ports.
id: conn_id &log;
## SSH major version (1 or 2)
version: count &log;
## SSH major version (1, 2, or unset). The version can be unset if the
## client and server version strings ## unset, malformed or incompatible
## so no common version can be extracted. If no version can be extracted
## even though both client and server versions are set a `conn_weird`
## event will be raised.
version: count &log &optional;
## Authentication result (T=success, F=failure, unset=unknown)
auth_success: bool &log &optional;
## The number of authentication attemps we observed. There's always
@ -155,9 +159,20 @@ function set_session(c: connection)
}
}
function set_version(c: connection, version: string)
function set_version(c: connection)
{
if ( c$ssh?$server && c$ssh?$client && |c$ssh$client| > 4 && |c$ssh$server| > 4 )
# We always either set the version field to a concrete value, or unset it.
delete c$ssh$version;
# If either the client or server string is unset we cannot compute a
# version and return early. We do not raise a weird in this case as we
# might arrive here while having only seen one side of the handshake.
const has_server = c$ssh?$server && |c$ssh$server| > 0;
const has_client = c$ssh?$client && |c$ssh$client| > 0;
if ( ! ( has_server && has_client ) )
return;
if ( |c$ssh$client| > 4 && |c$ssh$server| > 4 )
{
if ( c$ssh$client[4] == "1" && c$ssh$server[4] == "2" )
{
@ -166,7 +181,8 @@ function set_version(c: connection, version: string)
c$ssh$version = 2;
# SSH1 vs SSH2 -> Undefined
else
c$ssh$version = 0;
Reporter::conn_weird("SSH protocol version mismatch", c, fmt("%s vs %s", c$ssh$server, c$ssh$client));
return;
}
else if ( c$ssh$client[4] == "2" && c$ssh$server[4] == "1" )
{
@ -175,7 +191,8 @@ function set_version(c: connection, version: string)
c$ssh$version = 2;
else
# SSH2 vs SSH1 -> Undefined
c$ssh$version = 0;
Reporter::conn_weird("SSH protocol version mismatch", c, fmt("%s vs %s", c$ssh$server, c$ssh$client));
return;
}
else if ( c$ssh$client[4] == "1" && c$ssh$server[4] == "1" )
{
@ -199,21 +216,25 @@ function set_version(c: connection, version: string)
{
c$ssh$version = 2;
}
return;
}
Reporter::conn_weird("cannot determine SSH protocol version used", c, fmt("%s vs %s", c$ssh$server, c$ssh$client));
}
event ssh_server_version(c: connection, version: string)
{
set_session(c);
c$ssh$server = version;
set_version(c, version);
set_version(c);
}
event ssh_client_version(c: connection, version: string)
{
set_session(c);
c$ssh$client = version;
set_version(c, version);
set_version(c);
}
event ssh_auth_attempted(c: connection, authenticated: bool) &priority=5