#ifndef __BIG_ENDIAN__
#include "DSTCPEndian.h"
#include <string.h>
#include <errno.h> // system call error numbers
#include <unistd.h> // for select call
#include <stdlib.h> // for calloc()
#include <stdio.h>
#include <ctype.h>
#include <syslog.h>
#include <Security/Authorization.h>
#ifdef DSSERVERTCP
#include "CServerPlugin.h"
#include "CLog.h"
#include "CRefTable.h"
#else
#include "CDSRefMap.h"
#include "DirServicesPriv.h"
#endif
#include "CSharedData.h"
#define DUMP_BUFFER 0
#if DUMP_BUFFER
char* objectTypes[] =
{
"kResult",
"ktDirRef",
"ktNodeRef",
"ktRecRef",
"ktAttrListRef",
"ktAttrValueListRef",
"ktDataBuff",
"ktDataList",
"ktDirPattMatch",
"kAttrPattMatch",
"kAttrMatch",
"kMatchRecCount",
"kNodeNamePatt",
"ktAccessControlEntry",
"ktAttrEntry",
"ktAttrValueEntry",
"kOpenRecBool",
"kAttrInfoOnly",
"kRecFlags",
"kAttrFlags",
"kRecEntryIndex",
"kAttrInfoIndex",
"kAttrValueIndex",
"kAttrValueID",
"kOutBuffLen",
"kAuthStepDataLen",
"kAuthOnlyBool",
"kDirNodeName",
"kAuthMethod",
"kNodeInfoTypeList",
"kRecNameList",
"kRecTypeList",
"kAttrTypeList",
"kRecTypeBuff",
"kRecNameBuff",
"kAttrType",
"kAttrTypeBuff",
"kAttrValueBuff",
"kNewAttrBuff",
"kFirstAttrBuff",
"unknown",
"kAttrBuff",
"kAuthStepBuff",
"kAuthResponseBuff",
"kAttrTypeRequestList",
"kCustomRequestCode",
"kPluginName",
"kNodeCount",
"kNodeIndex",
"kAttrInfoCount",
"kAttrRecEntryCount",
"ktRecordEntry",
"kAuthStepDataResponse",
"kContextData",
"ktPidRef",
"ktGenericRef",
"kNodeChangeToken",
"ktEffectiveUID",
"ktUID",
"kAttrMatches",
"kAttrValueList"
};
FILE* gDumpFile = NULL;
void DumpBuf(char* buf, UInt32 len)
{
char acsiiBuf[17];
for (UInt32 i = 0; i < len; i++)
{
if ((i % 16) == 0) ::memset(acsiiBuf, 0, 17);
fprintf(gDumpFile, "%02X ", buf[i]);
if (::isprint(buf[i]))
acsiiBuf[i % 16] = buf[i];
else
acsiiBuf[i % 16] = '.';
if ((i % 16) == 15) fprintf(gDumpFile, " %s\n", acsiiBuf);
}
}
#endif
DSTCPEndian::DSTCPEndian(sComProxyData* message, int direction) : fMessage(message)
{
toBig = (direction == kDSSwapToBig);
fIPAddress = 0;
fPort = 0;
}
void DSTCPEndian::SwapMessage()
{
short i;
sObject* object;
bool isTwoWay = false;
UInt32 ourMsgID = 0;
if (fMessage == nil) return;
#if DUMP_BUFFER
UInt32 bufSize = 0;
if (gDumpFile == NULL)
gDumpFile = fopen("/Library/Logs/DirectoryService/PacketDump", "w");
if (toBig)
fprintf(gDumpFile, "\n\n\nBuffer in host order (preSwap)\n");
else
fprintf(gDumpFile, "\n\n\nBuffer in network order (preSwap)\n");
for (i=0; i< 10; i++)
{
object = &fMessage->obj[i];
UInt32 objType = DSGetLong(&object->type, toBig);
UInt32 offset = DSGetLong(&object->offset, toBig);
UInt32 length = DSGetLong(&object->length, toBig);
char* type = "unknown";
if (objType >= kResult && objType <= kAttrValueList)
type = objectTypes[objType - kResult];
if (objType != 0)
{
if (length > 0)
fprintf(gDumpFile, "Object %d, type %s, offset %ld, size %ld\n", i, type, DSGetLong(&object->offset, toBig), DSGetLong(&object->length, toBig));
else
fprintf(gDumpFile, "Object %d, type %s, value %ld\n", i, type, DSGetLong(&object->count, toBig));
}
if (length > 0)
{
UInt32 size = offset + length - sizeof(sComProxyData) + 4;
if (size > bufSize) bufSize = size;
}
}
DumpBuf(fMessage->data, bufSize);
#endif
ourMsgID = fMessage->fMsgID;
DSSwapLong(&fMessage->fDataSize, toBig);
DSSwapLong(&fMessage->fDataLength, toBig);
DSSwapLong(&fMessage->fMsgID, toBig);
DSSwapLong(&fMessage->fPID, toBig);
UInt32 aNodeRef = 0;
#ifndef DSSERVERTCP
UInt32 aNodeRefMap = 0; #endif
bool bCustomCall = false;
UInt32 aCustomRequestNum = 0;
bool bIsAPICallResponse = false;
const char* aPluginName = nil;
for (i=0; i< 10; i++)
{
object = &fMessage->obj[i];
UInt32 objType = DSGetLong(&object->type, toBig);
if (objType == kAuthMethod)
{
char* method = (char *)fMessage + DSGetLong(&object->offset, toBig);
if ( ::strcmp( method, kDSStdAuth2WayRandom ) == 0 )
isTwoWay = true;
}
if (objType == kCustomRequestCode)
{
bCustomCall = true;
aCustomRequestNum = (UInt32)DSGetLong(&object->count, toBig);
#ifdef DSSERVERTCP
DbgLog(kLogTCPEndpoint, "DSSERVERTCP>DSTCPEndian::SwapMessage(): kCustomRequestCode with code %u", aCustomRequestNum );
#else
LOG1(kStdErr, "FW-DSTCPEndian::SwapMessage(): kCustomRequestCode with code %u", aCustomRequestNum );
#endif
}
if (objType == ktNodeRef)
{
aNodeRef = (UInt32)DSGetLong(&object->count, toBig);
}
#ifndef DSSERVERTCP
if (objType == ktNodeRefMap)
{
aNodeRefMap = (UInt32)DSGetLong(&object->count, toBig);
}
#endif
if (objType == kResult)
{
bIsAPICallResponse = true;
}
}
#ifndef DSSERVERTCP
if (bIsAPICallResponse)
{
DSSwapLong(&ourMsgID, toBig);
if (aCustomRequestNum == 0)
{
aCustomRequestNum = CDSRefMap::GetCustomCodeFromMsgIDMap( ourMsgID );
if (aCustomRequestNum != 0)
{
CDSRefMap::RemoveMsgIDToCustomCodeMap( ourMsgID );
bCustomCall = true;
}
}
}
#endif
if ( bCustomCall && (aCustomRequestNum != 0) )
{
#ifdef DSSERVERTCP
if (aNodeRef != 0)
{
CServerPlugin *aPluginPtr = nil;
SInt32 myResult = CRefTable::VerifyNodeRef( aNodeRef, &aPluginPtr, fPort, fIPAddress );
if (myResult == eDSNoErr)
{
aPluginName = aPluginPtr->GetPluginName();
}
}
#else
if (aNodeRefMap != 0)
{
CDSRefMap::MapMsgIDToServerRef( ourMsgID, aNodeRef );
CDSRefMap::MapMsgIDToCustomCode( ourMsgID, aCustomRequestNum );
aPluginName = dsGetPluginNamePriv( aNodeRefMap, getpid() ); }
else
{
if (bIsAPICallResponse)
{
UInt32 ourServerRef = 0;
ourServerRef = CDSRefMap::GetServerRefFromMsgIDMap( ourMsgID );
CDSRefMap::RemoveMsgIDToServerRefMap( ourMsgID );
aNodeRefMap = CDSRefMap::GetLocalRefFromServerMap( ourServerRef );
aPluginName = dsGetPluginNamePriv( aNodeRefMap, getpid() ); }
}
#endif
}
for (i=0; i< 10; i++)
{
object = &fMessage->obj[i];
if (object->type == 0)
continue;
UInt32 objType = DSGetAndSwapLong(&object->type, toBig);
DSSwapLong(&object->count, toBig);
UInt32 objOffset = DSGetAndSwapLong(&object->offset, toBig);
DSSwapLong(&object->used, toBig);
UInt32 objLength = DSGetAndSwapLong(&object->length, toBig);
DSSwapObjectData(objType, (char *)fMessage + objOffset, objLength, (!isTwoWay), bCustomCall, aCustomRequestNum, (const char*)aPluginName, bIsAPICallResponse, toBig);
}
#if DUMP_BUFFER
if (toBig)
fprintf(gDumpFile, "\n\nBuffer in network order (post Swap)\n");
else
fprintf(gDumpFile, "\n\nBuffer in host order (post Swap)\n");
DumpBuf(fMessage->data, bufSize);
fflush(stdout);
#endif
}
void DSTCPEndian::AddIPAndPort( UInt32 inIPAddress, UInt32 inPort)
{
fIPAddress = inIPAddress;
fPort = inPort;
}
#endif