Continue clean-up. Some reformatting, removing hard-coded values, documentation, etc.

This commit is contained in:
Vlad Grigorescu 2015-02-04 15:29:06 -05:00
parent 2d11fafd5e
commit 0071a1c003
6 changed files with 339 additions and 270 deletions

View file

@ -1,94 +1,11 @@
%extern{
#include "file_analysis/Manager.h"
%}
%header{
Val* GetTimeFromAsn1(const KRB_Time* atime, int64 usecs);
Val* GetTimeFromAsn1(StringVal* atime, int64 usecs);
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname);
Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t);
Val* asn1_integer_to_val(const ASN1Integer* i, TypeTag t);
RecordVal* proc_krb_kdc_options(const KRB_KDC_Options* opts);
RecordVal* proc_krb_kdc_req_arguments(KRB_KDC_REQ* msg, const BroAnalyzer bro_analyzer);
VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_analyzer, bool is_error);
VectorVal* proc_cipher_list(const Array* list);
VectorVal* proc_host_address_list(const KRB_Host_Addresses* list);
VectorVal* proc_tickets(const KRB_Ticket_Sequence* list);
bool proc_error_arguments(RecordVal* rv, const std::vector<KRB_ERROR_Arg*>* args, int64 error_code);
%}
%code{
Val* GetTimeFromAsn1(const KRB_Time* atime, int64 usecs)
{
return GetTimeFromAsn1(bytestring_to_val(atime->time()), usecs);
}
Val* GetTimeFromAsn1(StringVal* atime, int64 usecs)
{
time_t lResult = 0;
char lBuffer[17];
char* pBuffer = lBuffer;
size_t lTimeLength = atime->Len();
char * pString = (char *) atime->Bytes();
if ( lTimeLength != 15 && lTimeLength != 17 )
return 0;
if (lTimeLength == 17 )
pString = pString + 2;
memcpy(pBuffer, pString, 15);
*(pBuffer+15) = '\0';
tm lTime;
lTime.tm_sec = ((lBuffer[12] - '0') * 10) + (lBuffer[13] - '0');
lTime.tm_min = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
lTime.tm_hour = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
lTime.tm_mday = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
lTime.tm_mon = (((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0')) - 1;
lTime.tm_year = ((lBuffer[0] - '0') * 1000) + ((lBuffer[1] - '0') * 100) + ((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0') - 1900;
lTime.tm_wday = 0;
lTime.tm_yday = 0;
lTime.tm_isdst = 0;
lResult = timegm(&lTime);
if ( !lResult )
lResult = 0;
return new Val(double(lResult + (usecs/100000)), TYPE_TIME);
}
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname)
{
if ( pname->data()->size() == 1 )
return bytestring_to_val(pname->data()[0][0]->encoding()->content());
if ( pname->data()->size() == 2 )
return new StringVal(fmt("%s/%s", (char *) pname->data()[0][0]->encoding()->content().begin(), (char *)pname->data()[0][1]->encoding()->content().begin()));
return new StringVal("unknown");
}
Val* asn1_integer_to_val(const ASN1Integer* i, TypeTag t)
{
return asn1_integer_to_val(i->encoding(), t);
}
Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t)
{
return new Val(binary_to_int64(i->content()), t);
}
RecordVal* proc_krb_kdc_options(const KRB_KDC_Options* opts)
{
RecordVal* rv = new RecordVal(BifType::Record::KRB::KDC_Options);
@ -110,159 +27,6 @@ RecordVal* proc_krb_kdc_options(const KRB_KDC_Options* opts)
return rv;
}
VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_analyzer, bool is_error)
{
VectorVal* vv = new VectorVal(internal_type("KRB::Type_Value_Vector")->AsVectorType());
for ( uint i = 0; i < data->padata_elems()->size(); ++i)
{
KRB_PA_Data* element = (*data->padata_elems())[i];
int64 data_type = element->data_type();
if ( is_error && ( data_type == 16 || data_type == 17 ) )
data_type = 0;
switch( data_type )
{
case 1:
// will be generated as separate event
break;
case 2:
// encrypted timestamp is unreadable
break;
case 3:
{
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
type_val->Assign(0, new Val(element->data_type(), TYPE_COUNT));
type_val->Assign(1, bytestring_to_val(element->pa_data_element()->pa_pw_salt()->encoding()->content()));
vv->Assign(vv->Size(), type_val);
break;
}
case 16:
{
const bytestring& cert = element->pa_data_element()->pa_pk_as_req()->cert();
ODesc common;
common.AddRaw("Analyzer::ANALYZER_KRB");
common.Add(bro_analyzer->Conn()->StartTime());
common.AddRaw("T", 1);
bro_analyzer->Conn()->IDString(&common);
ODesc file_handle;
file_handle.Add(common.Description());
file_handle.Add(0);
string file_id = file_mgr->HashHandle(file_handle.Description());
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
cert.length(), bro_analyzer->GetAnalyzerTag(),
bro_analyzer->Conn(), true, file_id);
file_mgr->EndOfFile(file_id);
break;
}
case 17:
{
const bytestring& cert = element->pa_data_element()->pa_pk_as_rep()->cert();
ODesc common;
common.AddRaw("Analyzer::ANALYZER_KRB");
common.Add(bro_analyzer->Conn()->StartTime());
common.AddRaw("F", 1);
bro_analyzer->Conn()->IDString(&common);
ODesc file_handle;
file_handle.Add(common.Description());
file_handle.Add(1);
string file_id = file_mgr->HashHandle(file_handle.Description());
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
cert.length(), bro_analyzer->GetAnalyzerTag(),
bro_analyzer->Conn(), false, file_id);
file_mgr->EndOfFile(file_id);
break;
}
default:
{
if ( ! is_error && element->pa_data_element()->unknown().length() )
{
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
type_val->Assign(0, new Val(element->data_type(), TYPE_COUNT));
type_val->Assign(1, bytestring_to_val(element->pa_data_element()->unknown()));
vv->Assign(vv->Size(), type_val);
}
break;
}
}
}
return vv;
}
VectorVal* proc_cipher_list(const Array* list)
{
VectorVal* ciphers = new VectorVal(internal_type("index_vec")->AsVectorType());
for ( uint i = 0; i < list->data()->size(); ++i )
ciphers->Assign(ciphers->Size(), asn1_integer_to_val((*list->data())[i], TYPE_COUNT));
return ciphers;
}
VectorVal* proc_host_address_list(const KRB_Host_Addresses* list)
{
VectorVal* addrs = new VectorVal(internal_type("KRB::Host_Address_Vector")->AsVectorType());
for ( uint i = 0; i < list->addresses()->size(); ++i )
{
RecordVal* addr = new RecordVal(BifType::Record::KRB::Host_Address);
KRB_Host_Address* element = (*list->addresses())[i];
switch ( binary_to_int64(element->addr_type()->encoding()->content()) )
{
case 2:
addr->Assign(0, new AddrVal(IPAddr(IPv4,
(const uint32_t*) c_str(element->address()->data()->content()),
IPAddr::Network)));
break;
case 24:
addr->Assign(0, new AddrVal(IPAddr(IPv6,
(const uint32_t*) c_str(element->address()->data()->content()),
IPAddr::Network)));
break;
case 20:
addr->Assign(1, bytestring_to_val(element->address()->data()->content()));
break;
default:
RecordVal* unk = new RecordVal(BifType::Record::KRB::Type_Value);
unk->Assign(0, asn1_integer_to_val(element->addr_type(), TYPE_COUNT));
unk->Assign(1, bytestring_to_val(element->address()->data()->content()));
addr->Assign(2, unk);
break;
}
addrs->Assign(addrs->Size(), addr);
}
return addrs;
}
VectorVal* proc_tickets(const KRB_Ticket_Sequence* list)
{
VectorVal* tickets = new VectorVal(internal_type("KRB::Ticket_Vector")->AsVectorType());
for ( uint i = 0; i < list->tickets()->size(); ++i )
{
KRB_Ticket* element = (*list->tickets())[i];
RecordVal* ticket = new RecordVal(BifType::Record::KRB::Ticket);
ticket->Assign(0, asn1_integer_to_val(element->tkt_vno()->data(), TYPE_COUNT));
ticket->Assign(1, bytestring_to_val(element->realm()->data()->content()));
ticket->Assign(2, GetStringFromPrincipalName(element->sname()));
ticket->Assign(3, asn1_integer_to_val(element->enc_part()->etype()->data(), TYPE_COUNT));
tickets->Assign(tickets->Size(), ticket);
}
return tickets;
}
bool proc_error_arguments(RecordVal* rv, const std::vector<KRB_ERROR_Arg*>* args, int64 error_code )
{
uint ctime_i = 0, ctime_usecs_i = 0, stime_i = 0, stime_usecs_i = 0;
@ -322,7 +86,7 @@ bool proc_error_arguments(RecordVal* rv, const std::vector<KRB_ERROR_Arg*>* args
rv->Assign(9, bytestring_to_val((*args)[i]->args()->e_text()->encoding()->content()));
break;
case 12:
if ( error_code == 25 )
if ( error_code == KDC_ERR_PREAUTH_REQUIRED )
rv->Assign(10, proc_padata((*args)[i]->args()->e_data()->padata(), NULL, true));
break;
default:
@ -537,39 +301,39 @@ refine typeattr KRB_AS_REQ += &let {
refine typeattr KRB_TGS_REQ += &let {
proc: bool = $context.connection.proc_krb_kdc_req(data);
};
};
refine typeattr KRB_AS_REP += &let {
proc: bool = $context.connection.proc_krb_kdc_rep(data);
};
};
refine typeattr KRB_TGS_REP += &let {
proc: bool = $context.connection.proc_krb_kdc_rep(data);
};
};
refine typeattr KRB_AP_REQ += &let {
proc: bool = $context.connection.proc_krb_ap_req(this);
};
};
refine typeattr KRB_AP_REP += &let {
proc: bool = $context.connection.proc_krb_ap_rep(this);
};
};
refine typeattr KRB_ERROR_MSG += &let {
proc: bool = $context.connection.proc_krb_error_msg(this);
};
};
refine typeattr KRB_SAFE_MSG += &let {
proc: bool = $context.connection.proc_krb_safe_msg(this);
};
};
refine typeattr KRB_PRIV_MSG += &let {
proc: bool = $context.connection.proc_krb_priv_msg(this);
};
};
refine typeattr KRB_CRED_MSG += &let {
proc: bool = $context.connection.proc_krb_cred_msg(this);
};
};
#refine typeattr KRB_REQ_Arg_Data += &let {
# proc: bool = $context.connection.debug_req_arg(this);

View file

@ -1,3 +1,67 @@
%header{
Val* GetTimeFromAsn1(const KRB_Time* atime, int64 usecs);
Val* GetTimeFromAsn1(StringVal* atime, int64 usecs);
Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t);
Val* asn1_integer_to_val(const ASN1Integer* i, TypeTag t);
%}
%code{
Val* GetTimeFromAsn1(const KRB_Time* atime, int64 usecs)
{
return GetTimeFromAsn1(bytestring_to_val(atime->time()), usecs);
}
Val* GetTimeFromAsn1(StringVal* atime, int64 usecs)
{
time_t lResult = 0;
char lBuffer[17];
char* pBuffer = lBuffer;
size_t lTimeLength = atime->Len();
char * pString = (char *) atime->Bytes();
if ( lTimeLength != 15 && lTimeLength != 17 )
return 0;
if (lTimeLength == 17 )
pString = pString + 2;
memcpy(pBuffer, pString, 15);
*(pBuffer+15) = '\0';
tm lTime;
lTime.tm_sec = ((lBuffer[12] - '0') * 10) + (lBuffer[13] - '0');
lTime.tm_min = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
lTime.tm_hour = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
lTime.tm_mday = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
lTime.tm_mon = (((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0')) - 1;
lTime.tm_year = ((lBuffer[0] - '0') * 1000) + ((lBuffer[1] - '0') * 100) + ((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0') - 1900;
lTime.tm_wday = 0;
lTime.tm_yday = 0;
lTime.tm_isdst = 0;
lResult = timegm(&lTime);
if ( !lResult )
lResult = 0;
return new Val(double(lResult + (usecs/100000)), TYPE_TIME);
}
Val* asn1_integer_to_val(const ASN1Integer* i, TypeTag t)
{
return asn1_integer_to_val(i->encoding(), t);
}
Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t)
{
return new Val(binary_to_int64(i->content()), t);
}
%}
type ASN1Encoding = record {
meta: ASN1EncodingMeta;
content: bytestring &length = meta.length;
@ -10,8 +74,8 @@ type ASN1EncodingMeta = record {
} &let {
long_len: bool = (len & 0x80) > 0;
length: uint64 = long_len ? binary_to_int64(more_len) : len;
has_index: bool = (tag >= 160);
index: uint8 = tag - 160;
has_index: bool = (tag >= ASN1_INDEX_TAG_OFFSET);
index: uint8 = tag - ASN1_INDEX_TAG_OFFSET;
};
type ASN1OptionalEncodingMeta(is_present: bool, previous_metadata: ASN1EncodingMeta) = case is_present of {

View file

@ -1,3 +1,4 @@
# Defined in RFC 4120
enum KRBMessageTypes {
AS_REQ = 10,
AS_REP = 11,
@ -11,3 +12,23 @@ enum KRBMessageTypes {
KRB_ERROR = 30,
};
# Defined by IANA in Kerberos Parameters - Pre-authentication and Typed Data
enum KRBPADataTypes {
PA_TGS_REQ = 1,
PA_ENC_TIMESTAMP = 2,
PA_PW_SALT = 3,
PA_PW_AS_REQ = 16,
PA_PW_AS_REP = 17,
};
# Defined in RFC 4120
enum KRBErrorCodes {
KDC_ERR_PREAUTH_REQUIRED = 25,
};
# Defined in ASN.1
enum ASN1Consts {
ASN1_SEQUENCE_TAG = 48,
ASN1_APP_TAG_OFFSET = 96,
ASN1_INDEX_TAG_OFFSET = 160,
};

View file

@ -1,24 +1,156 @@
# Kerberos pre-authentication data is a significant piece of the complexity,
# so we're splitting this off
%extern{
#include "file_analysis/Manager.h"
%}
%header{
VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_analyzer, bool is_error);
%}
%code{
VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_analyzer, bool is_error)
{
VectorVal* vv = new VectorVal(internal_type("KRB::Type_Value_Vector")->AsVectorType());
if ( ! data->data()->has_padata() )
return vv;
for ( uint i = 0; i < data->data()->padata_elems()->size(); ++i)
{
KRB_PA_Data* element = (*data->data()->padata_elems())[i];
int64 data_type = element->data_type();
if ( is_error && ( data_type == PA_PW_AS_REQ || data_type == PA_PW_AS_REP ) )
data_type = 0;
switch( data_type )
{
case PA_TGS_REQ:
// will be generated as separate event
break;
case PA_ENC_TIMESTAMP:
// encrypted timestamp is unreadable
break;
case PA_PW_SALT:
{
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
type_val->Assign(0, new Val(element->data_type(), TYPE_COUNT));
type_val->Assign(1, bytestring_to_val(element->pa_data_element()->pa_pw_salt()->encoding()->content()));
vv->Assign(vv->Size(), type_val);
break;
}
case PA_PW_AS_REQ:
{
const bytestring& cert = element->pa_data_element()->pa_pk_as_req()->cert();
ODesc common;
common.AddRaw("Analyzer::ANALYZER_KRB");
common.Add(bro_analyzer->Conn()->StartTime());
// Request means is_orig=T
common.AddRaw("T", 1);
bro_analyzer->Conn()->IDString(&common);
ODesc file_handle;
file_handle.Add(common.Description());
file_handle.Add(0);
string file_id = file_mgr->HashHandle(file_handle.Description());
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
cert.length(), bro_analyzer->GetAnalyzerTag(),
bro_analyzer->Conn(), true, file_id);
file_mgr->EndOfFile(file_id);
break;
}
case PA_PW_AS_REP:
{
const bytestring& cert = element->pa_data_element()->pa_pk_as_rep()->cert();
ODesc common;
common.AddRaw("Analyzer::ANALYZER_KRB");
common.Add(bro_analyzer->Conn()->StartTime());
// Response means is_orig=F
common.AddRaw("F", 1);
bro_analyzer->Conn()->IDString(&common);
ODesc file_handle;
file_handle.Add(common.Description());
file_handle.Add(1);
string file_id = file_mgr->HashHandle(file_handle.Description());
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
cert.length(), bro_analyzer->GetAnalyzerTag(),
bro_analyzer->Conn(), false, file_id);
file_mgr->EndOfFile(file_id);
break;
}
default:
{
if ( ! is_error && element->pa_data_element()->unknown().length() )
{
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
type_val->Assign(0, new Val(element->data_type(), TYPE_COUNT));
type_val->Assign(1, bytestring_to_val(element->pa_data_element()->unknown()));
vv->Assign(vv->Size(), type_val);
}
break;
}
}
}
return vv;
}
%}
# Basic structure:
# 1) In KDC_REQ/KDC_REP packets, the PA_Data is optional and needs a bit of "lookahead."
# KRB_PA_Data_Optional -> KRB_PA_Data_Optional_Contents -> KRB_PA_Data_Sequence
#
# 2) Once we get to the KRB_PA_Data_Sequence level:
# KRB_PA_Data_Sequence -> KRB_PA_Data_Container -> KRB_PA_Data -> KRB_PA_Data_Element
# Encapsulating header #1 for KDC_REQ/KDC_REP packets where the PADATA is optional.
type KRB_PA_Data_Optional(pkt_type: uint8, desired_index: uint8) = record {
first_meta : ASN1EncodingMeta;
padata : KRB_PA_Data_Field(has_padata, pkt_type, first_meta.length);
padata : KRB_PA_Data_Optional_Contents(has_padata, pkt_type, first_meta.length);
next_meta : ASN1OptionalEncodingMeta(has_padata, first_meta);
} &let {
has_padata : bool = first_meta.index == desired_index;
};
type KRB_PA_Data_Field(is_present: bool, pkt_type: uint8, length: uint64) = case is_present of {
# Encapsulating header #2 for KDC_REQ/KDC_REP packets where the PADATA is optional.
#
# Note: Split off due to a BinPAC bug
type KRB_PA_Data_Optional_Contents(is_present: bool, pkt_type: uint8, length: uint64) = case is_present of {
true -> padata: KRB_PA_Data_Sequence(pkt_type) &length=length;
false -> none: empty;
};
# This is our main type
type KRB_PA_Data_Sequence(pkt_type: uint8) = record {
seq_meta : ASN1EncodingMeta;
padata_elems: KRB_PA_Data(pkt_type)[];
meta : ASN1EncodingMeta;
data : KRB_PA_Data_Container(pkt_type, meta.tag, meta.length);
};
# The data in KRB_PA_Data_Sequence is usually (and supposed to be) a sequence, which we'll parse,
# but is sometimes an octet string. We'll grab that but ignore it.
#
# Note: This is a separate type due to a BinPAC bug.
type KRB_PA_Data_Container(pkt_type: uint8, tag: uint8, length: uint64) = case tag of {
ASN1_SEQUENCE_TAG -> padata_elems : KRB_PA_Data(pkt_type)[];
default -> unknown : bytestring &length=length;
} &let {
has_padata: bool = (tag == ASN1_SEQUENCE_TAG);
};
# The pre-auth data sequence.
#
# Note: Error packets don't have pre-auth data, they just advertise which mechanisms they support.
type KRB_PA_Data(pkt_type: uint8) = record {
seq_meta : ASN1EncodingMeta;
pa_data_type : SequenceElement(true);
@ -31,21 +163,24 @@ type KRB_PA_Data(pkt_type: uint8) = record {
data_type: int64 = binary_to_int64(pa_data_type.data.content);
};
# Each pre-auth element
type KRB_PA_Data_Element(type: int64, length: uint64) = case type of {
1 -> pa_tgs_req : KRB_AP_REQ;
3 -> pa_pw_salt : ASN1OctetString;
16 -> pa_pk_as_req : KRB_PA_PK_AS_Req &length=length;
17 -> pa_pk_as_rep : KRB_PA_PK_AS_Rep &length=length;
default -> unknown : bytestring &length=length;
PA_TGS_REQ -> pa_tgs_req : KRB_AP_REQ;
PA_PW_SALT -> pa_pw_salt : ASN1OctetString;
PA_PW_AS_REQ -> pa_pk_as_req : KRB_PA_PK_AS_Req &length=length;
PA_PW_AS_REP -> pa_pk_as_rep : KRB_PA_PK_AS_Rep &length=length;
default -> unknown : bytestring &length=length;
};
# The PKINIT certificate structure for a request
type KRB_PA_PK_AS_Req = record {
string_meta : ASN1EncodingMeta;
string_meta : ASN1EncodingMeta;
seq_meta1 : ASN1EncodingMeta;
elem_0_meta1: ASN1EncodingMeta;
elem_0_meta1 : ASN1EncodingMeta;
seq_meta2 : ASN1EncodingMeta;
oid : ASN1Encoding;
elem_0_meta2: ASN1EncodingMeta;
oid : ASN1Encoding;
elem_0_meta2 : ASN1EncodingMeta;
seq_meta3 : ASN1EncodingMeta;
version : ASN1Encoding;
digest_algs : ASN1Encoding;
@ -53,17 +188,18 @@ type KRB_PA_PK_AS_Req = record {
cert_meta : ASN1EncodingMeta;
cert : bytestring &length=cert_meta.length;
# Ignore everything else
: bytestring &restofdata &transient;
: bytestring &restofdata &transient;
};
# The PKINIT certificate structure for a reply
type KRB_PA_PK_AS_Rep = record {
string_meta : ASN1EncodingMeta;
elem_0_meta1: ASN1EncodingMeta;
string_meta : ASN1EncodingMeta;
elem_0_meta1 : ASN1EncodingMeta;
seq_meta1 : ASN1EncodingMeta;
elem_0_meta2: ASN1EncodingMeta;
elem_0_meta2 : ASN1EncodingMeta;
seq_meta2 : ASN1EncodingMeta;
oid : ASN1Encoding;
elem_0_meta3: ASN1EncodingMeta;
oid : ASN1Encoding;
elem_0_meta3 : ASN1EncodingMeta;
seq_meta3 : ASN1EncodingMeta;
version : ASN1Encoding;
digest_algs : ASN1Encoding;
@ -71,6 +207,6 @@ type KRB_PA_PK_AS_Rep = record {
cert_meta : ASN1EncodingMeta;
cert : bytestring &length=cert_meta.length;
# Ignore everything else
: bytestring &restofdata &transient;
: bytestring &restofdata &transient;
};

View file

@ -18,7 +18,7 @@ type KRB_PDU_TCP = record {
type KRB_PDU = record {
app_meta : ASN1EncodingMeta;
msg_type : case (app_meta.tag - 96) of {
msg_type : case (app_meta.tag - ASN1_APP_TAG_OFFSET) of {
AS_REQ -> as_req : KRB_AS_REQ;
AS_REP -> as_rep : KRB_AS_REP;
TGS_REQ -> tgs_req : KRB_TGS_REQ;
@ -188,7 +188,7 @@ type KRB_ERROR_Arg_Data(index: uint8, error_code: int64) = case index of {
12 -> e_data : KRB_ERROR_E_Data(error_code);
};
type KRB_ERROR_E_Data(error_code: uint64) = case ( error_code == 25 ) of {
type KRB_ERROR_E_Data(error_code: uint64) = case ( error_code == KDC_ERR_PREAUTH_REQUIRED ) of {
true -> padata : KRB_PA_Data_Sequence(KRB_ERROR);
false -> unknown : bytestring &restofdata;
};

View file

@ -1,5 +1,89 @@
# Fundamental KRB types
%header{
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname);
VectorVal* proc_cipher_list(const Array* list);
VectorVal* proc_host_address_list(const KRB_Host_Addresses* list);
VectorVal* proc_tickets(const KRB_Ticket_Sequence* list);
%}
%code{
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname)
{
if ( pname->data()->size() == 1 )
return bytestring_to_val(pname->data()[0][0]->encoding()->content());
if ( pname->data()->size() == 2 )
return new StringVal(fmt("%s/%s", (char *) pname->data()[0][0]->encoding()->content().begin(), (char *)pname->data()[0][1]->encoding()->content().begin()));
return new StringVal("unknown");
}
VectorVal* proc_cipher_list(const Array* list)
{
VectorVal* ciphers = new VectorVal(internal_type("index_vec")->AsVectorType());
for ( uint i = 0; i < list->data()->size(); ++i )
ciphers->Assign(ciphers->Size(), asn1_integer_to_val((*list->data())[i], TYPE_COUNT));
return ciphers;
}
VectorVal* proc_host_address_list(const KRB_Host_Addresses* list)
{
VectorVal* addrs = new VectorVal(internal_type("KRB::Host_Address_Vector")->AsVectorType());
for ( uint i = 0; i < list->addresses()->size(); ++i )
{
RecordVal* addr = new RecordVal(BifType::Record::KRB::Host_Address);
KRB_Host_Address* element = (*list->addresses())[i];
switch ( binary_to_int64(element->addr_type()->encoding()->content()) )
{
case 2:
addr->Assign(0, new AddrVal(IPAddr(IPv4,
(const uint32_t*) c_str(element->address()->data()->content()),
IPAddr::Network)));
break;
case 24:
addr->Assign(0, new AddrVal(IPAddr(IPv6,
(const uint32_t*) c_str(element->address()->data()->content()),
IPAddr::Network)));
break;
case 20:
addr->Assign(1, bytestring_to_val(element->address()->data()->content()));
break;
default:
RecordVal* unk = new RecordVal(BifType::Record::KRB::Type_Value);
unk->Assign(0, asn1_integer_to_val(element->addr_type(), TYPE_COUNT));
unk->Assign(1, bytestring_to_val(element->address()->data()->content()));
addr->Assign(2, unk);
break;
}
addrs->Assign(addrs->Size(), addr);
}
return addrs;
}
VectorVal* proc_tickets(const KRB_Ticket_Sequence* list)
{
VectorVal* tickets = new VectorVal(internal_type("KRB::Ticket_Vector")->AsVectorType());
for ( uint i = 0; i < list->tickets()->size(); ++i )
{
KRB_Ticket* element = (*list->tickets())[i];
RecordVal* ticket = new RecordVal(BifType::Record::KRB::Ticket);
ticket->Assign(0, asn1_integer_to_val(element->tkt_vno()->data(), TYPE_COUNT));
ticket->Assign(1, bytestring_to_val(element->realm()->data()->content()));
ticket->Assign(2, GetStringFromPrincipalName(element->sname()));
ticket->Assign(3, asn1_integer_to_val(element->enc_part()->etype()->data(), TYPE_COUNT));
tickets->Assign(tickets->Size(), ticket);
}
return tickets;
}
%}
type KRB_Principal_Name = record {
seq_meta : ASN1EncodingMeta;
name_meta : ASN1EncodingMeta;