zeek/src/analyzer/protocol/socks/socks-protocol.pac
Jon Siwek 961fd06cad Refactor SOCKS5 user/pass authentication support.
- Rename event "socks_login_userpass" to "socks_login_userpass_request"
- Rename event "socks_login_reply" to "socks_login_userpass_reply"
- Split unsupported authN weird into 2 types: method vs. version

Addresses BIT-1011
2015-02-12 17:06:38 -06:00

205 lines
5.1 KiB
JavaScript

type SOCKS_Message(is_orig: bool) = case $context.connection.v5_in_auth_sub_negotiation() of {
true -> auth: SOCKS5_Auth_Message(is_orig);
false -> msg: SOCKS_Version(is_orig);
};
type SOCKS_Version(is_orig: bool) = record {
version: uint8;
msg: case version of {
4 -> socks4_msg: SOCKS4_Message(is_orig);
5 -> socks5_msg: SOCKS5_Message(is_orig);
default -> socks_msg_fail: SOCKS_Version_Error(version);
};
};
type SOCKS_Version_Error(version: uint8) = record {
nothing: empty;
};
# SOCKS5 Implementation
type SOCKS5_Message(is_orig: bool) = case $context.connection.v5_past_authentication() of {
false -> auth: SOCKS5_Auth_Negotiation(is_orig);
true -> msg: SOCKS5_Real_Message(is_orig);
};
type SOCKS5_Auth_Negotiation(is_orig: bool) = case is_orig of {
true -> req: SOCKS5_Auth_Negotiation_Request;
false -> rep: SOCKS5_Auth_Negotiation_Reply;
};
type SOCKS5_Auth_Negotiation_Request = record {
method_count: uint8;
methods: uint8[method_count];
};
type SOCKS5_Auth_Negotiation_Reply = record {
selected_auth_method: uint8;
} &let {
in_auth_sub_neg = $context.connection.set_v5_in_auth_sub_negotiation(selected_auth_method == 0 || selected_auth_method == 0xff ? false : true);
past_auth = $context.connection.set_v5_past_authentication();
set_auth = $context.connection.set_v5_auth_method(selected_auth_method);
};
type SOCKS5_Auth_Message(is_orig: bool) = case is_orig of {
true -> req: SOCKS5_Auth_Request;
false -> rep: SOCKS5_Auth_Reply;
};
type SOCKS5_Auth_Request = case $context.connection.v5_auth_method() of {
0x02 -> userpass : SOCKS5_Auth_Request_UserPass;
default -> unsupported : SOCKS5_Unsupported_Authentication_Method;
};
type SOCKS5_Unsupported_Authentication_Method = record {
crap: bytestring &restofdata;
};
type SOCKS5_Unsupported_Authentication_Version(version: uint8) = record {
crap: bytestring &restofdata;
};
type SOCKS5_Auth_Request_UserPass = record {
version: uint8;
msg: case version of {
1 -> v1: SOCKS5_Auth_Request_UserPass_v1;
default -> unsupported: SOCKS5_Unsupported_Authentication_Version(version);
};
};
type SOCKS5_Auth_Request_UserPass_v1 = record {
ulen : uint8;
username : bytestring &length=ulen;
plen : uint8;
password : bytestring &length=plen;
};
type SOCKS5_Auth_Reply = case $context.connection.v5_auth_method() of {
0x02 -> userpass : SOCKS5_Auth_Reply_UserPass;
default -> unsupported : SOCKS5_Unsupported_Authentication_Method;
} &let {
in_auth_sub_neg = $context.connection.set_v5_in_auth_sub_negotiation(false);
};
type SOCKS5_Auth_Reply_UserPass = record {
version: uint8;
msg: case version of {
1 -> v1: SOCKS5_Auth_Reply_UserPass_v1;
default -> unsupported: SOCKS5_Unsupported_Authentication_Version(version);
};
};
type SOCKS5_Auth_Reply_UserPass_v1 = record {
code : uint8;
};
type SOCKS5_Real_Message(is_orig: bool) = case is_orig of {
true -> request: SOCKS5_Request;
false -> reply: SOCKS5_Reply;
};
type Domain_Name = record {
len: uint8;
name: bytestring &length=len;
} &byteorder = bigendian;
type SOCKS5_Address = record {
addr_type: uint8;
addr: case addr_type of {
1 -> ipv4: uint32;
3 -> domain_name: Domain_Name;
4 -> ipv6: uint32[4];
default -> err: bytestring &restofdata &transient;
};
} &byteorder = bigendian;
type SOCKS5_Request = record {
command : uint8;
reserved : uint8;
remote_name : SOCKS5_Address;
port : uint16;
} &byteorder = bigendian;
type SOCKS5_Reply = record {
reply: uint8;
reserved: uint8;
bound: SOCKS5_Address;
port: uint16;
} &byteorder = bigendian;
# SOCKS4 Implementation
type SOCKS4_Message(is_orig: bool) = case is_orig of {
true -> request: SOCKS4_Request;
false -> reply: SOCKS4_Reply;
};
type SOCKS4_Request = record {
command: uint8;
port: uint16;
addr: uint32;
user: uint8[] &until($element == 0);
host: case v4a of {
true -> name: uint8[] &until($element == 0); # v4a
false -> empty: uint8[] &length=0;
} &requires(v4a);
} &byteorder = bigendian &let {
v4a: bool = (addr <= 0x000000ff);
};
type SOCKS4_Reply = record {
zero: uint8;
status: uint8;
port: uint16;
addr: uint32;
} &byteorder = bigendian;
refine connection SOCKS_Conn += {
%member{
bool v5_in_auth_sub_negotiation_;
bool v5_authenticated_;
uint8 selected_auth_method_;
%}
%init{
v5_in_auth_sub_negotiation_ = false;
v5_authenticated_ = false;
selected_auth_method_ = 255;
%}
function v5_in_auth_sub_negotiation(): bool
%{
return v5_in_auth_sub_negotiation_;
%}
function set_v5_in_auth_sub_negotiation(b: bool): bool
%{
v5_in_auth_sub_negotiation_ = b;
return true;
%}
function v5_past_authentication(): bool
%{
return v5_authenticated_;
%}
function set_v5_past_authentication(): bool
%{
v5_authenticated_ = true;
return true;
%}
function set_v5_auth_method(method: uint8): bool
%{
selected_auth_method_ = method;
return true;
%}
function v5_auth_method(): uint8
%{
return selected_auth_method_;
%}
};