A number of Kerberos fixes, following testing. Added some fields to the log, and parsed some more data.

This commit is contained in:
Vlad Grigorescu 2015-01-19 18:16:27 -05:00
parent 2c8a3fce49
commit 2e8eb574f5
7 changed files with 321 additions and 152 deletions

View file

@ -2975,31 +2975,6 @@ export {
module KRB; module KRB;
export { export {
## The data from the ERROR_MSG message. See :rfc:`4120`.
type KRB::Error_Msg: record {
## Protocol version number (5 for KRB5)
pvno: count;
## The message type (30 for ERROR_MSG)
msg_type: count;
## Current time on the client
client_time: time &optional;
## Current time on the server
server_time: time;
## The specific error code
error_code: count;
## Realm of the ticket
client_realm: string &optional;
## Name on the ticket
client_name: string &optional;
## Realm of the service
service_realm: string;
## Name of the service
service_name: string;
## Additional text to explain the error
error_text: string &optional;
};
## KDC Options. See :rfc:`4120` ## KDC Options. See :rfc:`4120`
type KRB::KDC_Options: record { type KRB::KDC_Options: record {
## The ticket to be issued should have its forwardable flag set. ## The ticket to be issued should have its forwardable flag set.
@ -3030,7 +3005,7 @@ export {
enc_tkt_in_skey : bool; enc_tkt_in_skey : bool;
## The request is for a renewal ## The request is for a renewal
renew : bool; renew : bool;
## The request ist to validate a postdated ticket. ## The request is to validate a postdated ticket.
validate : bool; validate : bool;
}; };
@ -3045,6 +3020,33 @@ export {
type KRB::Type_Value_Vector: vector of KRB::Type_Value; type KRB::Type_Value_Vector: vector of KRB::Type_Value;
## The data from the ERROR_MSG message. See :rfc:`4120`.
type KRB::Error_Msg: record {
## Protocol version number (5 for KRB5)
pvno : count;
## The message type (30 for ERROR_MSG)
msg_type : count;
## Current time on the client
client_time : time &optional;
## Current time on the server
server_time : time;
## The specific error code
error_code : count;
## Realm of the ticket
client_realm : string &optional;
## Name on the ticket
client_name : string &optional;
## Realm of the service
service_realm : string;
## Name of the service
service_name : string;
## Additional text to explain the error
error_text : string &optional;
## Optional pre-authentication data
pa_data : vector of KRB::Type_Value &optional;
};
## A Kerberos ticket. See :rfc:`4120`. ## A Kerberos ticket. See :rfc:`4120`.
type KRB::Ticket: record { type KRB::Ticket: record {
## Protocol version number (5 for KRB5) ## Protocol version number (5 for KRB5)
@ -3062,9 +3064,9 @@ export {
## A Kerberos host address See :rfc:`4120`. ## A Kerberos host address See :rfc:`4120`.
type KRB::Host_Address: record { type KRB::Host_Address: record {
## IPv4 or IPv6 address ## IPv4 or IPv6 address
ip : addr &optional; ip : addr &log &optional;
## NetBIOS address ## NetBIOS address
netbios : string &optional; netbios : string &log &optional;
## Some other type that we don't support yet ## Some other type that we don't support yet
unknown : KRB::Type_Value &optional; unknown : KRB::Type_Value &optional;
}; };

View file

@ -1,5 +1,7 @@
signature dpd_krb { signature dpd_krb_udp {
ip-proto == udp ip-proto == udp
payload /\x6c...\x30...\xa1\x03\x02\x05/ payload /\x6c...\x30...\xa1\x03\x02\x05/
enable "krb" enable "krb"
} }

View file

@ -17,11 +17,28 @@ export {
## Client ## Client
client: string &log &optional; client: string &log &optional;
## Service ## Service
service:string &log; service: string &log;
## Ticket valid from ## Ticket valid from
from: time &log &optional; from: time &log &optional;
## Ticket valid till ## Ticket valid till
till: time &log &optional; till: time &log &optional;
## Forwardable ticket requested
forwardable: bool &log &optional;
## Proxiable ticket requested
proxiable: bool &log &optional;
## Postdated ticket requested
postdated: bool &log &optional;
## Renewable ticket requested
renewable: bool &log &optional;
## The request is for a renewal
renew_request: bool &log &optional;
# The request is to validate a postdated ticket
validate_request: bool &log &optional;
# Network addresses supplied by the client
network_addrs: vector of addr &log &optional;
# NetBIOS addresses supplied by the client
netbios_addrs: vector of string &log &optional;
## Result ## Result
result: string &log &default="unknown"; result: string &log &default="unknown";
## Error code ## Error code
@ -32,6 +49,19 @@ export {
logged: bool &default=F; logged: bool &default=F;
}; };
## The server response error texts which are *not* logged.
const ignored_errors: set[string] = {
# This will significantly increase the noisiness of the log.
# However, one attack is to iterate over principals, looking
# for ones that don't require preauth, and then performn
# an offline attack on that ticket. To detect that attack,
# log NEEDED_PREAUTH.
"NEEDED_PREAUTH",
# This is a more specific version of NEEDED_PREAUTH that's used
# by Winodws AD Kerberos.
"Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ",
} &redef;
## Event that can be handled to access the KRB record as it is sent on ## Event that can be handled to access the KRB record as it is sent on
## to the loggin framework. ## to the loggin framework.
global log_krb: event(rec: Info); global log_krb: event(rec: Info);
@ -53,6 +83,13 @@ event krb_error(c: connection, msg: Error_Msg)
{ {
local info: Info; local info: Info;
if ( msg?$error_text && msg$error_text in ignored_errors )
{
if ( c?$krb )
delete c$krb;
return;
}
if ( c?$krb && c$krb$logged ) if ( c?$krb && c$krb$logged )
return; return;
@ -99,11 +136,38 @@ event krb_as_req(c: connection, msg: KDC_Request)
info$ts = network_time(); info$ts = network_time();
info$uid = c$uid; info$uid = c$uid;
info$id = c$id; info$id = c$id;
info$client = fmt("%s/%s", msg$client_name, msg$service_realm); info$client = fmt("%s/%s", msg$client_name, msg$service_realm);
info$service = msg$service_name; info$service = msg$service_name;
if ( msg?$from ) if ( msg?$from )
info$from = msg$from; info$from = msg$from;
if ( msg?$host_addrs )
{
for ( i in msg$host_addrs )
{
if ( msg$host_addrs[i]?$ip )
{
if ( ! info?$network_addrs )
info$network_addrs = vector();
info$network_addrs[|info$network_addrs|] = msg$host_addrs[i]$ip;
}
if ( msg$host_addrs[i]?$netbios )
{
if ( ! info?$netbios_addrs )
info$netbios_addrs = vector();
info$netbios_addrs[|info$netbios_addrs|] = msg$host_addrs[i]$netbios;
}
}
}
info$till = msg$till; info$till = msg$till;
info$forwardable = msg$kdc_options$forwardable;
info$proxiable = msg$kdc_options$proxiable;
info$postdated = msg$kdc_options$postdated;
info$renewable = msg$kdc_options$renewable;
c$krb = info; c$krb = info;
} }

View file

@ -33,6 +33,7 @@ void KRB_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
} }
catch ( const binpac::Exception& e ) catch ( const binpac::Exception& e )
{ {
printf("BinPAC Exception: %s\n", e.c_msg());
ProtocolViolation(e.c_msg()); ProtocolViolation(e.c_msg());
} }
} }

View file

@ -5,11 +5,12 @@ connection KRB_Conn(bro_analyzer: BroAnalyzer) {
flow KRB_Flow(is_orig: bool) { flow KRB_Flow(is_orig: bool) {
datagram = KRB_PDU withcontext(connection, this); datagram = KRB_PDU withcontext(connection, this);
}; };
%header{ %header{
Val* GetTimeFromAsn1(const KRB_Time* atime); Val* GetTimeFromAsn1(const KRB_Time* atime);
Val* GetTimeFromAsn1(StringVal* atime);
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname); Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname);
Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t); Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t);
@ -20,18 +21,26 @@ RecordVal* proc_krb_kdc_options(const KRB_KDC_Options* opts);
%code{ %code{
Val* GetTimeFromAsn1(const KRB_Time* atime) Val* GetTimeFromAsn1(const KRB_Time* atime)
{
return GetTimeFromAsn1(bytestring_to_val(atime->time()));
}
Val* GetTimeFromAsn1(StringVal* atime)
{ {
time_t lResult = 0; time_t lResult = 0;
char lBuffer[16]; char lBuffer[17];
char* pBuffer = lBuffer; char* pBuffer = lBuffer;
size_t lTimeLength = atime->time().length(); size_t lTimeLength = atime->Len();
char * pString = (char *) atime->time().data(); char * pString = (char *) atime->Bytes();
if ( lTimeLength != 15 ) if ( lTimeLength != 15 && lTimeLength != 17 )
return 0; return 0;
if (lTimeLength == 17 )
pString = pString + 2;
memcpy(pBuffer, pString, 15); memcpy(pBuffer, pString, 15);
*(pBuffer+15) = '\0'; *(pBuffer+15) = '\0';
@ -53,7 +62,7 @@ Val* GetTimeFromAsn1(const KRB_Time* atime)
lResult = 0; lResult = 0;
return new Val(double(lResult), TYPE_TIME); return new Val(double(lResult), TYPE_TIME);
} }
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname) Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname)
{ {
@ -102,7 +111,6 @@ refine connection KRB_Conn += {
function proc_krb_kdc_req(msg: KRB_KDC_REQ): bool function proc_krb_kdc_req(msg: KRB_KDC_REQ): bool
%{ %{
if ( ( binary_to_int64(${msg.msg_type.data.content}) == 10 ) && ! krb_as_req ) if ( ( binary_to_int64(${msg.msg_type.data.content}) == 10 ) && ! krb_as_req )
return false; return false;
@ -126,9 +134,6 @@ refine connection KRB_Conn += {
case 1: case 1:
// will be generated as separate event // will be generated as separate event
break; break;
case 2:
// encrypted timestamp is unreadable
break;
case 3: case 3:
{ {
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value); RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
@ -138,11 +143,14 @@ refine connection KRB_Conn += {
break; break;
} }
default: default:
{
if ( ${msg.padata.padata_elems[i].pa_data_element.unknown}.length() )
{ {
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value); RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
type_val->Assign(0, new Val(${msg.padata.padata_elems[i].data_type}, TYPE_COUNT)); type_val->Assign(0, new Val(${msg.padata.padata_elems[i].data_type}, TYPE_COUNT));
type_val->Assign(1, bytestring_to_val(${msg.padata.padata_elems[i].pa_data_element.unknown})); type_val->Assign(1, bytestring_to_val(${msg.padata.padata_elems[i].pa_data_element.unknown}));
padata->Assign(padata->Size(), type_val); padata->Assign(padata->Size(), type_val);
}
break; break;
} }
} }
@ -197,7 +205,7 @@ refine connection KRB_Conn += {
for ( uint j = 0; j < ${msg.body.args[i].data.addrs.addresses}->size(); ++j ) for ( uint j = 0; j < ${msg.body.args[i].data.addrs.addresses}->size(); ++j )
{ {
RecordVal* addr = new RecordVal(BifType::Record::KRB::Host_Address); RecordVal* addr = new RecordVal(BifType::Record::KRB::Host_Address);
switch ( binary_to_int64(${msg.body.args[i].data.addrs.addresses[j].addr_type.data.content}) ) switch ( binary_to_int64(${msg.body.args[i].data.addrs.addresses[j].addr_type.encoding.content}) )
{ {
case 2: case 2:
addr->Assign(0, new AddrVal(IPAddr(IPv4, (const uint32_t*) c_str(${msg.body.args[i].data.addrs.addresses[j].address.data.content}), IPAddr::Network))); addr->Assign(0, new AddrVal(IPAddr(IPv4, (const uint32_t*) c_str(${msg.body.args[i].data.addrs.addresses[j].address.data.content}), IPAddr::Network)));
@ -210,7 +218,7 @@ refine connection KRB_Conn += {
break; break;
default: default:
RecordVal* unk = new RecordVal(BifType::Record::KRB::Type_Value); RecordVal* unk = new RecordVal(BifType::Record::KRB::Type_Value);
unk->Assign(0, asn1_integer_to_val(${msg.body.args[i].data.addrs.addresses[j].addr_type.data}, TYPE_COUNT)); unk->Assign(0, asn1_integer_to_val(${msg.body.args[i].data.addrs.addresses[j].addr_type}, TYPE_COUNT));
unk->Assign(1, bytestring_to_val(${msg.body.args[i].data.addrs.addresses[j].address.data.content})); unk->Assign(1, bytestring_to_val(${msg.body.args[i].data.addrs.addresses[j].address.data.content}));
addr->Assign(2, unk); addr->Assign(2, unk);
break; break;
@ -344,31 +352,23 @@ refine connection KRB_Conn += {
if ( krb_error ) if ( krb_error )
{ {
RecordVal* rv = new RecordVal(BifType::Record::KRB::Error_Msg); RecordVal* rv = new RecordVal(BifType::Record::KRB::Error_Msg);
rv->Assign(0, asn1_integer_to_val(${msg.pvno.data}, TYPE_COUNT));
rv->Assign(1, asn1_integer_to_val(${msg.msg_type.data}, TYPE_COUNT));
if ( ${msg.has_ctime} )
rv->Assign(2, GetTimeFromAsn1(bytestring_to_val(${msg.ctime})));
// TODO: if ( ${msg.has_cusec} )
rv->Assign(3, GetTimeFromAsn1(bytestring_to_val(${msg.stime})));
// TODO: ${msg.susec}
rv->Assign(4, asn1_integer_to_val(${msg.error_code.data}, TYPE_COUNT));
for ( uint i = 0; i < ${msg.args}->size(); i++ ) for ( uint i = 0; i < ${msg.args}->size(); i++ )
{ {
switch ( ${msg.args[i].seq_meta.index} ) switch ( ${msg.args[i].seq_meta.index} )
{ {
case 0:
rv->Assign(0, asn1_integer_to_val(${msg.args[i].args.pvno}, TYPE_COUNT));
break;
case 1:
rv->Assign(1, asn1_integer_to_val(${msg.args[i].args.msg_type}, TYPE_COUNT));
break;
case 2:
rv->Assign(2, GetTimeFromAsn1(${msg.args[i].args.ctime}));
break;
case 3:
// TODO
break;
case 4:
rv->Assign(3, GetTimeFromAsn1(${msg.args[i].args.stime}));
break;
case 5:
// TODO
break;
case 6:
rv->Assign(4, asn1_integer_to_val(${msg.args[i].args.error_code}, TYPE_COUNT));
break;
case 7: case 7:
rv->Assign(5, bytestring_to_val(${msg.args[i].args.crealm.encoding.content})); rv->Assign(5, bytestring_to_val(${msg.args[i].args.crealm.encoding.content}));
break; break;
@ -384,6 +384,42 @@ refine connection KRB_Conn += {
case 11: case 11:
rv->Assign(9, bytestring_to_val(${msg.args[i].args.e_text.encoding.content})); rv->Assign(9, bytestring_to_val(${msg.args[i].args.e_text.encoding.content}));
break; break;
case 12:
if ( ${msg.error_code.data.content}[0] == 25 )
{
VectorVal* padata = new VectorVal(internal_type("KRB::Type_Value_Vector")->AsVectorType());
for ( uint j = 0; j < ${msg.args[i].args.e_data.padata.padata_elems}->size(); ++j)
{
switch( ${msg.args[i].args.e_data.padata.padata_elems[j].data_type} )
{
case 1:
// will be generated as separate event
break;
case 3:
{
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
type_val->Assign(0, new Val(${msg.args[i].args.e_data.padata.padata_elems[j].data_type}, TYPE_COUNT));
type_val->Assign(1, bytestring_to_val(${msg.args[i].args.e_data.padata.padata_elems[j].pa_data_element.pa_pw_salt.encoding.content}));
padata->Assign(padata->Size(), type_val);
break;
}
default:
{
if ( ${msg.args[i].args.e_data.padata.padata_elems[j].pa_data_element.unknown}.length() )
{
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
type_val->Assign(0, new Val(${msg.args[i].args.e_data.padata.padata_elems[j].data_type}, TYPE_COUNT));
type_val->Assign(1, bytestring_to_val(${msg.args[i].args.e_data.padata.padata_elems[j].pa_data_element.unknown}));
padata->Assign(padata->Size(), type_val);
}
break;
}
}
}
rv->Assign(10, padata);
}
break;
default: default:
break; break;
} }
@ -411,12 +447,23 @@ refine connection KRB_Conn += {
return true; return true;
%} %}
function debug_req_arg(msg: KRB_REQ_Arg_Data): bool
%{
printf("KRB_REQ_Arg index=%d\n", ${msg.index});
return true;
%}
function debug_asn1_encoding_meta(msg: ASN1EncodingMeta): bool
%{
printf("ASN1 Element tag=%x, length=%d\n", ${msg.tag}, ${msg.length});
return true;
%}
} }
refine typeattr KRB_AS_REQ += &let { refine typeattr KRB_AS_REQ += &let {
proc: bool = $context.connection.proc_krb_kdc_req(data); proc: bool = $context.connection.proc_krb_kdc_req(data);
}; };
refine typeattr KRB_TGS_REQ += &let { refine typeattr KRB_TGS_REQ += &let {
proc: bool = $context.connection.proc_krb_kdc_req(data); proc: bool = $context.connection.proc_krb_kdc_req(data);
@ -454,3 +501,10 @@ refine typeattr KRB_CRED_MSG += &let {
proc: bool = $context.connection.proc_krb_cred_msg(this); proc: bool = $context.connection.proc_krb_cred_msg(this);
}; };
#refine typeattr KRB_REQ_Arg_Data += &let {
# proc: bool = $context.connection.debug_req_arg(this);
#};
#refine typeattr ASN1EncodingMeta += &let {
# proc: bool = $context.connection.debug_asn1_encoding_meta(this);
#};

View file

@ -6,10 +6,11 @@ type ASN1Encoding = record {
type ASN1EncodingMeta = record { type ASN1EncodingMeta = record {
tag: uint8; tag: uint8;
len: uint8; len: uint8;
more_len: bytestring &length = long_len ? len & 0x7f : 0; more_len: bytestring &length = long_len ? (len & 0x7f) : 0;
} &let { } &let {
long_len: bool = len & 0x80; long_len: bool = (len & 0x80) > 0;
length: uint64 = long_len ? binary_to_int64(more_len) : len & 0x7f; length: uint64 = long_len ? binary_to_int64(more_len) : len;
has_index: bool = (tag >= 160);
index: uint8 = tag - 160; index: uint8 = tag - 160;
}; };

View file

@ -64,7 +64,7 @@ type KRB_KDC_REQ = record {
body : KRB_REQ_Body &length=body_length; body : KRB_REQ_Body &length=body_length;
} &let { } &let {
has_padata : bool = padata_meta.index == 3; has_padata : bool = padata_meta.index == 3;
body_length: uint8 = has_padata ? meta2.length : padata_meta.length; body_length: uint64 = has_padata ? meta2.length : padata_meta.length;
}; };
type KRB_PA_Data_Sequence = record { type KRB_PA_Data_Sequence = record {
@ -76,16 +76,15 @@ type KRB_PA_Data = record {
seq_meta : ASN1EncodingMeta; seq_meta : ASN1EncodingMeta;
pa_data_type : SequenceElement(true); pa_data_type : SequenceElement(true);
pa_data_elem_meta : ASN1EncodingMeta; pa_data_elem_meta : ASN1EncodingMeta;
pa_data_element : KRB_PA_Data_Element(data_type); pa_data_element : KRB_PA_Data_Element(data_type, pa_data_elem_meta.length);
} &let { } &let {
data_type: int64 = binary_to_int64(pa_data_type.data.content); data_type: int64 = binary_to_int64(pa_data_type.data.content);
}; };
type KRB_PA_Data_Element(type: int64) = case type of { type KRB_PA_Data_Element(type: int64, length: uint64) = case type of {
1 -> pa_tgs_req : KRB_AP_REQ; 1 -> pa_tgs_req : KRB_AP_REQ;
2 -> pa_enc_timestamp : KRB_Encrypted_Data;
3 -> pa_pw_salt : ASN1OctetString; 3 -> pa_pw_salt : ASN1OctetString;
default -> unknown : bytestring &restofdata; default -> unknown : bytestring &length=length;
}; };
type KRB_REQ_Body = record { type KRB_REQ_Body = record {
@ -116,30 +115,31 @@ type KRB_REQ_Arg_Data(index: uint8) = case index of {
type KRB_KDC_Options = record { type KRB_KDC_Options = record {
meta : ASN1EncodingMeta; meta : ASN1EncodingMeta;
pad: uint8;
flags: uint32; flags: uint32;
} &let { } &let {
reserved : bool = flags & 0x80000000; reserved : bool = (flags & 0x80000000) > 0;
forwardable : bool = flags & 0x40000000; forwardable : bool = (flags & 0x40000000) > 0;
forwarded : bool = flags & 0x20000000; forwarded : bool = (flags & 0x20000000) > 0;
proxiable : bool = flags & 0x10000000; proxiable : bool = (flags & 0x10000000) > 0;
proxy : bool = flags & 0x8000000; proxy : bool = (flags & 0x8000000) > 0;
allow_postdate : bool = flags & 0x4000000; allow_postdate : bool = (flags & 0x4000000) > 0;
postdated : bool = flags & 0x2000000; postdated : bool = (flags & 0x2000000) > 0;
unused7 : bool = flags & 0x1000000; unused7 : bool = (flags & 0x1000000) > 0;
renewable : bool = flags & 0x800000; renewable : bool = (flags & 0x800000) > 0;
unused9 : bool = flags & 0x400000; unused9 : bool = (flags & 0x400000) > 0;
unused10 : bool = flags & 0x200000; unused10 : bool = (flags & 0x200000) > 0;
opt_hardware_auth : bool = flags & 0x100000; opt_hardware_auth : bool = (flags & 0x100000) > 0;
unused12 : bool = flags & 0x80000; unused12 : bool = (flags & 0x80000) > 0;
unused13 : bool = flags & 0x40000; unused13 : bool = (flags & 0x40000) > 0;
# ... # ...
unused15 : bool = flags & 0x10000; unused15 : bool = (flags & 0x10000) > 0;
# ... # ...
disable_transited_check : bool = flags & 0x10; disable_transited_check : bool = (flags & 0x10) > 0;
renewable_ok : bool = flags & 0x8; renewable_ok : bool = (flags & 0x8) > 0;
enc_tkt_in_skey : bool = flags & 0x4; enc_tkt_in_skey : bool = (flags & 0x4) > 0;
renew : bool = flags & 0x2; renew : bool = (flags & 0x2) > 0;
validate : bool = flags & 0x1; validate : bool = (flags & 0x1) > 0;
}; };
type KRB_Principal_Name = record { type KRB_Principal_Name = record {
@ -148,7 +148,7 @@ type KRB_Principal_Name = record {
name_type : ASN1Integer; name_type : ASN1Integer;
seq_meta_1: ASN1EncodingMeta; seq_meta_1: ASN1EncodingMeta;
seq_meta_2: ASN1EncodingMeta; seq_meta_2: ASN1EncodingMeta;
data : ASN1OctetString[] &length=seq_meta_2.length; data : ASN1OctetString[];
}; };
type KRB_Time = record { type KRB_Time = record {
@ -162,7 +162,8 @@ type KRB_Host_Addresses = record {
}; };
type KRB_Host_Address = record { type KRB_Host_Address = record {
addr_type: SequenceElement(true); addr_type_meta : SequenceElement(false);
addr_type : ASN1Integer;
address : SequenceElement(true); address : SequenceElement(true);
}; };
@ -176,7 +177,7 @@ type KRB_Ticket(in_sequence: bool) = record {
tkt_vno : SequenceElement(true); tkt_vno : SequenceElement(true);
realm : SequenceElement(true); realm : SequenceElement(true);
sname_meta: ASN1EncodingMeta; sname_meta: ASN1EncodingMeta;
sname : KRB_Principal_Name; sname : KRB_Principal_Name &length=sname_meta.length;
enc_part : KRB_Encrypted_Data; enc_part : KRB_Encrypted_Data;
}; };
@ -187,7 +188,7 @@ type KRB_Ticket_Sequence = record {
type KRB_Encrypted_Data_in_Seq = record { type KRB_Encrypted_Data_in_Seq = record {
index_meta : ASN1EncodingMeta; index_meta : ASN1EncodingMeta;
data : KRB_Encrypted_Data; data : KRB_Encrypted_Data &length=index_meta.length;
}; };
type KRB_Encrypted_Data = record { type KRB_Encrypted_Data = record {
@ -223,12 +224,13 @@ type KRB_KDC_REP = record {
false -> n2 : empty; false -> n2 : empty;
}; };
client_realm: ASN1OctetString &length=realm_length; client_realm: ASN1OctetString &length=realm_length;
client_name : KRB_Principal_Name; cname_meta : ASN1EncodingMeta;
client_name : KRB_Principal_Name &length=cname_meta.length;
ticket : KRB_Ticket(true); ticket : KRB_Ticket(true);
enc_part : KRB_Encrypted_Data_in_Seq; enc_part : KRB_Encrypted_Data_in_Seq;
} &let { } &let {
has_padata : bool = padata_meta.index == 2; has_padata : bool = padata_meta.index == 2;
realm_length: uint8 = has_padata ? meta2.length : padata_meta.length; realm_length: uint64 = has_padata ? meta2.length : padata_meta.length;
}; };
### AP_REQ ### AP_REQ
@ -249,9 +251,9 @@ type KRB_AP_Options = record {
flags : uint32; flags : uint32;
: padding[1]; : padding[1];
} &let { } &let {
reserved : bool = flags & 0x80000000; reserved : bool = (flags & 0x80000000) > 0;
use_session_key : bool = flags & 0x40000000; use_session_key : bool = (flags & 0x40000000) > 0;
mutual_required : bool = flags & 0x20000000; mutual_required : bool = (flags & 0x20000000) > 0;
}; };
@ -265,30 +267,73 @@ type KRB_AP_REP = record {
### KRB_ERROR ### KRB_ERROR
# pvno [0] INTEGER (5),
# msg-type [1] INTEGER (30),
# ctime [2] KerberosTime OPTIONAL,
# cusec [3] Microseconds OPTIONAL,
# stime [4] KerberosTime,
# susec [5] Microseconds,
# error-code [6] Int32,
# crealm [7] Realm OPTIONAL,
# cname [8] PrincipalName OPTIONAL,
# realm [9] Realm -- service realm --,
# sname [10] PrincipalName -- service name --,
# e-text [11] KerberosString OPTIONAL,
type KRB_ERROR_MSG = record { type KRB_ERROR_MSG = record {
seq_meta: ASN1EncodingMeta; seq_meta : ASN1EncodingMeta;
args : KRB_ERROR_Arg[]; pvno : SequenceElement(true);
msg_type : SequenceElement(true);
ctime_meta : ASN1EncodingMeta;
tmp1 : case has_ctime of {
true -> ctime : bytestring &length=ctime_meta.length;
false -> n1 : empty;
};
tmp2 : case has_ctime of {
true -> cusec_meta : ASN1EncodingMeta;
false -> n2 : empty;
};
tmp3 : case has_cusec of {
true -> cusec : ASN1Integer;
false -> n3 : empty;
};
tmp4 : case has_cusec of {
true -> stime_meta : ASN1EncodingMeta;
false -> n4 : empty;
};
stime : bytestring &length=stime_length;
susec : SequenceElement(true);
error_code : SequenceElement(true);
args : KRB_ERROR_Arg(binary_to_int64(error_code.data.content))[];
} &let {
has_ctime: bool = ctime_meta.index == 2;
has_cusec: bool = has_ctime ? cusec_meta.index == 3 : ctime_meta.index == 3;
stime_length: uint64 = has_ctime ? (has_cusec ? stime_meta.length : cusec_meta.length) : (has_cusec ? stime_meta.length : ctime_meta.length);
}; };
type KRB_ERROR_Arg = record { type KRB_ERROR_Arg(error_code: uint64) = record {
seq_meta: ASN1EncodingMeta; seq_meta: ASN1EncodingMeta;
args : KRB_ERROR_Arg_Data(seq_meta.index) &length=seq_meta.length; args : KRB_ERROR_Arg_Data(seq_meta.index, error_code) &length=seq_meta.length;
}; };
type KRB_ERROR_Arg_Data(index: uint8) = case index of { type KRB_ERROR_Arg_Data(index: uint8, error_code: uint64) = case index of {
0 -> pvno : ASN1Integer;
1 -> msg_type : ASN1Integer;
2 -> ctime : KRB_Time;
3 -> cusec : ASN1Integer;
4 -> stime : KRB_Time;
5 -> susec : ASN1Integer;
6 -> error_code : ASN1Integer;
7 -> crealm : ASN1OctetString; 7 -> crealm : ASN1OctetString;
8 -> cname : KRB_Principal_Name; 8 -> cname : KRB_Principal_Name;
9 -> realm : ASN1OctetString; 9 -> realm : ASN1OctetString;
10 -> sname : KRB_Principal_Name; 10 -> sname : KRB_Principal_Name;
11 -> e_text : ASN1OctetString; 11 -> e_text : ASN1OctetString;
12 -> e_data : ASN1OctetString; 12 -> e_data : KRB_ERROR_PA_Data(error_code);
};
type KRB_ERROR_PA_Data(error_code: uint64) = record {
have_padata1: case ( error_code == 25 ) of {
true -> meta1 : ASN1EncodingMeta;
false -> data : ASN1OctetString;
};
have_padata2: case ( error_code == 25 ) of {
true -> padata : KRB_PA_Data_Sequence;
false -> n1 : empty;
};
}; };
### KRB_SAFE ### KRB_SAFE