📄 icserver.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "icserver.h"
#include "icXmlParser.h"
#include "icutils.h"
#include "icdistrict.h"
#include "errorctx.h"
/* Send server request
*/
int icServerRequest (
VoltIdentityObject *idObj,
icServerResponseData *responseData,
int *responseCode,
icServerRequestData requestData,
icHTTPfn httpFn,
void *httpFnAppData,
unsigned char *trustStore,
unsigned long timeOut,
VoltTransportCtx *transCtx
)
{
int status;
int max, i, len;
char *request = (char *)0;
char *response = (char *)0;
char *authTokens = (char *)0;
unsigned char *buf = (unsigned char *)0;
unsigned char *temp = (unsigned char *)0;
char *url = (char *)0;
VoltLibCtx *libCtx = (VoltLibCtx *)0;
unsigned char *id64 = (unsigned char *)0;
unsigned char *certReq64 = (unsigned char *)0;
unsigned char *request64 = (unsigned char*)0;
char* escapedStr = (char*)0;
VoltHttpRequestInfoPost postInfo;
VoltHttpRequestInfo reqInfo;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
libCtx = (VoltLibCtx *)transCtx->voltObject.libraryCtx;
/* Form request
*/
max = 1024;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
authTokens = (char *)Z3Malloc (256);
if (authTokens == (char*)0)
goto cleanup;
authTokens[0] = 0;
VOLT_SET_ERROR_TYPE (errorType, 0)
for (i = 0; i < requestData.authTokensCount; i++)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = icStrcatalloc (
&authTokens, (unsigned char *)" <vs:authToken value=\"", libCtx);
if (status != 0)
goto cleanup;
VOLT_SET_FNCT_LINE (fnctLine)
status = icStringXMLEscapeAlloc(libCtx,
requestData.authTokens[i], &escapedStr);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = icStrcatalloc (
&authTokens, (unsigned char *)escapedStr, libCtx);
Z2Free(escapedStr);
if (status != 0)
goto cleanup;
VOLT_SET_FNCT_LINE (fnctLine)
status = icStrcatalloc (
&authTokens, (unsigned char *)"\"/>\n", libCtx);
if (status != 0)
goto cleanup;
}
VOLT_SET_FNCT_LINE (fnctLine)
status = icBase64Encode (
&id64, &len, requestData.id, requestData.idLen, 1, libCtx);
if (status != 0)
goto cleanup;
if (requestData.request != (Asn1P10Request *)0)
{
/* Get the length of the expected buffer and allocate sufficient
* memory.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_ENCODING;
len = i2d_Asn1P10Request (requestData.request, (unsigned char **)0);
if (len == 0)
goto cleanup;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
buf = (unsigned char *) Z2Malloc (len , 0);
if (buf == (unsigned char *)0)
goto cleanup;
VOLT_SET_FNCT_LINE (fnctLine)
temp = buf;
status = VT_ERROR_INVALID_ENCODING;
len = i2d_Asn1P10Request (requestData.request, &temp);
if (len == 0)
goto cleanup;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = icBase64Encode (&certReq64, &len, buf, len, 1, libCtx);
if (status != 0)
goto cleanup;
VOLT_SET_FNCT_LINE (fnctLine)
status = icBuildServerRequestAlloc (
libCtx, requestData.components, authTokens, id64, certReq64,
&request);
if (status != 0)
goto cleanup;
}
else
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = icBuildServerRequestAlloc (
libCtx, requestData.components, authTokens, id64, (char *)0,
&request);
if (status != 0)
goto cleanup;
}
/* Rather than URL-encode the post data, we just base64 it ...
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = icBase64Encode (
&request64, &len, request, Z2Strlen(request), 1, libCtx);
if (status != 0)
goto cleanup;
/* ...except that we need to escape any +'s and any possible trailing =
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = icStrrepl ((char **)&request64, "+", "%2B", libCtx);
if (status != 0)
goto cleanup;
VOLT_SET_FNCT_LINE (fnctLine)
status = icStrrepl ((char **)&request64, "=", "%3D", libCtx);
if (status != 0)
goto cleanup;
/* Then prepend the "field" name to it
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = icStrprependalloc ((char **)&request64, IC_REQUEST_FIELD, libCtx);
if (status != 0)
goto cleanup;
/* Post request to server
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = icBuildURLAlloc (
libCtx, VOLT_IC_URL, "https://", requestData.server,
IC_SERVER_DEFAULT_URL, &url);
if (status != 0)
goto cleanup;
VOLT_SET_FNCT_LINE (fnctLine)
postInfo.transCtx = transCtx;
postInfo.idObj = idObj;
postInfo.postData = request64;
reqInfo.requestType = VOLT_REQUEST_TYPE_POST;
reqInfo.requestData = (Pointer)&postInfo;
status = httpFn (
&reqInfo, &response, responseCode, url,
0, trustStore, timeOut, httpFnAppData);
if (status != 0)
goto cleanup;
/* response code 401 is Invalid Auth.
*/
if (*responseCode == 401)
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_AUTHORIZATION_DENIED;
goto cleanup;
}
else if (*responseCode != 200)
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_DOWNLOAD_FAILURE;
goto cleanup;
}
VOLT_SET_FNCT_LINE (fnctLine)
status = icParseServerResponse (
responseCode, responseData, response, libCtx);
cleanup:
if (buf != (unsigned char *)0 )
Z2Free (buf);
if (url != (char *)0 )
Z2Free (url);
if (certReq64 != (unsigned char *)0)
Z2Free (certReq64);
if (id64 != (unsigned char *)0)
Z2Free(id64);
if (request != (char *)0)
Z2Free (request);
if (authTokens != (char *) 0)
Z2Free(authTokens);
if (request64 != (unsigned char *)0)
Z2Free (request64);
if (response != (char *)0)
Z2Free (response);
VOLT_LOG_ERROR_COMPARE (
status, (VtLibCtx)libCtx, status, errorType, fnctLine,
"icServerRequest", (char *)0)
return (status);
}
int icParseServerResponse (
int *code,
icServerResponseData *responseData,
char *responseText,
VoltLibCtx *libCtx
)
{
int status, i, j, len;
char *responseCode = (char *)0;
char *tempMessage = (char*)0;
char *url = (char *)0;
icXmlNode *node, *privKeyNode, *authTokenNode, *headerNode, *certNode, *root;
icXmlParser *parser;
icInputStream *bufStream;
unsigned char *ptr = (char *)0;
unsigned char *certDer = (char *)0;
char *point;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* Parse response text
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = icInputStreamCreate (
ICInputStreamImplString, (unsigned char *)responseText,
Z2Strlen (responseText), VOLT_IC_STREAM_COPY_REFERENCE, &bufStream,
libCtx);
if (status != 0)
goto cleanup1;
VOLT_SET_FNCT_LINE (fnctLine)
status = icXmlParserCreate (&parser, libCtx);
if (status != 0)
goto cleanup1;
VOLT_SET_FNCT_LINE (fnctLine)
status = icXmlParserParse (parser, bufStream, libCtx);
if (status != 0)
goto cleanup1;
root = parser->main;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
if (root == (icXmlNode *) 0)
goto cleanup1;
/* Initialize response struct to empty
*/
Z2Memset (responseData, 0, sizeof (*responseData));
VOLT_SET_FNCT_LINE (fnctLine)
if (root->node_type != IC_XML_NODE_TAG)
goto cleanup1;
VOLT_SET_FNCT_LINE (fnctLine)
if (Z2Strcmp (root->tag_name, "vs:response") != 0)
goto cleanup1;
VOLT_SET_FNCT_LINE (fnctLine)
icTableGet (root->attributes, "code", &responseCode, libCtx);
if (responseCode == (char *)0)
goto cleanup1;
point = responseCode;
*code = 0;
while ( (*point != '\0') && (*point != ' ') )
{
*code = ((*code) * 10) + (int)(*point) - (int)'0';
point++;
}
icTableGet (root->attributes, "message", &tempMessage, libCtx);
if (tempMessage != (char *)0)
icSafeStrncpy (
responseData->errorMsg, tempMessage, sizeof (responseData->errorMsg),
libCtx);
privKeyNode = (icXmlNode *)0;
authTokenNode = (icXmlNode *)0;
certNode = (icXmlNode *)0;
for (i = 0; i < root->num_children; i++)
{
node = root->children[i];
if (node->node_type != IC_XML_NODE_TAG)
continue;
if (Z2Strcmp (node->tag_name, "vs:header") == 0)
{
for (j = 0; j < node->num_children; j++)
{
headerNode = node->children[j];
if (headerNode->node_type != IC_XML_NODE_TAG)
continue;
if (Z2Strcmp(headerNode->tag_name, "vs:id") == 0)
{
/* Should have one TEXT child
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
if ( (headerNode->num_children != 1) ||
(headerNode->children[0]->node_type != IC_XML_NODE_TEXT) )
goto cleanup1;
status = icBase64Decode (
&(responseData->id), &(responseData->idLen),
headerNode->children[0]->text, -1, libCtx);
if (status != 0)
goto cleanup1;
}
}
}
if (Z2Strcmp(node->tag_name, "vs:body") == 0)
{
for (j = 0; j < node->num_children; j++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -