📄 zdm2read.c
字号:
/* Copyright 2003-2005, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "securearchive.h"
#include "errorctx.h"
#include "vtassert.h"
#include "datanode.h"
#include "compress.h"
#include "archive.h"
#include "sacommon.h"
#include "zdm2common.h"
#include "stringutil.h"
#include "securemail.h"
#include "zdm.h"
typedef struct VoltZDM2ReadLocalCtx {
VtSecureArchiveObject mSecureArchive;
VtBufferTypeInfo mBufferTypeInfo;
unsigned int mMessageFormat;
VtZDMEmailRecipientList mPrimaryRecipientList;
VtZDMEmailRecipientList mCCRecipientList;
int mCurrentEntryType;
VtDataNodeObject mInsecureAttributes;
VtStreamObject mInputStream;
unsigned char mOwnsInputStream;
unsigned char mReadInitCalled;
unsigned char mMessageUnwrapped;
unsigned char mEmailRecipientsInited;
unsigned char mSecureArchiveInited;
} VoltZDM2ReadLocalCtx;
static void VoltZDM2ReadLocalCtxDestroy(Pointer obj, Pointer ctx)
{
VtZDMObject zdmObj = (VtZDMObject)obj;
VoltZDM2ReadLocalCtx* readCtx;
VtLibCtx libCtx = (VtLibCtx)0;
if ((obj == (Pointer)0) || (ctx == (Pointer)0))
return;
readCtx = (VoltZDM2ReadLocalCtx*)ctx;
VT_ASSERT(readCtx != (VoltZDM2ReadLocalCtx*)0);
libCtx = zdmObj->voltObject.libraryCtx;
VT_ASSERT(libCtx != (VtLibCtx)0);
VtDestroySecureArchiveObject(&readCtx->mSecureArchive);
VtDestroyDataNodeObject(&readCtx->mInsecureAttributes);
if (readCtx->mOwnsInputStream)
VtDestroyStreamObject(&readCtx->mInputStream);
Z2Free(readCtx->mPrimaryRecipientList.emailList);
Z2Free(readCtx->mCCRecipientList.emailList);
Z2Free(readCtx);
}
static int VoltZDM2InitEmailRecipients(
VtZDMObject zdmObj
)
{
int status = 0;
VtLibCtx libCtx = (VtLibCtx)0;
VoltZDM2ReadLocalCtx* readCtx;
VtDataNodeObject attributesNode;
VtDataNodeObject recipientsNode;
VtDataNodeObject recipientNode;
VtDataNodeObject node;
const unsigned char* recipientAddress;
long recipientFlags;
int recipientCount;
int i;
VOLT_DECLARE_FNCT_LINE(fnctLine)
VOLT_DECLARE_ERROR_TYPE(errorType)
VT_ASSERT(zdmObj != (VtZDMObject)0);
libCtx = zdmObj->voltObject.libraryCtx;
VT_ASSERT(libCtx != (VtLibCtx)0);
readCtx = (VoltZDM2ReadLocalCtx*) zdmObj->localCtx;
VT_ASSERT(readCtx != (VoltZDM2ReadLocalCtx*)0);
VT_ASSERT(readCtx->mSecureArchive != (VtSecureArchiveObject)0);
VOLT_SET_ERROR_TYPE(errorType, 0)
do
{
if (readCtx->mEmailRecipientsInited)
break;
/* Access the attributes node maintained by the secure archive.
* This is sort of a hack and we could get around it by getting
* all the information through the public attribute API, but it
* would be inconvenient.
*/
VOLT_SET_FNCT_LINE(fnctLine)
status = VtGetSecureArchiveParam(readCtx->mSecureArchive,
VtSecureArchiveParamAttributesNode, (Pointer*)&attributesNode);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeResolveChild(attributesNode,
VoltZDM2RecipientsAttributeName, 0, &recipientsNode);
if (status != 0)
break;
/* Figure out how many total recipients there are. This count will
* include both primary and CC recipients. We use this total to
* allocate the email address array for both the primary and CC
* recipients even though we probably won't fill them up, but it's
* not that wasteful and it avoid having to make a preliminary pass
* over the recipients to determine the counts.
*/
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeGetChildCount(recipientsNode, &recipientCount);
if (status != 0)
break;
readCtx->mPrimaryRecipientList.emailList = (const unsigned char**)
Z3Malloc(recipientCount * sizeof(unsigned char*));
readCtx->mCCRecipientList.emailList = (const unsigned char**)
Z3Malloc(recipientCount * sizeof(unsigned char*));
if ((readCtx->mPrimaryRecipientList.emailList == (const unsigned char**)0) ||
(readCtx->mCCRecipientList.emailList == (const unsigned char**)0))
{
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE(fnctLine)
status = VT_ERROR_MEMORY;
break;
}
/* Loop over the recipients, extracting the recipient email
* address and flags.
*/
for (i = 0; i < recipientCount; i++)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeGetChild(recipientsNode, i, &recipientNode);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeLookupChild(recipientNode,
VoltZDM2AddressAttributeName, &node);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeGetStringValue(node, &recipientAddress);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeLookupChild(recipientNode,
VoltZDM2FlagsAttributeName, &node);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeGetIntegerValue(node, &recipientFlags);
if (status != 0)
break;
/* If the primary recipient flag is set then add it to the
* primary recipient list.
*/
if ((recipientFlags & VOLT_ZDM_RECIPIENT_FLAGS_PRIMARY) != 0)
{
readCtx->mPrimaryRecipientList.emailList[
readCtx->mPrimaryRecipientList.count++] = recipientAddress;
}
/* If the CC recipient flag is set then add it to the
* CC recipient list.
*/
if ((recipientFlags & VOLT_ZDM_RECIPIENT_FLAGS_CC) != 0)
{
readCtx->mCCRecipientList.emailList[
readCtx->mCCRecipientList.count++] = recipientAddress;
}
}
readCtx->mEmailRecipientsInited = 1;
}
while (0);
VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
fnctLine,"VoltZDM2InitEmailRecipients", (unsigned char*)0)
return status;
}
static int VoltZDM2InitInsecureAttributes(
VtZDMObject zdmObj
)
{
int status = 0;
VtLibCtx libCtx = (VtLibCtx)0;
VoltZDM2ReadLocalCtx* readCtx;
VtSecureArchiveCurrentEntryInfo currentEntryInfo;
unsigned char buffer[1000];
unsigned int size;
VtStreamSize streamSize; unsigned char* attributesXML = (unsigned char*)0;
VtStreamObject attributesStream = (VtStreamObject)0;
VtStreamImplMemoryInfo memoryInfo;
VOLT_DECLARE_FNCT_LINE(fnctLine)
VOLT_DECLARE_ERROR_TYPE(errorType)
VT_ASSERT(zdmObj != (VtZDMObject)0);
libCtx = zdmObj->voltObject.libraryCtx;
VT_ASSERT(libCtx != (VtLibCtx)0);
readCtx = (VoltZDM2ReadLocalCtx*) zdmObj->localCtx;
VT_ASSERT(readCtx != (VoltZDM2ReadLocalCtx*)0);
VT_ASSERT(readCtx->mSecureArchive != (VtSecureArchiveObject)0);
VOLT_SET_ERROR_TYPE(errorType, 0)
do
{
if (readCtx->mInsecureAttributes != (VtDataNodeObject)0)
break;
/* Create a stream to hold the contents of the insecure
* attributes entry. Since we're going to access the buffer
* directly below to pass to the data node call, the stream
* needs to be a memory-based stream, so we always create the
* stream using the VtStreamImplMemory instead of using the
* buffer type specified by the user. The insecure attributes
* entry will typically be pretty small, so there shouldn't be
* much of a memory overhead from using the memory-based stream.
*/
VOLT_SET_FNCT_LINE(fnctLine)
Z2Memset(&memoryInfo, 0, sizeof(memoryInfo));
memoryInfo.flags = VT_STREAM_OPEN_ON_ACCESS;
memoryInfo.openMode = VT_STREAM_OPEN_READ_WRITE;
status = VtCreateStreamObject(libCtx, VtStreamImplMemory,
(Pointer)&memoryInfo, &attributesStream);
if (status != 0)
break;
/* Set the current entry in the secure archive */
currentEntryInfo.type = VT_SECURE_ARCHIVE_CURRENT_ENTRY_INSECURE;
currentEntryInfo.name = VoltZDM2InsecureAttributesFilePathName;
VOLT_SET_FNCT_LINE(fnctLine)
status = VtSetSecureArchiveParam(readCtx->mSecureArchive,
VtSecureArchiveParamCurrentEntry, (Pointer)¤tEntryInfo);
if (status != 0)
break;
/* Copy over the contents to the stream */
for (;;)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtSecureArchiveReadUpdate(readCtx->mSecureArchive,
(unsigned char*)0, 0, (unsigned int*)0, buffer,
sizeof(buffer), &size);
if ((status != 0) || (size == 0))
{
if (status == VT_ERROR_END_OF_STREAM)
status = 0;
break;
}
VOLT_SET_FNCT_LINE(fnctLine)
status = VtStreamWrite(attributesStream, buffer, size);
if (status != 0)
break;
}
if (status != 0)
break;
/* Add a null-terminator, so we can use the memory buffer
* as a C string to pass to the data node call.
*/
VOLT_SET_FNCT_LINE(fnctLine)
status = VtStreamWrite(attributesStream, "", 1);
if (status != 0)
break;
/* Get a pointer to the stream's underlying buffer. This buffer
* is still owned by the stream, so we don't need to delete it
*/
VOLT_SET_FNCT_LINE(fnctLine)
status = VtStreamGetBuffer(attributesStream, &attributesXML, &streamSize);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = VtCreateDataNodeObjectFromXML(libCtx, attributesXML,
&readCtx->mInsecureAttributes);
if (status != 0)
break;
}
while (0);
VtDestroyStreamObject(&attributesStream);
VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
fnctLine,"VoltZDM2InitInsecureAttributes", (unsigned char*)0)
return status;
}
static int VoltZDM2UnwrapMessage(
VtZDMObject zdmObj
)
{
int status = 0;
VtLibCtx libCtx = (VtLibCtx)0;
VoltZDM2ReadLocalCtx* readCtx;
const unsigned int messageBufferSize = 4096;
unsigned char* messageBuffer = (unsigned char*)0;
unsigned char* dataBuffer = (unsigned char*)0;
unsigned int dataBufferSize = 0;
unsigned int dataSize;
VtAlgorithmObject base64Decoder = (VtAlgorithmObject)0;
unsigned char* startTag = (unsigned char*)0;
unsigned char* endTag = (unsigned char*)0;
VtStreamSize dataLength;
int copyDataLength = 0;
const unsigned char* copySrc;
int foundStartTag = 0;
int foundEndTag = 0;
int startTagLength, endTagLength;
unsigned char* foundStr;
unsigned char* startData = 0;
unsigned char* endData;
int final = 0;
unsigned int bytesConsumed;
VOLT_DECLARE_FNCT_LINE(fnctLine)
VOLT_DECLARE_ERROR_TYPE(errorType)
VT_ASSERT(zdmObj != (VtZDMObject)0);
libCtx = zdmObj->voltObject.libraryCtx;
VT_ASSERT(libCtx != (VtLibCtx)0);
readCtx = (VoltZDM2ReadLocalCtx*) zdmObj->localCtx;
VT_ASSERT(readCtx != (VoltZDM2ReadLocalCtx*)0);
VOLT_SET_ERROR_TYPE(errorType, 0)
do
{
if (readCtx->mMessageUnwrapped)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = VoltZDM2FormatMessageTag(libCtx,
VoltZDM2SecureBlockStartTagPrefix,
VoltZDM2SecureBlockStartTagSuffix, (unsigned char*)0,
VT_MESSAGE_FORMAT_CURRENT_VERSION, 0, &startTag);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = VoltZDM2FormatMessageTag(libCtx,
VoltZDM2SecureBlockEndTagPrefix,
VoltZDM2SecureBlockEndTagSuffix, (unsigned char*)0,
VT_MESSAGE_FORMAT_CURRENT_VERSION, 0, &endTag);
if (status != 0)
break;
startTagLength = Z2Strlen(startTag);
endTagLength = Z2Strlen(endTag);
messageBuffer = (unsigned char*) Z3Malloc(messageBufferSize + 1);
if (messageBuffer == (unsigned char*)0)
{
VOLT_SET_FNCT_LINE(fnctLine)
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
status = VT_ERROR_MEMORY;
break;
}
do
{
status = VtStreamRead(readCtx->mInputStream, messageBuffer + copyDataLength,
messageBufferSize - copyDataLength, &dataLength);
if (status == VT_ERROR_END_OF_STREAM)
{
final = 1;
status = foundEndTag ? 0 : VT_ERROR_INVALID_ZDM_MSG;
}
if (status != 0)
break;
startData = (unsigned char*)0;
endData = (unsigned char*)0;
dataLength += copyDataLength;
messageBuffer[dataLength] = 0;
if (!foundStartTag)
{
foundStr = Z2Stristr(messageBuffer, startTag);
foundStartTag = (foundStr != (unsigned char*)0);
if (foundStartTag)
{
startData = foundStr + startTagLength;
//while (isspace((unsigned char)*startData))
// startData++;
}
}
else
{
startData = messageBuffer;
}
if (foundStartTag)
{
copyDataLength = endTagLength;
if (!foundEndTag)
{
foundStr = Z2Stristr(startData, endTag);
foundEndTag = (foundStr != NULL);
if (foundEndTag)
{
endData = foundStr;
//while ((endData > startData) && isspace((unsigned char)*--endData)) {}
//endData++;
}
}
if (!foundEndTag)
endData = messageBuffer + dataLength - copyDataLength;
if (endData > startData)
{
if (base64Decoder == (VtAlgorithmObject)0)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtCreateAlgorithmObject(libCtx, VtAlgorithmImplBase64,
(Pointer)0, &base64Decoder);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDecodeInit(base64Decoder);
if (status != 0)
break;
}
if (final)
{
status = VtDecodeFinal(base64Decoder, (VtRandomObject)0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -