Basic RADIUS functionality implemented.

This commit is contained in:
Vlad Grigorescu 2013-12-10 22:09:16 -05:00
parent ccd8b15d52
commit f3c0d17541
7 changed files with 140 additions and 429 deletions

View file

@ -2762,6 +2762,23 @@ export {
name: string &optional;
} &log;
}
module RADIUS;
export {
type RADIUS::AttributeList: vector of string;
type RADIUS::Attributes: table[count] of RADIUS::AttributeList;
type RADIUS::Message: record {
## The type of message (Access-Request, Access-Accept, etc.)
code : count;
## The transaction ID
trans_id : count;
## The "authenticator" string
authenticator : string;
## Any attributes
attributes : RADIUS::Attributes &optional;
};
}
module GLOBAL;
@load base/bif/event.bif

View file

@ -1,3 +1,2 @@
# Generated by binpac_quickstart
@load ./main
#@load-sigs ./dpd.sig

View file

@ -229,309 +229,3 @@ const framed_protocol_types: table[count] of string = {
[6] = "X.75 Synchronous"
} &default=function(i: count): string { return fmt("unknown-%d", i); };
const vendor_9_types: table[count] of string = {
[1] = "Cisco-AVPair",
[2] = "Cisco-NAS-Port",
[3] = "Cisco-Fax-Account-Id-Origin",
[4] = "Cisco-Fax-Msg-Id",
[5] = "Cisco-Fax-Pages",
[6] = "Cisco-Fax-Coverpage-Flag",
[7] = "Cisco-Fax-Modem-Time",
[8] = "Cisco-Fax-Connect-Speed",
[9] = "Cisco-Fax-Recipient-Count",
[10] = "Cisco-Fax-Process-Abort-Flag",
[11] = "Cisco-Fax-Dsn-Address",
[12] = "Cisco-Fax-Dsn-Flag",
[13] = "Cisco-Fax-Mdn-Address",
[14] = "Cisco-Fax-Mdn-Flag",
[15] = "Cisco-Fax-Auth-Status",
[16] = "Cisco-Email-Server-Address",
[17] = "Cisco-Email-Server-Ack-Flag",
[18] = "Cisco-Gateway-Id",
[19] = "Cisco-Call-Type",
[20] = "Cisco-Port-Used",
[21] = "Cisco-Abort-Cause",
[23] = "Cisco-h323-remote-address",
[24] = "Cisco-h323-conf-id",
[25] = "Cisco-h323-setup-time",
[26] = "Cisco-h323-call-origin",
[27] = "Cisco-h323-call-type",
[28] = "Cisco-h323-connect-time",
[29] = "Cisco-h323-disconnect-time",
[30] = "Cisco-h323-disconnect-cause",
[31] = "Cisco-h323-voice-quality",
[33] = "Cisco-h323-gw-id",
[35] = "Cisco-h323-incoming-conn-id",
[37] = "Cisco-Policy-Up",
[38] = "Cisco-Policy-Down",
[100] = "Cisco-sip-conf-id",
[101] = "Cisco-h323-credit-amount",
[102] = "Cisco-h323-credit-time",
[103] = "Cisco-h323-return-code",
[104] = "Cisco-h323-prompt-id",
[105] = "Cisco-h323-day-and-time",
[106] = "Cisco-h323-redirect-number",
[107] = "Cisco-h323-preferred-lang",
[108] = "Cisco-h323-redirect-ip-addr",
[109] = "Cisco-h323-billing-model",
[110] = "Cisco-h323-currency",
[111] = "Cisco-subscriber",
[112] = "Cisco-gw-rxd-cdn",
[113] = "Cisco-gw-final-xlated-cdn",
[114] = "Cisco-remote-media-address",
[115] = "Cisco-release-source",
[116] = "Cisco-gw-rxd-cgn",
[117] = "Cisco-gw-final-xlated-cgn",
[141] = "Cisco-call-id",
[142] = "Cisco-session-protocol",
[143] = "Cisco-method",
[144] = "Cisco-prev-hop-via",
[145] = "Cisco-prev-hop-ip",
[146] = "Cisco-incoming-req-uri",
[147] = "Cisco-outgoing-req-uri",
[148] = "Cisco-next-hop-ip",
[149] = "Cisco-next-hop-dn",
[150] = "Cisco-sip-hdr",
[187] = "Cisco-Multilink-ID",
[188] = "Cisco-Num-In-Multilink",
[190] = "Cisco-Pre-Input-Octets",
[191] = "Cisco-Pre-Output-Octets",
[192] = "Cisco-Pre-Input-Packets",
[193] = "Cisco-Pre-Output-Packets",
[194] = "Cisco-Maximum-Time",
[195] = "Cisco-Disconnect-Cause",
[197] = "Cisco-Data-Rate",
[198] = "Cisco-PreSession-Time",
[208] = "Cisco-PW-Lifetime",
[209] = "Cisco-IP-Direct",
[210] = "Cisco-PPP-VJ-Slot-Comp",
[212] = "Cisco-PPP-Async-Map",
[217] = "Cisco-IP-Pool-Definition",
[218] = "Cisco-Assign-IP-Pool",
[228] = "Cisco-Route-IP",
[233] = "Cisco-Link-Compression",
[234] = "Cisco-Target-Util",
[235] = "Cisco-Maximum-Channels",
[242] = "Cisco-Data-Filter",
[243] = "Cisco-Call-Filter",
[244] = "Cisco-Idle-Limit",
[249] = "Cisco-Subscriber-Password",
[250] = "Cisco-Account-Info",
[251] = "Cisco-Service-Info",
[252] = "Cisco-Command-Code",
[253] = "Cisco-Xmit-Rate"
} &default=function(i: count): string { return fmt("Cisco-unknown-%d", i); };
const vendor_255_types: table[count] of string = {
[1] = "CVPN5000-Tunnel-Throughput",
[2] = "CVPN5000-Client-Assigned-IP",
[3] = "CVPN5000-Client-Real-IP",
[4] = "CVPN5000-VPN-GroupInfo",
[5] = "CVPN5000-VPN-Password",
[6] = "CVPN5000-Echo",
[7] = "CVPN5000-Client-Assigned-IPX"
} &default=function(i: count): string { return fmt("CVPN5000-unknown-%d", i); };
const vendor_311_types: table[count] of string = {
[1] = "MS-CHAP-Response",
[2] = "MS-CHAP-Error",
[3] = "MS-CHAP-CPW-1",
[4] = "MS-CHAP-CPW-2",
[5] = "MS-CHAP-LM-Enc-PW",
[6] = "MS-CHAP-NT-Enc-PW",
[7] = "MS-MPPE-Encryption-Policy",
[8] = "MS-MPPE-Encryption-Types",
[9] = "MS-RAS-Vendor",
[10] = "MS-CHAP-Domain",
[11] = "MS-CHAP-Challenge",
[12] = "MS-CHAP-MPPE-Keys",
[13] = "MS-BAP-Usage",
[14] = "MS-Link-Utilization-Threshold",
[15] = "MS-Link-Drop-Time-Limit",
[16] = "MS-MPPE-Send-Key",
[17] = "MS-MPPE-Recv-Key",
[18] = "MS-RAS-Version",
[19] = "MS-Old-ARAP-Password",
[20] = "MS-New-ARAP-Password",
[21] = "MS-ARAP-PW-Change-Reason",
[22] = "MS-Filter",
[23] = "MS-Acct-Auth-Type",
[24] = "MS-Acct-EAP-Type",
[25] = "MS-CHAP2-Response",
[26] = "MS-CHAP2-Success",
[27] = "MS-CHAP2-CPW",
[28] = "MS-Primary-DNS-Server",
[29] = "MS-Secondary-DNS-Server",
[30] = "MS-Primary-NBNS-Server",
[31] = "MS-Secondary-NBNS-Server",
[34] = "MS-RAS-Client-Name",
[35] = "MS-RAS-Client-Version",
[36] = "MS-Quarantine-IPFilter",
[37] = "MS-Quarantine-Session-Timeout",
[40] = "MS-User-Security-Identity",
[41] = "MS-Identity-Type",
[42] = "MS-Service-Class",
[44] = "MS-Quarantine-User-Class",
[45] = "MS-Quarantine-State",
[46] = "MS-Quarantine-Grace-Time",
[47] = "MS-Network-Access-Server-Type",
[48] = "MS-AFW-Zone",
[49] = "MS-AFW-Protection-Level",
[50] = "MS-Machine-Name",
[51] = "MS-IPv6-Filter",
[52] = "MS-IPv4-Remediation-Servers",
[53] = "MS-IPv6-Remediation-Servers",
[54] = "MS-RNAP-Not-Quarantine-Capable",
[55] = "MS-Quarantine-SOH",
[56] = "MS-RAS-Correlation",
[57] = "MS-Extended-Quarantine-State",
[58] = "MS-HCAP-User-Groups",
[59] = "MS-HCAP-Location-Group-Name",
[60] = "MS-HCAP-User-Name",
[61] = "MS-User-IPv4-Address",
[62] = "MS-User-IPv6-Address",
[63] = "MS-TSG-Device-Redirection"
} &default=function(i: count): string { return fmt("MS-unknown-%d", i); };
const vendor_3076_types: table[count] of string = {
[1] = "CVPN3000-Access-Hours",
[2] = "CVPN3000-Simultaneous-Logins",
[3] = "CVPN3000-Min-Password-Length",
[4] = "CVPN3000-Allow-Alpha-Only-Passwords",
[5] = "CVPN3000-Primary-DNS",
[6] = "CVPN3000-Secondary-DNS",
[7] = "CVPN3000-Primary-WINS",
[8] = "CVPN3000-Secondary-WINS",
[9] = "CVPN3000-SEP-Card-Assignment",
[10] = "CVPN3000-Priority-On-SEP",
[11] = "CVPN3000-Tunneling-Protocols",
[12] = "CVPN3000-IPSec-Sec-Association",
[13] = "CVPN3000-IPSec-Authentication",
[15] = "CVPN3000-IPSec-Banner1",
[16] = "CVPN3000-IPSec-Allow-Passwd-Store",
[17] = "CVPN3000-Use-Client-Address",
[18] = "CVPN3000-PPTP-Min-Auth-Protocol",
[19] = "CVPN3000-L2TP-Min-Auth-Protocol",
[20] = "CVPN3000-PPTP-Encryption",
[21] = "CVPN3000-L2TP-Encryption",
[22] = "CVPN3000-Auth-Server-Type",
[23] = "CVPN3000-Auth-Server-Password",
[24] = "CVPN3000-Request-Auth-Vector",
[25] = "CVPN3000-IPSec-LTL-Keepalives",
[26] = "CVPN3000-IPSec-Group-Name",
[27] = "CVPN3000-IPSec-Split-Tunnel-List",
[28] = "CVPN3000-IPSec-Default-Domain",
[29] = "CVPN3000-IPSec-Split-DNS-Names",
[30] = "CVPN3000-IPSec-Tunnel-Type",
[31] = "CVPN3000-IPSec-Mode-Config",
[32] = "CVPN3000-Auth-Server-Priority",
[33] = "CVPN3000-IPSec-User-Group-Lock",
[34] = "CVPN3000-IPSec-Over-UDP",
[35] = "CVPN3000-IPSec-Over-UDP-Port",
[36] = "CVPN3000-IPSec-Banner2",
[37] = "CVPN3000-PPTP-MPPC-Compression",
[38] = "CVPN3000-L2TP-MPPC-Compression",
[39] = "CVPN3000-IPSec-IP-Compression",
[40] = "CVPN3000-IPSec-IKE-Peer-ID-Check",
[41] = "CVPN3000-IKE-Keep-Alives",
[42] = "CVPN3000-IPSec-Auth-On-Rekey",
[45] = "CVPN3000-Reqrd-Client-Fw-Vendor-Code",
[46] = "CVPN3000-Reqrd-Client-Fw-Product-Code",
[47] = "CVPN3000-Reqrd-Client-Fw-Description",
[48] = "CVPN3000-Require-HW-Client-Auth",
[49] = "CVPN3000-Require-Individual-User-Auth",
[50] = "CVPN3000-Authd-User-Idle-Timeout",
[51] = "CVPN3000-Cisco-IP-Phone-Bypass",
[52] = "CVPN3000-User-Auth-Server-Name",
[53] = "CVPN3000-User-Auth-Server-Port",
[54] = "CVPN3000-User-Auth-Server-Secret",
[55] = "CVPN3000-IPSec-Split-Tunneling-Policy",
[56] = "CVPN3000-IPSec-Reqrd-Client-Fw-Cap",
[57] = "CVPN3000-IPSec-Client-Fw-Filter-Name",
[58] = "CVPN3000-IPSec-Client-Fw-Filter-Opt",
[59] = "CVPN3000-IPSec-Backup-Servers",
[60] = "CVPN3000-IPSec-Backup-Server-List",
[61] = "CVPN3000-DHCP-Network-Scope",
[62] = "CVPN3000-MS-Client-Icpt-DHCP-Conf-Msg",
[63] = "CVPN3000-MS-Client-Subnet-Mask",
[64] = "CVPN3000-Allow-Network-Extension-Mode",
[65] = "CVPN3000-IPSec-Authorization-Type",
[66] = "CVPN3000-IPSec-Authorization-Required",
[67] = "CVPN3000-IPSec-DN-Field",
[68] = "CVPN3000-IPSec-Confidence-Level",
[69] = "CVPN3000-WebVPN-Content-Filter",
[70] = "CVPN3000-WebVPN-Enable-functions",
[74] = "CVPN3000-WebVPN-Exchange-Addr",
[75] = "CVPN3000-LEAP-Bypass",
[78] = "CVPN3000-WebVPN-Exchange-NETBIOS-name",
[79] = "CVPN3000-Port-Forwarding-Name",
[80] = "CVPN3000-IE-Proxy-Server",
[81] = "CVPN3000-IE-Proxy-Server-Policy",
[82] = "CVPN3000-IE-Proxy-Exception-List",
[83] = "CVPN3000-IE-Proxy-Bypass-Local",
[84] = "CVPN3000-IKE-Keepalive-Retry-Interval",
[88] = "CVPN3000-Perfect-Forward-Secrecy-Enable",
[89] = "CVPN3000-NAC-Enable",
[90] = "CVPN3000-NAC-Status-Query-Timer",
[91] = "CVPN3000-NAC-Revalidation-Timer",
[92] = "CVPN3000-NAC-Default-ACL",
[93] = "CVPN3000-WebVPN-URL-Entry-Enable",
[94] = "CVPN3000-WebVPN-File-Access-Enable",
[95] = "CVPN3000-WebVPN-File-Svr-Entry-Enable",
[96] = "CVPN3000-WebVPN-File-Svr-Brwsing-Enable",
[97] = "CVPN3000-WebVPN-Port-Forwarding-Enable",
[98] = "CVPN3000-WebVPN-Outlook-Exch-Proxy-Enb",
[99] = "CVPN3000-WebVPN-Port-Fwding-HTTP-Proxy",
[100] = "CVPN3000-WebVPN-Auto-Applet-Downld-Enb",
[101] = "CVPN3000-WebVPN-Citrix-Metaframe-Enable",
[102] = "CVPN3000-WebVPN-Apply-ACL",
[103] = "CVPN3000-WebVPN-SSL-VPN-Client-Enable",
[104] = "CVPN3000-WebVPN-SSL-VPN-Client-Required",
[105] = "CVPN3000-WebVPN-SSL-VPN-Client-Keep-Ins",
[128] = "CVPN3000-Partition-Primary-DHCP",
[129] = "CVPN3000-Partition-Secondary-DHCP",
[131] = "CVPN3000-Partition-Premise-Router",
[132] = "CVPN3000-Partition-Max-Sessions",
[133] = "CVPN3000-Partition-Mobile-IP-Key",
[134] = "CVPN3000-Partition-Mobile-IP-Address",
[135] = "CVPN3000-Partition-Mobile-IP-SPI",
[136] = "CVPN3000-Strip-Realm",
[137] = "CVPN3000-Group-Name"
} &default=function(i: count): string { return fmt("CPNV3000-unknown-%d", i); };
const vendor_14823_types: table[count] of string = {
[1] = "Aruba-User-Role",
[2] = "Aruba-User-Vlan",
[3] = "Aruba-Priv-Admin-User",
[4] = "Aruba-Admin-Role",
[5] = "Aruba-Essid-Name",
[6] = "Aruba-Location-Id",
[7] = "Aruba-Port-Identifier",
[8] = "Aruba-MMS-User-Template",
[9] = "Aruba-Named-User-Vlan",
[10] = "Aruba-AP-Group",
[11] = "Aruba-Framed-IPv6-Address",
[12] = "Aruba-Device-Type",
[13] = "Aruba-AP-Name",
[14] = "Aruba-No-DHCP-Fingerprint",
[15] = "Aruba-Mdps-Device-Udid",
[16] = "Aruba-Mdps-Device-Imei",
[17] = "Aruba-Mdps-Device-Iccid",
[18] = "Aruba-Mdps-Max-Devices",
[19] = "Aruba-Mdps-Device-Name",
[20] = "Aruba-Mdps-Device-Product",
[21] = "Aruba-Mdps-Device-Version",
[22] = "Aruba-Mdps-Device-Serial",
[23] = "Aruba-CPPM-Role",
[24] = "Aruba-AirGroup-User-Name",
[25] = "Aruba-AirGroup-Shared-User",
[26] = "Aruba-AirGroup-Shared-Role",
[27] = "Aruba-AirGroup-Device-Type",
[28] = "Aruba-Auth-Survivability",
[29] = "Aruba-AS-User-Name",
[30] = "Aruba-AS-Credential-Hash",
[31] = "Aruba-WorkSpace-App-Name",
[32] = "Aruba-Mdps-Provisioning-Settings",
[33] = "Aruba-Mdps-Device-Profile"
} &default=function(i: count): string { return fmt("Aruba-unknown-%d", i); };

View file

@ -1,7 +0,0 @@
# Generated by binpac_quickstart
signature dpd_radius {
ip-proto == udp
# TODO: payload /^RADIUS/
enable "radius"
}

View file

@ -11,19 +11,51 @@ export {
type Info: record {
## Timestamp for when the event happened.
ts: time &log;
ts : time &log;
## Unique ID for the connection.
uid: string &log;
uid : string &log;
## The connection's 4-tuple of endpoint addresses/ports.
id: conn_id &log;
msg_type: string &log;
id : conn_id &log;
## The username, if present
username : string &log &optional;
## MAC address, if present
mac : string &log &optional;
## Remote IP address, if present
remote_ip : addr &log &optional;
## Connect info, if present
connect_info : string &log &optional;
## Successful or failed authentication
result : string &log &optional;
## Whether this has already been logged and can be ignored
logged : bool &optional;
};
## The amount of time we wait for an authentication response before
## expiring it.
const expiration_interval = 10secs &redef;
## Logs an authentication attempt if we didn't see a response in time
##
## t: A table of Info records.
##
## idx: The index of the connection$radius table corresponding to the
## radius authentication about to expire.
##
## Returns: 0secs, which when this function is used as an
## :bro:attr:`&expire_func`, indicates to remove the element at
## *idx* immediately.
global expire: function(t: table[count] of Info, idx: count): interval;
## Event that can be handled to access the RADIUS record as it is sent on
## to the loggin framework.
global log_radius: event(rec: Info);
}
redef record connection += {
radius: table[count] of Info &optional &write_expire=expiration_interval &expire_func=expire;
};
const ports = { 1812/udp };
event bro_init() &priority=5
@ -32,111 +64,57 @@ event bro_init() &priority=5
Analyzer::register_for_ports(Analyzer::ANALYZER_RADIUS, ports);
}
event radius_message(c: connection, msg_type: count, trans_id: count)
event radius_message(c: connection, result: RADIUS::Message)
{
local info: Info;
info$ts = network_time();
info$uid = c$uid;
info$id = c$id;
info$msg_type = msg_types[msg_type];
Log::write(RADIUS::LOG, info);
}
event radius_attribute(c: connection, attr_type: count, trans_id: count, value: string)
{
switch ( attr_types[attr_type] ) {
# case "Calling-Station-Id":
# tmp = normalize_mac(value);
# if ( tmp != "" )
# print cat(attr_types[attr_type], " ", tmp);
# else
# print cat(attr_types[attr_type], " ", value);
# break;
# case "Called-Station-Id":
# fallthrough;
## Strings:
case "Reply-Message":
fallthrough;
case "User-Name":
print cat(attr_types[attr_type], ": ", value);
break;
## IPs:
case "Framed-IP-Address":
fallthrough;
case "Framed-IP-Netmask":
fallthrough;
case "NAS-IP-Address":
print cat(attr_types[attr_type], ": ", count_to_v4_addr(bytestring_to_count(value)));
break;
## Counts:
case "Framed-MTU":
fallthrough;
case "NAS-Port":
fallthrough;
case "Session-Timeout":
print cat(attr_types[attr_type], ": ", bytestring_to_count(value));
break;
## Other:
case "NAS-Port-Type":
print cat(attr_types[attr_type], ": ", nas_port_types[bytestring_to_count(value)]);
break;
case "Service-Type":
print cat(attr_types[attr_type], ": ", service_types[bytestring_to_count(value)]);
break;
case "Framed-Protocol":
print cat(attr_types[attr_type], ": ", framed_protocol_types[bytestring_to_count(value)]);
break;
case "Vendor-Specific":
switch(bytestring_to_count(sub_bytes(value, 0, 4))) {
case 9:
# Cisco IOS/PIX 6.0
print cat(vendor_9_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128));
break;
case 255:
# Cisco VPN 5000
print cat(vendor_255_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128));
break;
case 311:
# Microsoft
print cat(vendor_311_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128));
break;
case 3076:
# Cisco VPN 3000
print cat(vendor_3076_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128));
break;
case 14823:
# Aruba
print cat(vendor_14823_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128));
break;
default:
print cat("Unknown vendor: ", bytestring_to_count(sub_bytes(value, 0, 4)));
break;
if ( c?$radius && result$trans_id in c$radius )
info = c$radius[result$trans_id];
else
{
c$radius = table();
info$ts = network_time();
info$uid = c$uid;
info$id = c$id;
}
break;
default:
print cat(attr_types[attr_type], ": ", value);
break;
switch ( result$code ) {
case 1:
# Acess-Request
if ( result?$attributes ) {
# User-Name
if ( !info?$username && 1 in result$attributes )
info$username = result$attributes[1][0];
# Calling-Station-Id (we expect this to be a MAC)
if ( !info?$mac && 31 in result$attributes )
info$mac = normalize_mac(result$attributes[31][0]);
# Tunnel-Client-EndPoint (useful for VPNs)
if ( !info?$remote_ip && 66 in result$attributes )
info$remote_ip = to_addr(result$attributes[66][0]);
# Connect-Info
if ( !info?$connect_info && 77 in result$attributes )
info$connect_info = result$attributes[77][0];
}
break;
case 2:
# Access-Accept
info$result = "success";
break;
case 3:
# Access-Reject
info$result = "failed";
break;
}
if ( info?$result && !info?$logged )
{
info$logged = T;
Log::write(RADIUS::LOG, info);
}
c$radius[result$trans_id] = info;
}
# Called-Station-Id:
# Calling-Station-Id:
# Class:
# NAS-Identifier:
# State:
# Vendor-Specific:
# unknown-185:
# unknown-66:
# unknown-77:
# unknown-79:
# unknown-80:
# unknown-87:
# unknown-95:
function expire(t: table[count] of Info, idx: count): interval
{
t[idx]$result = "unknown";
return 0secs;
}

View file

@ -9,7 +9,7 @@
## trans_id: The RADIUS transaction identifier
## authenticator: The value of the authenticator field
##
event radius_message%(c: connection, msg_type: count, trans_id: count%);
event radius_message%(c: connection, result: RADIUS::Message%);
## Generated for each RADIUS attribute
##
@ -17,7 +17,10 @@ event radius_message%(c: connection, msg_type: count, trans_id: count%);
##
## c: The connection
## attr_type: The value of the code field (1 == User-Name, 2 == User-Password, etc.)
## trans_id: The RADIUS transaction identifier
## authenticator: The value of the authenticator field
##
event radius_attribute%(c: connection, attr_type: count, trans_id: count, value: string%);
event radius_attribute%(c: connection, attr_type: count, value: string%);
type RADIUS::AttributeList: vector;
type RADIUS::Attributes: table;
type RADIUS::Message: record;

View file

@ -1,23 +1,50 @@
# Generated by binpac_quickstart
refine flow RADIUS_Flow += {
function proc_radius_message(code: uint8, trans_id: uint8): bool
function proc_radius_message(msg: RADIUS_PDU): bool
%{
BifEvent::generate_radius_message(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), code, trans_id);
connection()->bro_analyzer()->ProtocolConfirmation();
if ( !radius_message ) return false;
RecordVal* result = new RecordVal(BifType::Record::RADIUS::Message);
result->Assign(0, new Val(${msg.code}, TYPE_COUNT));
result->Assign(1, new Val(${msg.trans_id}, TYPE_COUNT));
result->Assign(2, bytestring_to_val(${msg.authenticator}));
TableVal* Attributes = new TableVal(BifType::Table::RADIUS::Attributes);
for ( uint i = 0; i < ${msg.attributes}->size(); ++i ) {
// Do we already have a vector of attributes for this type?
VectorVal* current = (VectorVal*) Attributes->Lookup(new Val(${msg.attributes[i].code}, TYPE_COUNT));
if ( current )
current->Assign((uint) current->Size(), bytestring_to_val(${msg.attributes[i].value}));
else {
VectorVal* AttributeList = new VectorVal(BifType::Vector::RADIUS::AttributeList);
AttributeList->Assign((uint) 0, bytestring_to_val(${msg.attributes[i].value}));
Attributes->Assign(new Val(${msg.attributes[i].code}, TYPE_COUNT), AttributeList);
}
}
if ( ${msg.attributes}->size() )
result->Assign(3, Attributes);
BifEvent::generate_radius_message(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), result);
return true;
%}
function proc_radius_attribute(code: uint8, trans_id: uint8, value: bytestring): bool
function proc_radius_attribute(attr: RADIUS_Attribute): bool
%{
BifEvent::generate_radius_attribute(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), code, trans_id, bytestring_to_val(value));
if ( !radius_attribute ) return false;
BifEvent::generate_radius_attribute(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), ${attr.code}, bytestring_to_val(${attr.value}));
return true;
%}
};
refine typeattr RADIUS_PDU += &let {
proc: bool = $context.flow.proc_radius_message(code, trans_id);
proc: bool = $context.flow.proc_radius_message(this);
};
refine typeattr RADIUS_Attribute += &let {
proc: bool = $context.flow.proc_radius_attribute(code, trans_id, value);
proc: bool = $context.flow.proc_radius_attribute(this);
};