windows-nt/Source/XPSP1/NT/ds/security/protocols/kerberos/parser/kerbparser.c

1980 lines
68 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
//=============================================================================
// MODULE: Kerbparser.c
//
// Description:
//
// Bloodhound Parser DLL for Kerberos Authentication Protocol
//
// Modification History
//
// Michael Webb & Kris Frost Date: 06/04/99
//=============================================================================
#define MAINPROG
#include "kerbparser.h"
#include "kerbGlob.h"
#include "kdcreq.h"
#include "kdcrep.h"
#include "krberr.h"
#include <stdio.h>
;// Need to find out why error is generated without this semicolon
//=============================================================================
// Forward references.
//=============================================================================
VOID WINAPIV KerberosFormatSummary(LPPROPERTYINST lpPropertyInst);
//=============================================================================
// Protocol entry points.
//=============================================================================
VOID WINAPI KerberosRegister(HPROTOCOL);
VOID WINAPI KerberosDeregister(HPROTOCOL);
LPBYTE WINAPI KerberosRecognizeFrame(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL, DWORD, LPDWORD, LPHPROTOCOL, PDWORD_PTR);
LPBYTE WINAPI KerberosAttachProperties(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL, DWORD, DWORD_PTR);
DWORD WINAPI KerberosFormatProperties(HFRAME, LPVOID, LPVOID, DWORD, LPPROPERTYINST);
ENTRYPOINTS KerberosEntryPoints =
{
KerberosRegister,
KerberosDeregister,
KerberosRecognizeFrame,
KerberosAttachProperties,
KerberosFormatProperties
};
HPROTOCOL hKerberos = NULL;
DWORD Attached = 0;
PPF_PARSERDLLINFO WINAPI ParserAutoInstallInfo()
{
PPF_PARSERDLLINFO pParserDllInfo;
PPF_PARSERINFO pParserInfo;
DWORD NumProtocols, NumHandoffs;
PPF_HANDOFFSET pHandoffSet;
PPF_HANDOFFENTRY pHandoffEntry;
// Base structure ========================================================
// Allocate memory for parser info:
NumProtocols = 1;
pParserDllInfo = (PPF_PARSERDLLINFO)HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof( PF_PARSERDLLINFO ) +
NumProtocols * sizeof( PF_PARSERINFO) );
if( pParserDllInfo == NULL)
{
return NULL;
}
// fill in the parser DLL info
pParserDllInfo->nParsers = NumProtocols;
// fill in the individual parser infos...
// BLRPLATE ==============================================================
pParserInfo = &(pParserDllInfo->ParserInfo[0]);
sprintf( pParserInfo->szProtocolName, "KERBEROS" );
sprintf( pParserInfo->szComment, "Kerberos Authentication Protocol" );
sprintf( pParserInfo->szHelpFile, "");
// the incoming handoff set ----------------------------------------------
// allocate
NumHandoffs = 2;
pHandoffSet = (PPF_HANDOFFSET)HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof( PF_HANDOFFSET ) +
NumHandoffs * sizeof( PF_HANDOFFENTRY) );
if( pHandoffSet == NULL )
{
// just return early
return pParserDllInfo;
}
// fill in the incoming handoff set
pParserInfo->pWhoHandsOffToMe = pHandoffSet;
pHandoffSet->nEntries = NumHandoffs;
// UDP PORT 88
pHandoffEntry = &(pHandoffSet->Entry[0]);
sprintf( pHandoffEntry->szIniFile, "TCPIP.INI" );
sprintf( pHandoffEntry->szIniSection, "UDP_HandoffSet" );
sprintf( pHandoffEntry->szProtocol, "KERBEROS" );
pHandoffEntry->dwHandOffValue = 88;
pHandoffEntry->ValueFormatBase = HANDOFF_VALUE_FORMAT_BASE_DECIMAL;
// TCP PORT 88
pHandoffEntry = &(pHandoffSet->Entry[1]);
sprintf( pHandoffEntry->szIniFile, "TCPIP.INI" );
sprintf( pHandoffEntry->szIniSection, "TCP_HandoffSet" );
sprintf( pHandoffEntry->szProtocol, "KERBEROS" );
pHandoffEntry->dwHandOffValue = 88;
pHandoffEntry->ValueFormatBase = HANDOFF_VALUE_FORMAT_BASE_DECIMAL;
return pParserDllInfo;
}
//=============================================================================
// FUNCTION: DLLEntry()
//
// Modification History
//
// Michael Webb & Kris Frost Date: 06/04/99
//=============================================================================
BOOL WINAPI DLLEntry(HANDLE hInstance, ULONG Command, LPVOID Reserved)
{
//=========================================================================
// If we are loading!
//=========================================================================
if ( Command == DLL_PROCESS_ATTACH )
{
if ( Attached++ == 0 )
{
hKerberos = CreateProtocol("KERBEROS", &KerberosEntryPoints, ENTRYPOINTS_SIZE);
}
}
//=========================================================================
// If we are unloading!
//=========================================================================
if ( Command == DLL_PROCESS_DETACH )
{
if ( --Attached == 0 )
{
DestroyProtocol(hKerberos);
}
}
return TRUE; //... Bloodhound parsers ALWAYS return TRUE.
}
//=============================================================================
// FUNCTION: KerberosRegister()
//
// Modification History
//
// Michael Webb & Kris Frost Date: 06/04/99
//=============================================================================
VOID WINAPI KerberosRegister(HPROTOCOL hKerberosProtocol)
{
register DWORD i;
//=========================================================================
// Create the property database.
//=========================================================================
CreatePropertyDatabase(hKerberosProtocol, nKerberosProperties);
for(i = 0; i < nKerberosProperties; ++i)
{
AddProperty(hKerberosProtocol, &KerberosDatabase[i]);
}
// Here we are checking to see whether TCP or UDP is being used.
hTCP = GetProtocolFromName("TCP");
hUDP = GetProtocolFromName("UDP");
}
//=============================================================================
// FUNCTION: Deregister()
//
// Modification History
//
// Michael Webb & Kris Frost Date: 06/04/99
//=============================================================================
VOID WINAPI KerberosDeregister(HPROTOCOL hKerberosProtocol)
{
DestroyPropertyDatabase(hKerberosProtocol);
}
//=============================================================================
// FUNCTION: KerberosRecognizeFrame()
//
// Modification History
//
// Michael Webb & Kris Frost Date: 06/04/99
//=============================================================================
LPBYTE WINAPI KerberosRecognizeFrame(HFRAME hFrame, //... frame handle.
LPBYTE MacFrame, //... Frame pointer.
LPBYTE KerberosFrame, //... Relative pointer.
DWORD MacType, //... MAC type.
DWORD BytesLeft, //... Bytes left.
HPROTOCOL hPreviousProtocol, //... Previous protocol or NULL if none.
DWORD nPreviousProtocolOffset, //... Offset of previous protocol.
LPDWORD ProtocolStatusCode, //... Pointer to return status code in.
LPHPROTOCOL hNextProtocol, //... Next protocol to call (optional).
PDWORD_PTR InstData) //... Next protocol instance data.
{
// ProtoInfo=GetProtocolInfo(hPreviousProtocol);
// MessageBox(NULL, _itoa(TestForUDP,test,10),"TestForUDP 1", MB_OK);
*ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED;
return NULL;
}
//=============================================================================
// FUNCTION: KerberosAttachProperties()
//
// Modification History
//
// Michael Webb & Kris Frost Date: 06/04/99
//=============================================================================
LPBYTE WINAPI KerberosAttachProperties(HFRAME hFrame,
LPBYTE Frame,
LPBYTE KerberosFrame,
DWORD MacType,
DWORD BytesLeft,
HPROTOCOL hPreviousProtocol,
DWORD nPreviousProtocolOffset,
DWORD_PTR InstData)
{
// Local variable to hold the value of KerberosFrame, depending on whether
// the packet is TCP or UDP.
LPBYTE pKerberosFrame;
/* kf Here checking to see if first two octets of are equal to 00 00 which would be
the case should the packet be the first of TCP.
*/
if(KerberosFrame[0] == 0x00 && KerberosFrame[1] == 0x00)
{
TempFrame = KerberosFrame+4;
pKerberosFrame = TempFrame;
}
else
{
TempFrame = KerberosFrame;
pKerberosFrame = TempFrame;
}
// Here we are going to do a check to see if the packet is TCP and
// check to see if the first two octets of the packet don't have the
// value of 00 00. If not, then we mark the frame as a continuation
// packet. Reason for doing this is because, sometimes 0x1F of the
// first packet can still match one of the case statements which
// erroneously displays a continuation packet.
// NOTE: THIS CODE BREAKS ON SOME OF THE OLDER SNIFFS BECAUSE THE 4
// OCTETS WHICH SPECIFY THE ENTIRE PACKET LENGTH WERE SENT IN A TCP
// PACKET ALL BY ITSELF. ACCORDING TO DEV, THIS ISN'T EXPECTED BEHAVIOR
// IN THE LATER W2K BUILDS. THE 4 LENGTH OCTETS FOR TCP SHOULD ALWAYS BE
// PRE-PENDED TO THE FIRST TCP PACKET
if( hPreviousProtocol == hTCP && KerberosFrame[0] != 0 && KerberosFrame[1] != 0 )
{
// Displaying as a continutation packet
AttachPropertyInstance(hFrame,
KerberosDatabase[KerberosDefaultlbl].hProperty,
BytesLeft,
TempFrame,
0, 0, 0);
}
else
{
// pKerberosFrame is a local variable and is used
// to display TCP data as well.
switch (*(pKerberosFrame) & 0x1F)
{
case ASN1_KRB_AS_REQ:
case ASN1_KRB_TGS_REQ:
TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft);
TempFrame=KdcRequest(hFrame, TempFrame);
break;
case ASN1_KRB_AS_REP:
case ASN1_KRB_TGS_REP:
TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft);
TempFrame=KdcResponse(hFrame, TempFrame);
break;
case ASN1_KRB_AP_REQ:
TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft);
break;
case ASN1_KRB_AP_REP:
TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft);
break;
case ASN1_KRB_SAFE:
TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft);
break;
case ASN1_KRB_PRIV:
TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft);
break;
case ASN1_KRB_CRED:
TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft);
break;
case ASN1_KRB_ERROR:
TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft);
TempFrame=KrbError(hFrame, TempFrame);
break;
default:
AttachPropertyInstance(hFrame,
KerberosDatabase[KerberosDefaultlbl].hProperty,
BytesLeft,
TempFrame,
0, 0, 0);
break;
}
}
return (LPBYTE) KerberosFrame + BytesLeft;
}
//==============================================================================
// FUNCTION: KerberosFormatProperties()
//
// Modification History
//
// Michael Webb & Kris Frost Date: 06/04/99
//==============================================================================
DWORD WINAPI KerberosFormatProperties(HFRAME hFrame,
LPBYTE MacFrame,
LPBYTE FrameData,
DWORD nPropertyInsts,
LPPROPERTYINST p)
{
//=========================================================================
// Format each property in the property instance table.
//
// The property-specific instance data was used to store the address of a
// property-specific formatting function so all we do here is call each
// function via the instance data pointer.
//=========================================================================
// kf Doing a check here for TCP packets. If it's the first packet,
// we increment FrameData by 4 to get past the length header
if(*FrameData == 0x00 && *(FrameData+1) == 0x00)
FrameData+=4;
while (nPropertyInsts--)
{
switch (*FrameData & 0x1F)
{
case ASN1_KRB_AS_REQ:
strcpy(MsgType, "KRB_AS_REQ");
break;
case ASN1_KRB_AS_REP:
strcpy(MsgType, "KRB_AS_REP");
break;
case ASN1_KRB_TGS_REQ:
strcpy(MsgType, "KRB_TGS_REQ");
break;
case ASN1_KRB_TGS_REP:
strcpy(MsgType, "KRB_TGS_REP");
break;
case ASN1_KRB_AP_REQ:
strcpy(MsgType, "KRB_AP_REQ");
break;
case ASN1_KRB_AP_REP:
strcpy(MsgType, "KRB_AP_REP");
break;
case ASN1_KRB_SAFE:
strcpy(MsgType, "KRB_SAFE");
break;
case ASN1_KRB_PRIV:
strcpy(MsgType, "KRB_PRIV");
break;
case ASN1_KRB_CRED:
strcpy(MsgType, "KRB_CRED");
break;
case ASN1_KRB_ERROR:
strcpy(MsgType, "KRB_ERROR");
break;
default:
strcpy(MsgType, "Didn't recognize");
break;
}
((FORMAT) p->lpPropertyInfo->InstanceData)(p);
p++;
}
return NMERR_SUCCESS;
}
LPBYTE EntryFrame(HFRAME hFrame, LPBYTE KerberosFrame, DWORD BytesLeft)
{
int LenVal = 0;
TempFrame=KerberosFrame;
AttachPropertyInstance(hFrame,
KerberosDatabase[KerberosSummary].hProperty,
BytesLeft,
TempFrame,
0, 0, 0);
AttachPropertyInstance(hFrame,
KerberosDatabase[KerberosIDSummary].hProperty,
sizeof(BYTE),
TempFrame,
0, 1, 0);
// Adding Code here to display Summary, thus letting us indent the ASN breakdown of the
// Identifier Octets to where the user won't initially see this.
AttachPropertyInstance(hFrame,
KerberosDatabase[DispSummary].hProperty,
0,
TempFrame,
0, 2, 0);
// Break down the Identifier Octet for Message Type
TempFrame=CalcMsgType(hFrame, TempFrame, 3, KerberosIdentifier);
// Display Length Octet
TempFrame=CalcLengthSummary(hFrame, TempFrame, 3);
// Adjust TempFrame the appropriate # of octets
LenVal=CalcLenOctet(TempFrame-1);
// This code handles incrementing to the proper octet based
// on the number of octets occupied by TempFrame.
if(LenVal <= 1)
return TempFrame;
else
return TempFrame+=(LenVal-1);
}
/*************************************************************************************
**
**
** This function handles: pa-data ::= SEQUENCE{
** padata-type[1] INTEGER,
** padata-value[2] OCTET STRING
** }
** hFrame = Handle to the frame.
**
** TempFrame = Offset we which we are at in the current packet
**
** OffSet = The indention level to display the data within Netmon
**
** TypeVal = Variable used to identify node from KerberosDatabase[]
**
************************************************************************************/
LPBYTE HandlePaData(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
{
int TempLength;
int lValueReqPadata = 0;
//Display Padata[?] NEED TO CHANGE THIS FUNCTION TO PASS THE PARAMETERS SO THE FUNCTION
// WILL DISPLAY THE PROPER PADATA
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, KdcReqTagID, KdcReqSeq);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
//Display SEQUENCE OF
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5);
/* Incrementing TempFrame based on the number of octets
taken up by the Length octet
*/
TempFrame = IncTempFrame(TempFrame);
//Display SEQUENCE OF
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Display padata-type[1]
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, PaDataSummary, PaDataSeq);
// Display INTEGER value
TempFrame =DispPadata(hFrame, TempFrame, OffSet+4, PadataTypeValID);
// Display padata-value[2]
DispASNTypes(hFrame, TempFrame, OffSet+2, PaDataSummary, PaDataSeq);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, ++TempFrame, OffSet+5);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
//Display OCTET STRING
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+7);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// HERE IT LOOKS AS IF AN AS-REQ, PADATA-VALUE IS FORMATTED AS ENCRYPTEDDATA
// AND TGS IS FORMATTED AS AP-REQ. HOWEVER, IF A SMART CARD IS PRESENT, IT IS
// FORMATTED AS.
// Check to see if formatted as AP-REQ (6E)
if(*(TempFrame+1) == 0x6E )
TempFrame = HandleAPReq(hFrame, TempFrame); // If true, handle AP-REQ traffic
else if(*(TempFrame+1) == 0x81)
{// Here I'm incrementing TempFrame by two to get it to the first
// offset making up the Length Octet.
TempFrame++;
// Here I'm going to label the rest of the data as a Certificate
TempLength = CalcMsgLength(TempFrame);
AttachPropertyInstance(hFrame,
KerberosDatabase[Certificatelbl].hProperty,
TempLength,
TempFrame,
0, OffSet+4, 0);
// Increment TempFrame by the length octet value returned by CalcMsgLength
TempFrame+=TempLength;
// Pretty sloppy hack here but hoping Dev will supply me doc
// of how the certificate is structured in ASN.1. For the time
// being, CalcMsgLength doesn't take us to the end of padata and the
// start of KDC-Req-Body. With no idea of what the A1 and A2 tags I see
// in the smart card sniff. I don't know if it will possibly ever contain
// an A4. But at anyrate, I'm going to increase TempFrame by one until
// a value of A4 is matched. (This signifies the start of KDC-Req-Body.)
while(*TempFrame != 0xA3)
{
++TempFrame;
}
// Once TempFrame is A4, have to decrement TempFrame by one
// in order for KDC-Req-Body to start on the correct offset.
// Again this whole else statement is a Kludge but not much I can
// until I get the ASN.1 layout of Certificates.
--TempFrame;
}
else
{
//Display SEQUENCE OF
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+7);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
if(*(TempFrame+1) == 0xA0)
{
// Handle EncryptedData
TempFrame = HandleEncryptedData( hFrame, TempFrame, OffSet+2);
}
// kfrost 11/12 In smart card the value here is 0x80 or 0x81 in as-req & as-rep respectively.
// Can not find out or get Dev to produce the appropriate ASN.1 format that is being
// followed here. Basically, whatever encoding layout that is being followed, the first
// parameter is 06 Object Identifier. The only thing I have found is KERB-ALGORITHM-IDENTIFIER
// found in krb5.asn. Until I get some assistance walking through the offsets, I'm going to label
// the data as PKCS and increment TempFrame past all of this and start parsing again at KDC-Req-Body
else
{
if(*(TempFrame+1) == 0x80)
{
// Here I'm incrementing TempFrame by two to get it to the first
// offset making up the Length Octet.
TempFrame++;
// Here I'm going to label the rest of the data as a Certificate
TempLength = CalcMsgLength(TempFrame);
AttachPropertyInstance(hFrame,
KerberosDatabase[Certificatelbl].hProperty,
TempLength,
TempFrame,
0, OffSet+4, 0);
// Increment TempFrame by the length octet value returned by CalcMsgLength
TempFrame+=TempLength;
// Pretty sloppy hack here but hoping Dev will supply me doc
// of how the certificate is structured in ASN.1. For the time
// being, CalcMsgLength doesn't take us to the end of padata and the
// start of KDC-Req-Body. With no idea of what the A1 and A2 tags I see
// in the smart card sniff. I don't know if it will possibly ever contain
// an A4. But at anyrate, I'm going to increase TempFrame by one until
// a value of A4 is matched. (This signifies the start of KDC-Req-Body.)
while(*TempFrame != 0xA4)
{
++TempFrame;
}
// Once TempFrame is A4, have to decrement TempFrame by one
// in order for KDC-Req-Body to start on the correct offset.
// Again this whole else statement is a Kludge but not much I can
// until I get the ASN.1 layout of Certificates.
--TempFrame;
}
}
}
// Not going to display anymore padata after this point. padata[3] is a
// SequenceOf. Any repetition traffic will get highlighted and TempFrame will
// be incremented to the appropriate frame which starts req-body[4]
while(*(TempFrame+1) == 0x30)
{
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+7);
// Adjust TempFrame to the appropriate octet
TempFrame+=(CalcMsgLength(--TempFrame)+1);
}
return TempFrame;
}
LPBYTE HandleEncryptedData(HFRAME hFrame, LPBYTE TempFrame, int OffSet)
{
int size = 0;
int value = 0;
// Display Encryption Type
TempFrame = DefineEtype(hFrame, TempFrame, OffSet+2, DispSumEtype2, EncryptedDataTag, EncryptedDataTagBitF);
// Display Kvno[1] OPTIONAL
if(*TempFrame == 0xA1)
{
// KF LEFT OFF HERE. CLEAN UP CODE TO DISPLAY KVNO CORRECT
// Display Universal Class Tag
TempFrame = DispASNTypes(hFrame, --TempFrame, OffSet+2, EncryptedDataTag, EncryptedDataTagBitF);
// Need to finish handling kvno[1]
// Display INTEGER value
TempFrame =DispPadata(hFrame, TempFrame, OffSet+4, PadataTypeValID);
// The following increments TempFrame by 1 to get to the cipher[2] octet, however
// it doesn't take into account if the integer value takes up more than one octet.
++TempFrame;
}
// Display cipher[2]
TempFrame = DispASNTypes(hFrame, --TempFrame, OffSet+2, EncryptedDataTag, EncryptedDataTagBitF);
// Determing the size of cipher[2]
size = CalcMsgLength(TempFrame);
// Determine whether Length Octet is short or long to
// use in incrementing TempFrame in return value
value = *(TempFrame+1);
// Display Length Octet(s) and highlight cipher text
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5);
// The following return takes the offset to the end of cipher[2]. If
// value is equal to 0x81 then the length octet was short form
// else it's long form so add to size to TempFrame. If long from assumming
// length octet will be 2.
if(value <= 0x81)
{
return TempFrame+=(size);
}
else
{
return TempFrame+=(size+1);
}
}
// This function is used to break down Identifier Octets and display their types
LPBYTE CalcMsgType(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal )
{
AttachPropertyInstance(hFrame,
KerberosDatabase[KerberosClassTag].hProperty,
sizeof(BYTE),
TempFrame,
0, OffSet, 0);
AttachPropertyInstance(hFrame,
KerberosDatabase[PCIdentifier].hProperty,
sizeof(BYTE),
TempFrame,
0, OffSet, 0);
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
sizeof(BYTE),
TempFrame,
0, OffSet, 0);
return TempFrame;
}
LPBYTE CalcLengthSummary(HFRAME hFrame, LPBYTE TempFrame, int OffSet)
{
// Check the first bit of the length octet to see if length is short form (Value 0)
// or Long Form (Value is 1)
if(*(++TempFrame) & 0x80)
{
// This code handles long form. Bits 7-1 of this octet give the number of additional
// octets associated with this length octet. We need some type of checking after the last
// octet in length to determine if the next octet is an Identifier or Contents.
// The additional octets specified in bits 7-1 of the first octet give the length.
LongSize = *(TempFrame) & 0x7F; // Assign LongSize to the value of bits 7-1
lValueRepMsg = CalcMsgLength(TempFrame-1);
AttachPropertyInstance(hFrame,
KerberosDatabase[LengthSummary].hProperty,
sizeof(BYTE)+LongSize, // This highlights all bits associated with Length
TempFrame,
0, OffSet, 0);
AttachPropertyInstance(hFrame,
KerberosDatabase[LengthFlag].hProperty, // Will display short or Long
sizeof(BYTE),
TempFrame,
0, OffSet+1, 0);
AttachPropertyInstanceEx(hFrame,
KerberosDatabase[LengthBits].hProperty, // Shows how many octets used in Length
sizeof(BYTE),
TempFrame,
1,
&LongSize,
0, OffSet+1, 0);
if(LongSize > 1)
AttachPropertyInstance(hFrame,
KerberosDatabase[LongLength1].hProperty,
LongSize,
TempFrame+=1,
0, OffSet+1, 0);
else
AttachPropertyInstance(hFrame,
KerberosDatabase[LongLength2].hProperty,
LongSize,
TempFrame+=1,
0, OffSet+1, 0);
}
else
{ // Assuming this code is to handle short form.
lValueRepMsg = CalcMsgLength(TempFrame-1);
AttachPropertyInstance(hFrame,
KerberosDatabase[KdcReqSeqLength].hProperty,
sizeof(BYTE)+lValueRepMsg,
TempFrame,
0, OffSet, 0);
}
return TempFrame;
}
LPBYTE DefineValue(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
{
BYTE Size[4];
PBYTE lSize = (PBYTE)&Size;
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+2);
// Need to advance TempFrame the proper # of frames.
TempFrame = IncTempFrame(TempFrame);
// Display Universal Class Tag
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3);
// Need to advance TempFrame the proper # of frames.
TempFrame = IncTempFrame(TempFrame);
// Code below is used to display Integer values if they occupy more than 2 octets
if (*(TempFrame) == 3)
{
memcpy(lSize, TempFrame, 4);
*lSize = *lSize & 0xffffff00;
// Prints out Value. Need to change the Array to give better description
AttachPropertyInstanceEx(hFrame,
KerberosDatabase[TypeVal].hProperty,
*(TempFrame-1),
++TempFrame,
*(TempFrame) == 3 ? 4 : *(TempFrame),
lSize,
0, OffSet, 0);
}
else
{
// Prints out Value. Need to change the Array to give better description
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
*(TempFrame-1),
++TempFrame,
0, OffSet+1, 0);
}
// kf 8/16 This wasn't returning to the proper octet in some cases
return (TempFrame-1)+*(TempFrame-1);
}
/* This is spinoff of DefineValue. However, this code has been modified
to handle displaying the ASN.1 breakdown of etype[?]
*/
LPBYTE DefineEtype(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal, DWORD TypeVal2, DWORD TypeVal3)
{
// Display Universal Class Tag
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, TypeVal2, TypeVal3);
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
while(*(++TempFrame) == 0x02)
{
--TempFrame;
TempFrame = DispSum(hFrame, TempFrame, 0x02, 0x02, OffSet, DispSumEtype2);
// Display Unversal Class Tag
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5);
// Increment TempFrame according to length octet
TempFrame+=CalcMsgLength(--TempFrame);
++TempFrame;
// Display First Encryption Type
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
1,
TempFrame,
0, OffSet+4, 0);
}
return TempFrame;
}
int CalcMsgLength(LPBYTE TempFrame)
{
if(*(TempFrame+1) & 0x80)
{
LongSize = *(TempFrame+1) & 0x7F;
if(LongSize > 1)
// Here we are or'd the two values of the length octets together
// Note this could fail if the Length octet ever took up more than
// two octets in defining a length
return (*(TempFrame+3)) | (*(TempFrame+2) << 8);
else
// This is in case the length octet only had one following defining octet
return (BYTE) *(TempFrame+2);
}
else
// For a short form Length octet
return *(TempFrame+1) & 0x7F;
}
/***********************************************************************************************************
**
** This function will break down ASN.1 PrincipalName.
** PrincipalName ::= SEQUENCE{
** name-type[0] INTEGER, Specifies the type of name that follows.
** Pre-defined values for this field are specified in
** section 7.2.
**
** name-string[1] SEQUENCE OF GeneralString Encodes a sequence of components
** that form a name, each component
** encoded as a GeneralString. Taken
** together, a PrincipalName and a Realm
** form a principal Identifier.
**
**************************************************************************************************************/
LPBYTE DefinePrincipalName(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
{
// This functions starts breaking down the A0 octet of a PrincipalName
// Print out name-type[0] of PrincipalName
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, KrbPrincipalNamelSet, KrbPrincipalNamelBitF);
// Display octets associated with INTEGER
TempFrame = DefineValue(hFrame, TempFrame, OffSet+2, KrbPrincNameType);
// End code to display name-type[0] of PrincipalName
// Print out name-string[1] of PrincipalName
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, KrbPrincipalNamelSet, KrbPrincipalNamelBitF);
// Display Length Summary
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+2);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Display SEQUENCE
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag);
// Print out Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Checking for GeneralString 0x1B
TempRepGString = *(++TempFrame) & 0x1F;
while(TempRepGString == 0x1B)
{
//Display GeneralString
TempFrame = DispASNTypes(hFrame, --TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag);
// Calculate the size of the Length Octet
lValueRepMsg = CalcMsgLength(TempFrame);
//Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+4);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
sizeof(BYTE)+(lValueRepMsg - 1),
++TempFrame,
0, OffSet+3, 0);
// Assign TempRepGString to value of octet after the string to see if another SEQUENCE OF
// GeneralString exists.
TempRepGString = *(TempFrame+=lValueRepMsg) & 0x1F;
}
// End Code to display name-string[1]
return TempFrame;
}
// Function used parse Length octets in PrincipalName
int CalcLenOctet(LPBYTE TempFrame)
{
int size = 0;
// If long form, assign size to value of bits 7-1
if(*(TempFrame) & 0x80)
size = (*(TempFrame) & 0x7F);
else
// Short form, only takes one octet
size = 1;
return size;
}
/**********************************************************************************************
**
** LPBYTE DispASNTypes(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal, DWORD TypeVal2)
**
** This function is used to break down and display the ASN.1 Universal Tags.
** (Universal Tag Allocations can be found at page 155 in ASN.1 by Douglas Steedman.)
**
** hFrame - Handle to the fram
** TempFrame - Pointer to the current offset in the packet
** Offset - Used for indenting the parser display
** TypeVal - Used to distinguish which node out of the KerberosDatbase to use
** TypeVal2 - Same use as TypeVal
**
**********************************************************************************************/
LPBYTE DispASNTypes(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal, DWORD TypeVal2)
{
// Assign the value of last 5 bits to TempAsnMsg
TempAsnMsg = *(++TempFrame) & 0x1F;
// Calculates the length octet to see how many octets should be highlighted
lValueRepMsg = CalcMsgLength(TempFrame);
// Display the Identifier and the appropriate # of octets are highlighted
AttachPropertyInstanceEx(hFrame,
KerberosDatabase[TypeVal].hProperty,
sizeof(WORD) + lValueRepMsg,
TempFrame,
1,
&TempAsnMsg,
0, OffSet, 0);
// Adding Code here to display Summary, thus letting us indent the ASN breakdown of the
// Identifier Octets to where the user won't initially see this.
AttachPropertyInstance(hFrame,
KerberosDatabase[DispSummary].hProperty,
0,
TempFrame,
0, OffSet+1, 0);
// Break out the identifier octet to ASN.1 format
TempFrame=CalcMsgType(hFrame, TempFrame, OffSet+2, TypeVal2);
return TempFrame;
}
LPBYTE DispSeqOctets(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal, DWORD TypeVal2)
{
// Display SEQUENCE (First frame we handle in this file.
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, TypeVal, TypeVal2);
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3);
return TempFrame;
}
/***********************************************************************************************************
**
** This function will break down ASN.1 HostAddresses. P39 rfc 1510
** HostAddresses::= SEQUENCE OF SEQUENCE{
** addr-type[0] INTEGER,
** address[1] OCTET STRING,
** }
**
**
**
**
**
**
**************************************************************************************************************/
LPBYTE DispHostAddresses(HFRAME hFrame, LPBYTE TempFrame, int OffSet)
{
// Determine the number of octets occupied by the length ocet
lValueRepMsg = CalcLenOctet(TempFrame);
// Checking for SEQUENCE OF 0x30
TempReq = *(TempFrame+lValueRepMsg);
// while loop is calculate SEQUENCE OF SEQUENCE
while(TempReq == 0x30)
{
// Display SEQUENCE Octets
TempFrame = DispSeqOctets(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag);
// Display addr-type[0]
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, HostAddressesID, HostAddressesBitF);
// Calculate the size of the Length Octet
lValueRepMsg = CalcMsgLength(TempFrame);
// Display INTEGER
TempFrame = DefineValue(hFrame, TempFrame, OffSet+4, KdcContentsValue);
// Display address[1]
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, HostAddressesID, HostAddressesBitF);
// Display String value
TempFrame = DefineValue(hFrame, TempFrame, OffSet+4, DispString);
TempReq = *(TempFrame+lValueRepMsg);
}
return TempFrame;
}
LPBYTE DispSum(HFRAME hFrame, LPBYTE TempFrame, int ClassValue, int ClassValue2, int OffSet, DWORD TypeVal)
{
/* Working here now to display info name at the top. Will indent everything
else 1 to the right. Not sure how well this is going to work since name-string[1]
is a SEQUENCE OF. Writing code now to assume there is only going to be one name
and display the first one.
*/
TempFrameReq = (TempFrame+1);
TempFrameReq2 = (TempFrame+2);
// This while statement increments TempFrameReq until 1B is reached
// If 1B is ever used in a length octet or elsewhere this will fail.
// Might look at doing a memcopy later on to a global variable
// THINK WE CAN USE BERGETSTRING TO DISPLAY FULL SERVER NAME. WE CAN
// USE A STRING CONSTANTS WITH TO DISPLAY THE FULL VALUE.
// Incrementing TempFrameReq until String is found
while(*(TempFrameReq) != ClassValue || *(TempFrameReq2) == ClassValue2)
{
TempFrameReq++;
TempFrameReq2++;
// Trying to come up with a way to make sure the Length Value doesn't == ClassValue
// Still need some type of checking in case the length octet's value after the SEQUENCE OF
// turns out to be equal to ClassValue.
if(*(TempFrameReq) == ClassValue && *(TempFrameReq2) == ClassValue2)
{
TempFrameReq++;
TempFrameReq2++;
// Checking to see if Length Octet's value after SEQUENCE OF is equal to ClassValue. If so,
// incrementing TempFrameReq in order to get to the correct offset.
if(*(TempFrameReq) == ClassValue2 && *(TempFrameReq2) == ClassValue)
{
TempFrameReq++;
TempFrameReq2++;
}
}
}
if(ClassValue2 == 0x02)
{// Put this if statement to handle highlighting the appropriate # of
// Octets for EType. Don't know how valid this is going to be but trying
// to get all the code in. Will worry about later.
// Calculate the value of the length octet
lValueReq = CalcMsgLength(TempFrameReq-1);
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
1,
TempFrameReq+=2,
0, OffSet, 0);
}
else
{
// Calculate the value of the length octet
lValueReq = CalcMsgLength(TempFrameReq);
// Increment TempFrameReq to the proper Octet
TempFrameReq+=CalcLenOctet(TempFrameReq);
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
sizeof(BYTE)+(lValueReq-1),
++TempFrameReq,
0, OffSet, 0);
}
return TempFrame;
}
/****************************************************************************
**
**
** This function is used to display a top level Summary description
**
**
****************************************************************************/
LPBYTE DispTopSum(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
{
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
0,
TempFrame,
0, OffSet, 0);
return TempFrame;
}
/*********************************************************************************
**
** Another Subset of DispSum. Altering this function to gather string info
** and reformat to print out in a Date, Time format.
**
*********************************************************************************/
LPBYTE DispSumTime(HFRAME hFrame, LPBYTE TempFrame, int ClassValue, int OffSet, DWORD TypeVal)
{
char RawTimeBuf[16];
char TimeFormatBuf[TIME_FORMAT_SIZE];
LPSTR TimeFormat = TimeFormatBuf;
TempFrameReq = (TempFrame+1);
TempFrameReq2 = (TempFrame+2);
// This while statement increments TempFrameReq until 1B is reached
// If 1B is ever used in a length octet or elsewhere this will fail.
// Next loop is to find 1B value and is designed to prevent mistakenly
// going to the wrong octet in case a 1b is the value in a Length octet
// Incrementing TempFrameReq until String is found
while(*(TempFrameReq) != ClassValue || *(TempFrameReq2) == 0x30)
{
TempFrameReq++;
TempFrameReq2++;
// Trying to come up with a way to make sure the Length Value doesn't == ClassValue
// Still need some type of checking in case the length octet's value after the SEQUENCE OF
// turns out to be equal to ClassValue.
if(*(TempFrameReq) == ClassValue && *(TempFrameReq2) == 0x30)
{
TempFrameReq++;
TempFrameReq2++;
// Checking to see if Length Octet's value after SEQUENCE OF is equal to ClassValue. If so,
// incrementing TempFrameReq in order to get to the correct offset.
if(*(TempFrameReq) == 0x30 && *(TempFrameReq2) == ClassValue)
{
TempFrameReq++;
TempFrameReq2++;
}
}
}
// Calculate the value of the length octet
lValueReq = CalcMsgLength(TempFrameReq);
if( lValueReq > ((sizeof RawTimeBuf) / (sizeof RawTimeBuf[0])) )
{
memcpy( RawTimeBuf, (TempFrameReq+2), sizeof RawTimeBuf / sizeof RawTimeBuf[0] );
}
else
{
memcpy(RawTimeBuf, (TempFrameReq+2), lValueReq);
}
sprintf( TimeFormat, TIME_FORMAT_STRING,
RawTimeBuf[4], RawTimeBuf[5], // month
RawTimeBuf[6], RawTimeBuf[7], // day
RawTimeBuf[0], RawTimeBuf[1], RawTimeBuf[2], RawTimeBuf[3], // year
RawTimeBuf[8], RawTimeBuf[9], // hours
RawTimeBuf[10], RawTimeBuf[11], // minutes
RawTimeBuf[12], RawTimeBuf[13] ); // seconds
// Increment TempFrameReq to the proper Octet
TempFrameReq+=CalcLenOctet(TempFrameReq);
// Display initial Time
AttachPropertyInstanceEx( hFrame,
KerberosDatabase[TypeVal].hProperty,
lValueReq,
++TempFrameReq,
TIME_FORMAT_SIZE,
TimeFormat,
0,
OffSet,
0 );
return TempFrame;
}
/******************************************************************************
**
** Created this function to address displaying the FQDN of the server name (under KDC-Options)
** at the top level.
**
*******************************************************************************/
LPBYTE DispSumString(HFRAME hFrame, LPBYTE TempFrame, int ClassValue, int OffSet, DWORD TypeVal)
{
LPBYTE TempFrameSname, TempFrameSnameB;
int segments = 0;
int j = 0;
int ServNameCount = 0;
int lValueStr = 0;
int sizeAsString = 0;
LPSTR cServName = NULL;
LPSTR ServNameBuf[MAX_SERVER_NAME_SEGMENTS];
memset( ServNameBuf, 0, sizeof ServNameBuf );
TempFrameSname = (TempFrame+1);
TempFrameSnameB = (TempFrame+2);
// This while statement increments TempFrameReq until ClassValue is reached
// Incrementing TempFrameReq until ClassValue
while(*(TempFrameSname) != ClassValue || *(TempFrameSnameB) == 0x30)
{
TempFrameSname++;
TempFrameSnameB++;
// Trying to come up with a way to make sure the Length Value doesn't == ClassValue
// Still need some type of checking in case the length octet's value after the SEQUENCE OF
// turns out to be equal to ClassValue. 11/18. Found a situation where the first part of
// of a principal name had the length of 1B. Added the || *(TempFrameSnameB) == 0xA0 to
// handle this problem The 0xA0 is the first tag of Principal Name
if(*(TempFrameSname) == ClassValue && *(TempFrameSnameB) == 0x30 || *(TempFrameSnameB) == 0xA0)
{
TempFrameSname++;
TempFrameSnameB++;
// Checking to see if Length Octet's value after SEQUENCE OF is equal to ClassValue. If so,
// incrementing TempFrameReq in order to get to the correct offset.
if(*(TempFrameSname) == 0x30 && *(TempFrameSnameB) == ClassValue)
{
TempFrameSname++;
TempFrameSnameB++;
}
}
}
TempFrameSnameB = TempFrameSname;
while(*(TempFrameSnameB) == ClassValue)
{
if( segments >= MAX_SERVER_NAME_SEGMENTS )
{
break;
}
lValueStr = CalcMsgLength(TempFrameSnameB);
sizeAsString = lValueStr + sizeof '\0';
ServNameCount += lValueStr;
ServNameBuf[ segments ] = (LPSTR) malloc( sizeAsString );
if( ServNameBuf[ segments ] == NULL )
{
for( ; segments > 0; segments-- )
{
free( ServNameBuf[segments - 1] );
}
return TempFrame;
}
ZeroMemory( ServNameBuf[ segments ], sizeAsString );
memcpy( ServNameBuf[ segments ], TempFrameSnameB+2, lValueStr );
// Use the Length Octet to progress TempFrameReq
TempFrameSnameB+=CalcMsgLength(TempFrameSnameB);
// Need to Increment TempFrameSnameB by number of ASN.1 octets
// Increasing by two here. This could be wrong if the Length octet
// were ever in Long Form.
TempFrameSnameB+=2;
segments++;
}
cServName = (LPSTR) malloc( ServNameCount + segments );
if (NULL == cServName)
{
for( ; segments > 0; segments-- )
{
free( ServNameBuf[segments - 1] );
}
return TempFrame;
}
ZeroMemory(cServName, ServNameCount + segments );
strcpy(cServName, ServNameBuf[0]);
for( j = 1; j < segments; j++ )
{
strcat(cServName, "/");
strcat(cServName, ServNameBuf[j]);
}
AttachPropertyInstanceEx(hFrame,
KerberosDatabase[TypeVal].hProperty,
ServNameCount + 2*segments,
TempFrameSname+=2,
ServNameCount + segments,
cServName,
0, OffSet, 0);
for( ; segments > 0; segments-- )
{
free( ServNameBuf[segments - 1] );
}
if (NULL != cServName)
{
free(cServName);
}
return TempFrame;
}
/*********************************************************************************
**
**
** This function was copied from DefineValue but was created to display the
** Ticket Flags for KDC-Options in the KDC-Req packet.
**
*********************************************************************************/
LPBYTE DefineKdcOptions(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
{
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
sizeof(DWORD),
TempFrame,
0, OffSet, 0);
return (TempFrame);
}
/*****************************************************************************
* This function is used to display the initial values of padata-type[1] &
* padata-value[2] found in the AS-REQ packet
* NOTE: I LEFT *INTVAL AND THE OTHER LINES COMMENTED AS FOR IF THE INT VALUE
* TAKES UP TWO OCTETS, WE ONLY DISPLAY THE # INSTEAD OF ENCRYPTION TYPE. NOT
* WORRYING WITH THIS AT THIS TIME BUT LEAVING THE CODE IN PLACE SHOULD IT NEED
* TO BE IMPLEMENTED.
*****************************************************************************/
LPBYTE DispPadata(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
{
// Calculate Length Octet and highligh the # of octets
// BYTE *intval;
int size = 0;
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+1);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Display Universal Class Tag
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3);
//Assumming the Integer value will always be contained in
// either 1 or 2 octets.
size = *TempFrame;
// Here need to check the length octet and determine whether
// it is short or long form
if(size == 1)
{
// intval = malloc(2);
// memcpy(intval, (TempFrame+1), 2);
// Prints out Value. Need to change the Array to give better description
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
1,
++TempFrame,
0, OffSet+1, 0);
/* AttachPropertyInstanceEx(hFrame,
KerberosDatabase[TypeVal].hProperty,
1,
++TempFrame,
4,
intval,
0, OffSet, 0);
*/
}
else
{
// intval = malloc(4);
// memcpy(intval, (TempFrame+1), 4);
// *intval = *(intval) & 0xffff;
AttachPropertyInstance(hFrame,
KerberosDatabase[PaDataSummaryMulti].hProperty,
1,
++TempFrame,
0, OffSet+1, 0);
/*
// Prints out Value. Need to change the Array to give better description
AttachPropertyInstanceEx(hFrame,
KerberosDatabase[PaDataSummaryMulti].hProperty,
2,
++TempFrame,
4,
intval,
0, OffSet, 0);
*/
// Incrementing TempFrame by an extra Octet because the Integer here takes
// up 2 octets instead of one.
++TempFrame;
}
return (TempFrame);
}
LPBYTE IncTempFrame(LPBYTE TempFrame)
{
if(*(TempFrame-1) >= 0x81 && *(TempFrame-1) <= 0x84)
TempFrame+=CalcLenOctet(--TempFrame);
else
TempFrame;
return TempFrame;
}
LPBYTE HandleTicket(HFRAME hFrame, LPBYTE TempFrame, int OffSet)
{
// Display Summary ASN.1
TempFrame = DispASNSum(hFrame, TempFrame, OffSet+1, DispSummary);
//Display Ticket[3]
// Display msg-type[2]
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, KrbApReqID, KrbApReqBitF);
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+4);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Display Ticket (61)
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ApTicketID, ApTicketBitF);
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+4);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Display SEQUENCE
TempFrame = DispSeqOctets(hFrame, TempFrame, OffSet+3, ASN1UnivTagSumID, ASN1UnivTag);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Display Ticket Version value at the Top level
TempFrame = DispSum(hFrame, TempFrame, 0x02, 0x30, OffSet+2, DispSumTixVer);
// Display tvt-vno[0]
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+3, TicketStructID, TicketStructBitF);
// Break Down INTEGER values
TempFrame = DefineValue(hFrame, TempFrame, OffSet+4, KdcContentsValue);
// Display Realm name value at the Top level
TempFrame = DispSum(hFrame, TempFrame, 0x1B, 0x30, OffSet+2, DispStringRealmName);
// Display realm[1]
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+3, TicketStructID, TicketStructBitF);
TempFrame = DefineValue(hFrame, TempFrame, OffSet+5, DispStringRealmName);
// Display Server name value at the Top level
TempFrame = DispSumString(hFrame, TempFrame, 0x1B, OffSet+2, DispStringServNameGS);
// Display sname[2]
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+3, TicketStructID, TicketStructBitF);
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+4);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Display SEQUENCE Octets
TempFrame = DispSeqOctets(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag);
// Display sname[2]
TempFrame = DefinePrincipalName(hFrame, TempFrame, OffSet+3, DispStringServerName);
--TempFrame;
// Display enc-part[3]
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, TicketStructID, TicketStructBitF);
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+4);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Display SEQUENCE Octets
TempFrame = DispSeqOctets(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
//Display EncryptedData
TempFrame = HandleEncryptedData(hFrame, TempFrame, OffSet+1);
return TempFrame;
}
LPBYTE DispASNSum(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
{
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
0,
TempFrame,
0, OffSet, 0);
return TempFrame;
}
/************************************************************************************
**
**This function is a spinoff of DispSum. I created this one separately for the sole
**purpose of displaying the full value of susec and cusec at the top levels
**
*************************************************************************************/
LPBYTE DispSumSec(HFRAME hFrame, LPBYTE TempFrame, int ClassValue, int ClassValue2, int OffSet, DWORD TypeVal)
{
/* Working here now to display info name at the top. Will indent everything
else 1 to the right. Not sure how well this is going to work since name-string[1]
is a SEQUENCE OF. Writing code now to assume there is only going to be one name
and display the first one.
*/
BYTE SizeSec[4];
PBYTE lSizeSec = (PBYTE)&SizeSec;
TempFrameReq = (TempFrame+1);
TempFrameReq2 = (TempFrame+2);
// This while statement increments TempFrameReq until 1B is reached
// If 1B is ever used in a length octet or elsewhere this will fail.
// Might look at doing a me mcopy later on to a global variable
// THINK WE CAN USE BERGETSTRING TO DISPLAY FULL SERVER NAME. WE CAN
// USE A STRING CONSTANTS WITH TO DISPLAY THE FULL VALUE.
// Incrementing TempFrameReq until String is found
while(*(TempFrameReq) != ClassValue || *(TempFrameReq2) == ClassValue2)
{
TempFrameReq++;
TempFrameReq2++;
// Trying to come up with a way to make sure the Length Value doesn't == ClassValue
// Still need some type of checking in case the length octet's value after the SEQUENCE OF
// turns out to be equal to ClassValue.
if(*(TempFrameReq) == ClassValue && *(TempFrameReq2) == ClassValue2)
{
TempFrameReq++;
TempFrameReq2++;
// Checking to see if Length Octet's value after SEQUENCE OF is equal to ClassValue. If so,
// incrementing TempFrameReq in order to get to the correct offset.
if(*(TempFrameReq) == ClassValue2 && *(TempFrameReq2) == ClassValue)
{
TempFrameReq++;
TempFrameReq2++;
}
}
}
memcpy(lSizeSec, (TempFrameReq2++), 4);
*lSizeSec = *(lSizeSec) & 0xffffff00;
// Prints out Value. Need to change the Array to give better description
AttachPropertyInstanceEx(hFrame,
KerberosDatabase[TypeVal].hProperty,
3,
TempFrameReq2,
4,
lSizeSec,
0, OffSet, 0);
return TempFrame;
}
/*******************************************************************************************
* LPBYTE DispEdata(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
*
* This function is a spinoff of DefineValue. Problem is, e-data for Kerb error can be
* displayed in two different formats. Even though this does present duplicate code,
* it does make it more convenenient and cleaner to have specific functions to handle specific data.
*
*******************************************************************************************/
LPBYTE DispEdata(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
{
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+2);
// Need to advance TempFrame the proper # of frames.
TempFrame = IncTempFrame(TempFrame);
// Display Universal Class Tag
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3);
// Need to advance TempFrame the proper # of frames.
TempFrame = IncTempFrame(TempFrame);
// This if statement is checking to see if e-data is a Sequence of PA-DATA's. If so
// we send the data to function to handle padata, if not, we display the Octet String.
if (*((TempFrame)+1) == 0x30)
{
// Display padata
TempFrame = HandlePadataKrbErr(hFrame, TempFrame, 2, PaDataSummary);
// 1/18/00 LEFT OFF HERE. NEED TO DISPLAY E-DATA WHEN IT'S FORMATTED AS PA-DATA. LOOK AT
// ADDING THE IF STATEMENT IN HANDLEPADATA AS YOU DID YESTERDAY.
}
else
{
AttachPropertyInstance(hFrame,
KerberosDatabase[TypeVal].hProperty,
*(TempFrame-1),
++TempFrame,
0, OffSet+1, 0);
}
return (TempFrame-1)+*(TempFrame-1);
}
/*******************************************************************************************
** LPBYTE HandlePadataKrbErr(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
** This function handles the initial display of padata include in Kerb-Error
**
*******************************************************************************************/
LPBYTE HandlePadataKrbErr(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal)
{
//Display SEQUENCE OF
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
//Display SEQUENCE OF
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Display padata-type[1]
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, PaDataSummary, PaDataSeq);
// Display INTEGER value
TempFrame =DispPadata(hFrame, TempFrame, OffSet+4, PadataTypeValID);
// Display padata-value[2]
DispASNTypes(hFrame, TempFrame, OffSet+2, PaDataSummary, PaDataSeq);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, ++TempFrame, OffSet+5);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
//Display OCTET STRING
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+7);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
//Display SEQUENCE OF
TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+7);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Handle MethodData
TempFrame = HandleMethodData(hFrame, TempFrame);
return(TempFrame);
}
/******************************************************************************************
**
** LPBYTE HandleMethodData(HFRAME hFrame, LPBYTE TempFrame)
**
** This function displays METHOD-DATA as described in kerb-error
**
******************************************************************************************/
LPBYTE HandleMethodData(HFRAME hFrame, LPBYTE TempFrame)
{
int iStringLength = 0;
int inc = 0;
// METHOD-DATA :: = SEQUENCE of PA-DATA. This is a Sequence of, thus creating a loop to display
// all info. Added the inc variable so that the look will only go through twice. In the sniff
// I was going by, the 3rd sequence of looked to be formatted in a whole different form than
// METHOD-DATA. Even if this is by design, off-hand, I don't see how to code this to break
// out a different data format without any type of signifier in the frame.
while(*(TempFrame+1) == 0x30 && inc <= 1)
{
//Display SEQUENCE OF
TempFrame = DispASNTypes(hFrame, TempFrame, 6, ASN1UnivTagSumID, ASN1UnivTag);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, 8);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
// Display method-type[0]
TempFrame = DispASNTypes(hFrame, TempFrame, 5, MethodDataSummary, MethodDataBitF);
// Break Down INTEGER values
TempFrame = DefineValue(hFrame, TempFrame, 7, DispSumEtype2);
// Display method-data[1]
TempFrame = DispASNTypes(hFrame, TempFrame, 5, MethodDataSummary, MethodDataBitF);
// Display Length Octet(s)
TempFrame = CalcLengthSummary(hFrame, TempFrame, 8);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
//Display OCTET STRING
TempFrame = DispASNTypes(hFrame, TempFrame, 7, ASN1UnivTagSumID, ASN1UnivTag);
// Calculate the size of the Length Octet
iStringLength = CalcMsgLength(TempFrame);
//Display Length Octet
TempFrame = CalcLengthSummary(hFrame, TempFrame, 10);
// Incrementing TempFrame based on the number of octets
// taken up by the Length octet
TempFrame = IncTempFrame(TempFrame);
AttachPropertyInstance(hFrame,
KerberosDatabase[DispReqAddInfo].hProperty,
sizeof(BYTE)+(iStringLength - 1),
++TempFrame,
0, 9, 0);
// Increment TempFrame to the end of the string so we can check for another Sequence
TempFrame += (iStringLength - 1);
++inc;
}
// LEFT OFF HERE 1/19/00 THIS IS A SEQUENCE OF, SO YOU NEED TO INCREMENT TEMPFRAME APPROPRIATELY
// AND THEN CHECK FOR 0x30. IF PRESENT, KEEP LOOPING.
return(TempFrame);
}