2cc21a344c
in order to allow for the client component to be consumed by distributions targeting the desktop. This check-in is for the server project.
1459 lines
45 KiB
C
1459 lines
45 KiB
C
/***********************************************************************
|
|
*
|
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; version 2.1
|
|
* of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, Novell, Inc.
|
|
*
|
|
* To contact Novell about this file by physical or electronic mail,
|
|
* you may find current contact information at www.novell.com.
|
|
*
|
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
|
*
|
|
***********************************************************************/
|
|
|
|
|
|
//===[ Include files ]=====================================================
|
|
|
|
#include "internal.h"
|
|
|
|
//===[ Type definitions ]==================================================
|
|
|
|
//
|
|
// XML Constants for the CASA Identity Token
|
|
//
|
|
#define CASA_IDENT_TOKEN_ELEMENT_NAME "casa_ident_tok"
|
|
#define ID_ELEMENT_NAME "id"
|
|
#define SOURCE_NAME_ELEMENT_NAME "source_name"
|
|
#define SOURCE_URL_ELEMENT_NAME "source_url"
|
|
#define TARGET_SERVICE_ELEMENT_NAME "target_service"
|
|
#define TARGET_HOST_ELEMENT_NAME "target_host"
|
|
#define ATTRIBUTES_ELEMENT_NAME "attributes"
|
|
|
|
//
|
|
// Parse states
|
|
//
|
|
#define AWAITING_ROOT_ELEMENT_START 0x0
|
|
#define AWAITING_ROOT_ELEMENT_END 0x1
|
|
#define AWAITING_ID_DATA 0x2
|
|
#define AWAITING_ID_ELEMENT_START 0x3
|
|
#define AWAITING_ID_ELEMENT_END 0x4
|
|
#define AWAITING_SOURCE_NAME_DATA 0x5
|
|
#define AWAITING_SOURCE_NAME_ELEMENT_START 0x6
|
|
#define AWAITING_SOURCE_NAME_ELEMENT_END 0x7
|
|
#define AWAITING_SOURCE_URL_DATA 0x8
|
|
#define AWAITING_SOURCE_URL_ELEMENT_START 0x9
|
|
#define AWAITING_SOURCE_URL_ELEMENT_END 0xA
|
|
#define AWAITING_TARGET_SERVICE_DATA 0xB
|
|
#define AWAITING_TARGET_SERVICE_ELEMENT_START 0xC
|
|
#define AWAITING_TARGET_SERVICE_ELEMENT_END 0xD
|
|
#define AWAITING_TARGET_HOST_DATA 0xE
|
|
#define AWAITING_TARGET_HOST_ELEMENT_START 0xF
|
|
#define AWAITING_TARGET_HOST_ELEMENT_END 0x10
|
|
#define AWAITING_ATTRIBUTES_ELEMENT_START 0x11
|
|
#define AWAITING_ATTRIBUTE_DATA 0x12
|
|
#define AWAITING_ATTRIBUTE_START 0x13
|
|
#define AWAITING_ATTRIBUTE_END 0x14
|
|
#define DONE_PARSING 0x15
|
|
|
|
//
|
|
// Attribute structure
|
|
//
|
|
typedef struct _Attribute
|
|
{
|
|
LIST_ENTRY listEntry;
|
|
char *pAttribName;
|
|
int attribNameLen;
|
|
char *pAttribValue;
|
|
int attribValueLen;
|
|
|
|
} Attribute, *PAttribute;
|
|
|
|
|
|
//
|
|
// Identity Token Interface instance data
|
|
//
|
|
typedef struct _IdenTokenIfInstance
|
|
{
|
|
int refCount;
|
|
char *pIdentId;
|
|
int identIdLen;
|
|
char *pIdentSourceName;
|
|
int identSourceNameLen;
|
|
char *pIdentSourceUrl;
|
|
int identSourceUrlLen;
|
|
char *pTargetService;
|
|
int targetServiceLen;
|
|
char *pTargetHost;
|
|
int targetHostLen;
|
|
LIST_ENTRY attributeListHead;
|
|
IdenTokenIf idenTokenIf;
|
|
|
|
} IdenTokenIfInstance, *PIdenTokenIfInstance;
|
|
|
|
|
|
//
|
|
// Identity Token Parse Structure
|
|
//
|
|
typedef struct _IdenTokenParse
|
|
{
|
|
XML_Parser p;
|
|
int state;
|
|
int elementDataProcessed;
|
|
IdenTokenIfInstance *pIdenTokenIfInstance;
|
|
CasaStatus status;
|
|
|
|
} IdenTokenParse, *PIdenTokenParse;
|
|
|
|
//===[ Function prototypes ]===============================================
|
|
|
|
//===[ Global variables ]==================================================
|
|
|
|
// IdenTokenIf variables
|
|
static
|
|
int g_numIdenTokenIfObjs = 0;
|
|
|
|
// Synchronization mutex
|
|
static
|
|
HANDLE g_idenTokenIfMutex = NULL;
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
void
|
|
FreeIdenTokenIfInstance(
|
|
IN IdenTokenIfInstance *pIdenTokenIfInstance)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
LIST_ENTRY *pListEntry;
|
|
|
|
DbgTrace(2, "-FreeIdenTokenIfInstance- Start\n", 0);
|
|
|
|
// Free all of the resources associated with the IdenTokenIfInstance
|
|
if (pIdenTokenIfInstance->pIdentId)
|
|
free(pIdenTokenIfInstance->pIdentId);
|
|
|
|
if (pIdenTokenIfInstance->pIdentSourceName)
|
|
free(pIdenTokenIfInstance->pIdentSourceName);
|
|
|
|
if (pIdenTokenIfInstance->pIdentSourceUrl)
|
|
free(pIdenTokenIfInstance->pIdentSourceUrl);
|
|
|
|
if (pIdenTokenIfInstance->pTargetService)
|
|
free(pIdenTokenIfInstance->pTargetService);
|
|
|
|
if (pIdenTokenIfInstance->pTargetHost)
|
|
free(pIdenTokenIfInstance->pTargetHost);
|
|
|
|
// Go through all of the associated attributes
|
|
pListEntry = pIdenTokenIfInstance->attributeListHead.Flink;
|
|
while (pListEntry != &pIdenTokenIfInstance->attributeListHead)
|
|
{
|
|
Attribute *pAttribute = CONTAINING_RECORD(pListEntry, Attribute, listEntry);
|
|
|
|
// Free resources associated with the attribute
|
|
if (pAttribute->pAttribName)
|
|
free(pAttribute->pAttribName);
|
|
|
|
if (pAttribute->pAttribValue)
|
|
free(pAttribute->pAttribValue);
|
|
|
|
// Forget about this attribute
|
|
RemoveEntryList(&pAttribute->listEntry);
|
|
free(pAttribute);
|
|
|
|
// Start from the top again
|
|
pListEntry = pIdenTokenIfInstance->attributeListHead.Flink;
|
|
}
|
|
|
|
// Free the identity token if instance structure
|
|
free(pIdenTokenIfInstance);
|
|
|
|
DbgTrace(2, "-FreeIdenTokenIfInstance- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
void XMLCALL
|
|
IdenTokenStartElementHandler(
|
|
IN void *pUserData,
|
|
IN const XML_Char *name,
|
|
IN const XML_Char **atts)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
IdenTokenParse *pIdenTokenParse = (IdenTokenParse*) pUserData;
|
|
Attribute *pAttribute;
|
|
|
|
DbgTrace(2, "-IdenTokenStartElementHandler- Start\n", 0);
|
|
|
|
// Proceed based on the state
|
|
switch (pIdenTokenParse->state)
|
|
{
|
|
case AWAITING_ROOT_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the CASA Identity
|
|
// Token Element.
|
|
if (strcmp(name, CASA_IDENT_TOKEN_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_ID_ELEMENT_START;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_ID_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the ID Element.
|
|
if (strcmp(name, ID_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_ID_DATA;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_SOURCE_NAME_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the Source Name Element.
|
|
if (strcmp(name, SOURCE_NAME_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_SOURCE_NAME_DATA;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_SOURCE_URL_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the Source Url Element.
|
|
if (strcmp(name, SOURCE_URL_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_SOURCE_URL_DATA;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_TARGET_SERVICE_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the Target Service Element.
|
|
if (strcmp(name, TARGET_SERVICE_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_TARGET_SERVICE_DATA;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_TARGET_HOST_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the Target Host Element.
|
|
if (strcmp(name, TARGET_HOST_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_TARGET_HOST_DATA;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_ATTRIBUTES_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the Attributes Element.
|
|
if (strcmp(name, ATTRIBUTES_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_ATTRIBUTE_START;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_ATTRIBUTE_START:
|
|
|
|
// Allocate an initialize Attribute structure
|
|
pAttribute = malloc(sizeof(*pAttribute));
|
|
if (pAttribute)
|
|
{
|
|
memset(pAttribute, 0, sizeof(*pAttribute));
|
|
InsertTailList(&pIdenTokenParse->pIdenTokenIfInstance->attributeListHead,
|
|
&pAttribute->listEntry);
|
|
|
|
// Now save the attribute name
|
|
pAttribute->attribNameLen = strlen(name) + 1;
|
|
pAttribute->pAttribName = malloc(pAttribute->attribNameLen);
|
|
if (pAttribute->pAttribName)
|
|
{
|
|
strcpy(pAttribute->pAttribName, name);
|
|
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_ATTRIBUTE_DATA;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenStartElementHandler- Buffer allocation failure\n", 0);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenStartElementHandler- Buffer allocation failure\n", 0);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DbgTrace(0, "-IdenTokenStartElementHandler- Un-expected state = %d\n", pIdenTokenParse->state);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
break;
|
|
}
|
|
|
|
DbgTrace(2, "-IdenTokenStartElementHandler- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
CasaStatus
|
|
ConsumeElementData(
|
|
IN IdenTokenParse *pIdenTokenParse,
|
|
IN const XML_Char *s,
|
|
IN int len,
|
|
INOUT char **ppElementData,
|
|
INOUT int *pElementDataLen)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
|
|
|
DbgTrace(3, "-ConsumeElementData- Start\n", 0);
|
|
|
|
// Proceed based on whether or not we have already consumed data
|
|
// for this element.
|
|
if (*ppElementData == NULL)
|
|
{
|
|
// We have not yet consumed data for this element
|
|
pIdenTokenParse->elementDataProcessed = len;
|
|
|
|
// Allocate a buffer to hold this element data (null terminated).
|
|
*ppElementData = (char*) malloc(len + 1);
|
|
if (*ppElementData)
|
|
{
|
|
memset(*ppElementData, 0, len + 1);
|
|
memcpy(*ppElementData, s, len);
|
|
|
|
// Return the length of the element data buffer
|
|
*pElementDataLen = pIdenTokenParse->elementDataProcessed + 1;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-ConsumeElementData- Buffer allocation failure\n", 0);
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char *pNewBuf;
|
|
|
|
// We have already received token data, append this data to it.
|
|
pNewBuf = (char*) malloc(pIdenTokenParse->elementDataProcessed + len + 1);
|
|
if (pNewBuf)
|
|
{
|
|
memset(pNewBuf,
|
|
0,
|
|
pIdenTokenParse->elementDataProcessed + len + 1);
|
|
memcpy(pNewBuf,
|
|
*ppElementData,
|
|
pIdenTokenParse->elementDataProcessed);
|
|
memcpy(pNewBuf + pIdenTokenParse->elementDataProcessed, s, len);
|
|
pIdenTokenParse->elementDataProcessed += len;
|
|
|
|
// Swap the buffers
|
|
free(*ppElementData);
|
|
*ppElementData = pNewBuf;
|
|
|
|
// Return the length of the element data buffer
|
|
*pElementDataLen = pIdenTokenParse->elementDataProcessed + 1;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-ConsumeElementData- Buffer allocation failure\n", 0);
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
}
|
|
|
|
DbgTrace(3, "-ConsumeElementData- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
void XMLCALL
|
|
IdenTokenCharDataHandler(
|
|
IN void *pUserData,
|
|
IN const XML_Char *s,
|
|
IN int len)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
IdenTokenParse *pIdenTokenParse = (IdenTokenParse*) pUserData;
|
|
Attribute *pAttribute;
|
|
|
|
DbgTrace(2, "-IdenTokenCharDataHandler- Start\n", 0);
|
|
|
|
// Just exit if being called to process LF and CR characters
|
|
if (len == 1
|
|
&& ((*s == '\n') || (*s == '\r')))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
// Proceed based on the state
|
|
switch (pIdenTokenParse->state)
|
|
{
|
|
case AWAITING_ID_DATA:
|
|
case AWAITING_ID_ELEMENT_END:
|
|
|
|
pIdenTokenParse->status = ConsumeElementData(pIdenTokenParse,
|
|
s,
|
|
len,
|
|
&pIdenTokenParse->pIdenTokenIfInstance->pIdentId,
|
|
&pIdenTokenParse->pIdenTokenIfInstance->identIdLen);
|
|
if (CASA_SUCCESS(pIdenTokenParse->status))
|
|
{
|
|
// Advanced to the next state
|
|
pIdenTokenParse->state = AWAITING_ID_ELEMENT_END;
|
|
}
|
|
else
|
|
{
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_SOURCE_NAME_DATA:
|
|
case AWAITING_SOURCE_NAME_ELEMENT_END:
|
|
|
|
pIdenTokenParse->status = ConsumeElementData(pIdenTokenParse,
|
|
s,
|
|
len,
|
|
&pIdenTokenParse->pIdenTokenIfInstance->pIdentSourceName,
|
|
&pIdenTokenParse->pIdenTokenIfInstance->identSourceNameLen);
|
|
if (CASA_SUCCESS(pIdenTokenParse->status))
|
|
{
|
|
// Advanced to the next state
|
|
pIdenTokenParse->state = AWAITING_SOURCE_NAME_ELEMENT_END;
|
|
}
|
|
else
|
|
{
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_SOURCE_URL_DATA:
|
|
case AWAITING_SOURCE_URL_ELEMENT_END:
|
|
|
|
pIdenTokenParse->status = ConsumeElementData(pIdenTokenParse,
|
|
s,
|
|
len,
|
|
&pIdenTokenParse->pIdenTokenIfInstance->pIdentSourceUrl,
|
|
&pIdenTokenParse->pIdenTokenIfInstance->identSourceUrlLen);
|
|
if (CASA_SUCCESS(pIdenTokenParse->status))
|
|
{
|
|
// Advanced to the next state
|
|
pIdenTokenParse->state = AWAITING_SOURCE_URL_ELEMENT_END;
|
|
}
|
|
else
|
|
{
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_TARGET_SERVICE_DATA:
|
|
case AWAITING_TARGET_SERVICE_ELEMENT_END:
|
|
|
|
pIdenTokenParse->status = ConsumeElementData(pIdenTokenParse,
|
|
s,
|
|
len,
|
|
&pIdenTokenParse->pIdenTokenIfInstance->pTargetService,
|
|
&pIdenTokenParse->pIdenTokenIfInstance->targetServiceLen);
|
|
if (CASA_SUCCESS(pIdenTokenParse->status))
|
|
{
|
|
// Advanced to the next state
|
|
pIdenTokenParse->state = AWAITING_TARGET_SERVICE_ELEMENT_END;
|
|
}
|
|
else
|
|
{
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_TARGET_HOST_DATA:
|
|
case AWAITING_TARGET_HOST_ELEMENT_END:
|
|
|
|
pIdenTokenParse->status = ConsumeElementData(pIdenTokenParse,
|
|
s,
|
|
len,
|
|
&pIdenTokenParse->pIdenTokenIfInstance->pTargetHost,
|
|
&pIdenTokenParse->pIdenTokenIfInstance->targetHostLen);
|
|
if (CASA_SUCCESS(pIdenTokenParse->status))
|
|
{
|
|
// Advanced to the next state
|
|
pIdenTokenParse->state = AWAITING_TARGET_HOST_ELEMENT_END;
|
|
}
|
|
else
|
|
{
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_ATTRIBUTE_DATA:
|
|
case AWAITING_ATTRIBUTE_END:
|
|
|
|
// Get a pointer to current attribute structure
|
|
pAttribute = CONTAINING_RECORD(pIdenTokenParse->pIdenTokenIfInstance->attributeListHead.Blink,
|
|
Attribute,
|
|
listEntry);
|
|
|
|
pIdenTokenParse->status = ConsumeElementData(pIdenTokenParse,
|
|
s,
|
|
len,
|
|
&pAttribute->pAttribValue,
|
|
&pAttribute->attribValueLen);
|
|
if (CASA_SUCCESS(pIdenTokenParse->status))
|
|
{
|
|
// Advanced to the next state
|
|
pIdenTokenParse->state = AWAITING_ATTRIBUTE_END;
|
|
}
|
|
else
|
|
{
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DbgTrace(0, "-IdenTokenCharDataHandler- Un-expected state = %d\n", pIdenTokenParse->state);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
break;
|
|
}
|
|
|
|
exit:
|
|
|
|
DbgTrace(2, "-IdenTokenCharDataHandler- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
void XMLCALL
|
|
IdenTokenEndElementHandler(
|
|
IN void *pUserData,
|
|
IN const XML_Char *name)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
IdenTokenParse *pIdenTokenParse = (IdenTokenParse*) pUserData;
|
|
|
|
DbgTrace(2, "-IdenTokenEndElementHandler- Start\n", 0);
|
|
|
|
// Proceed based on the state
|
|
switch (pIdenTokenParse->state)
|
|
{
|
|
case AWAITING_ROOT_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the CASA Identity
|
|
// Token Element.
|
|
if (strcmp(name, CASA_IDENT_TOKEN_ELEMENT_NAME) == 0)
|
|
{
|
|
// Done.
|
|
pIdenTokenParse->state = DONE_PARSING;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenEndHandler- Un-expected end element, state = %08x\n", pIdenTokenParse->state);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_ID_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the Id Element.
|
|
if (strcmp(name, ID_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_SOURCE_NAME_ELEMENT_START;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenEndHandler- Un-expected end element, state = %08x\n", pIdenTokenParse->state);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_SOURCE_NAME_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the Source Name Element.
|
|
if (strcmp(name, SOURCE_NAME_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_SOURCE_URL_ELEMENT_START;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenEndHandler- Un-expected end element, state = %08x\n", pIdenTokenParse->state);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_SOURCE_URL_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the Source URL Element.
|
|
if (strcmp(name, SOURCE_URL_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_TARGET_SERVICE_ELEMENT_START;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenEndHandler- Un-expected end element, state = %08x\n", pIdenTokenParse->state);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_TARGET_SERVICE_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the Target Service Element.
|
|
if (strcmp(name, TARGET_SERVICE_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_TARGET_HOST_ELEMENT_START;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenEndHandler- Un-expected end element, state = %08x\n", pIdenTokenParse->state);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_TARGET_HOST_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the Target Host Element.
|
|
if (strcmp(name, TARGET_HOST_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_ATTRIBUTES_ELEMENT_START;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenEndHandler- Un-expected end element, state = %08x\n", pIdenTokenParse->state);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_ATTRIBUTE_END:
|
|
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_ATTRIBUTE_START;
|
|
break;
|
|
|
|
case AWAITING_ATTRIBUTE_START:
|
|
|
|
// We should we done with the attributes, in this state we are only expecting
|
|
// the Attributes element.
|
|
if (strcmp(name, ATTRIBUTES_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pIdenTokenParse->state = AWAITING_ROOT_ELEMENT_END;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-IdenTokenEndHandler- Un-expected end element, state = %08x\n", pIdenTokenParse->state);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DbgTrace(0, "-IdenTokenEndElementHandler- Un-expected state = %d\n", pIdenTokenParse->state);
|
|
XML_StopParser(pIdenTokenParse->p, XML_FALSE);
|
|
break;
|
|
}
|
|
|
|
DbgTrace(2, "-IdenTokenEndElementHandler- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
int SSCS_CALL
|
|
AddReference(
|
|
IN const void *pIfInstance)
|
|
//
|
|
// Arguments:
|
|
// pIfInstance -
|
|
// Pointer to interface object.
|
|
//
|
|
// Returns:
|
|
// Interface reference count.
|
|
//
|
|
// Description:
|
|
// Increases interface reference count.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
int refCount;
|
|
IdenTokenIfInstance *pIdenTokenIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenIfInstance, idenTokenIf);
|
|
|
|
DbgTrace(2, "-AddReference- Start\n", 0);
|
|
|
|
// Increment the reference count on the object
|
|
PlatAcquireMutex(g_idenTokenIfMutex);
|
|
pIdenTokenIfInstance->refCount ++;
|
|
refCount = pIdenTokenIfInstance->refCount;
|
|
PlatReleaseMutex(g_idenTokenIfMutex);
|
|
|
|
DbgTrace(2, "-AddReference- End, refCount = %08X\n", refCount);
|
|
|
|
return refCount;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
void SSCS_CALL
|
|
ReleaseReference(
|
|
IN const void *pIfInstance)
|
|
//
|
|
// Arguments:
|
|
// pIfInstance -
|
|
// Pointer to interface object.
|
|
//
|
|
// Returns:
|
|
// Nothing.
|
|
//
|
|
// Description:
|
|
// Decreases interface reference count. The interface is deallocated if
|
|
// the reference count becomes zero.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
bool freeObj = false;
|
|
IdenTokenIfInstance *pIdenTokenIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenIfInstance, idenTokenIf);
|
|
|
|
DbgTrace(2, "-ReleaseReference- Start\n", 0);
|
|
|
|
// Decrement the reference count on the object and determine if it needs to
|
|
// be released.
|
|
PlatAcquireMutex(g_idenTokenIfMutex);
|
|
pIdenTokenIfInstance->refCount --;
|
|
if (pIdenTokenIfInstance->refCount == 0)
|
|
{
|
|
// The object needs to be released, forget about it.
|
|
freeObj = true;
|
|
g_numIdenTokenIfObjs --;
|
|
}
|
|
PlatReleaseMutex(g_idenTokenIfMutex);
|
|
|
|
// Free object if necessary
|
|
if (freeObj)
|
|
{
|
|
FreeIdenTokenIfInstance(pIdenTokenIfInstance);
|
|
}
|
|
|
|
DbgTrace(2, "-ReleaseReference- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
CasaStatus SSCS_CALL
|
|
GetIdentityId(
|
|
IN const void *pIfInstance,
|
|
INOUT char *pIdentIdBuf,
|
|
INOUT int *pIdentIdLen)
|
|
//
|
|
// Arguments:
|
|
// pIfInstance -
|
|
// Pointer to interface object.
|
|
//
|
|
// pIdentIdBuf -
|
|
// Pointer to buffer that will receive the identity id. The returned
|
|
// id will be in the form of a NULL terminated string.
|
|
//
|
|
// pIdentIdBufLen -
|
|
// Pointer to variable with the length of the buffer pointed by
|
|
// pIdentIdBuf. On exit it contains the length of the returned id
|
|
// (including the NULL terminator).
|
|
//
|
|
//
|
|
// Returns:
|
|
// Casa Status
|
|
//
|
|
// Description:
|
|
// Get the identity id associated with the identity token.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
CasaStatus retStatus;
|
|
IdenTokenIfInstance *pIdenTokenIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenIfInstance, idenTokenIf);
|
|
|
|
DbgTrace(2, "-GetIdentityId- Start\n", 0);
|
|
|
|
// Check the input parameters
|
|
if (pIfInstance == NULL
|
|
|| pIdentIdLen == NULL
|
|
|| (pIdentIdBuf == NULL && *pIdentIdLen != 0))
|
|
{
|
|
DbgTrace(0, "-GetIdentityId- Invalid parameter\n", 0);
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INVALID_PARAMETER);
|
|
goto exit;
|
|
}
|
|
|
|
// Determine if the caller's buffer is large enough
|
|
if (*pIdentIdLen >= pIdenTokenIfInstance->identIdLen)
|
|
{
|
|
// Return the data to the caller
|
|
memcpy(pIdentIdBuf, pIdenTokenIfInstance->pIdentId, pIdenTokenIfInstance->identIdLen);
|
|
|
|
// Success
|
|
retStatus = CASA_STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_BUFFER_OVERFLOW);
|
|
}
|
|
|
|
// Return the lenght of the id
|
|
*pIdentIdLen = pIdenTokenIfInstance->identIdLen;
|
|
|
|
exit:
|
|
|
|
DbgTrace(2, "-GetIdentityId- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
CasaStatus SSCS_CALL
|
|
GetSourceName(
|
|
IN const void *pIfInstance,
|
|
INOUT char *pSourceNameBuf,
|
|
INOUT int *pSourceNameLen)
|
|
//
|
|
// Arguments:
|
|
// pIfInstance -
|
|
// Pointer to interface object.
|
|
//
|
|
// pSourceNameBuf -
|
|
// Pointer to buffer that will receive the name associated with the
|
|
// identity information source. The returned name will be in the form
|
|
// of a NULL terminated string.
|
|
//
|
|
// pSourceNameBufLen -
|
|
// Pointer to variable with the length of the buffer pointed by
|
|
// pSourceNameBuf. On exit it contains the length of the returned
|
|
// name (including the NULL terminator).
|
|
//
|
|
//
|
|
// Returns:
|
|
// Casa Status
|
|
//
|
|
// Description:
|
|
// Get the name of the identity source associated with the identity token.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
CasaStatus retStatus;
|
|
IdenTokenIfInstance *pIdenTokenIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenIfInstance, idenTokenIf);
|
|
|
|
DbgTrace(2, "-GetSourceName- Start\n", 0);
|
|
|
|
// Check the input parameters
|
|
if (pIfInstance == NULL
|
|
|| pSourceNameLen == NULL
|
|
|| (pSourceNameBuf == NULL && *pSourceNameLen != 0))
|
|
{
|
|
DbgTrace(0, "-GetSourceName- Invalid parameter\n", 0);
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INVALID_PARAMETER);
|
|
goto exit;
|
|
}
|
|
|
|
// Determine if the caller's buffer is large enough
|
|
if (*pSourceNameLen >= pIdenTokenIfInstance->identSourceNameLen)
|
|
{
|
|
// Return the data to the caller
|
|
memcpy(pSourceNameBuf, pIdenTokenIfInstance->pIdentSourceName, pIdenTokenIfInstance->identSourceNameLen);
|
|
|
|
// Success
|
|
retStatus = CASA_STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_BUFFER_OVERFLOW);
|
|
}
|
|
|
|
// Return the lenght of the source name
|
|
*pSourceNameLen = pIdenTokenIfInstance->identSourceNameLen;
|
|
|
|
exit:
|
|
|
|
DbgTrace(2, "-GetSourceName- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
CasaStatus SSCS_CALL
|
|
GetSourceUrl(
|
|
IN const void *pIfInstance,
|
|
INOUT char *pSourceUrlBuf,
|
|
INOUT int *pSourceUrlLen)
|
|
//
|
|
// Arguments:
|
|
// pIfInstance -
|
|
// Pointer to interface object.
|
|
//
|
|
// pSourceUrlBuf -
|
|
// Pointer to buffer that will receive the URL associated with the
|
|
// identity information source. The returned URL will be in the form
|
|
// of a NULL terminated string.
|
|
//
|
|
// pSourceUrlBufLen -
|
|
// Pointer to variable with the length of the buffer pointed by
|
|
// pSourceUrlBuf. On exit it contains the length of the returned
|
|
// URL (including the NULL terminator).
|
|
//
|
|
//
|
|
// Returns:
|
|
// Casa Status
|
|
//
|
|
// Description:
|
|
// Get the URL to the identity source associated with the identity token.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
CasaStatus retStatus;
|
|
IdenTokenIfInstance *pIdenTokenIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenIfInstance, idenTokenIf);
|
|
|
|
DbgTrace(2, "-GetSourceUrl- Start\n", 0);
|
|
|
|
// Check the input parameters
|
|
if (pIfInstance == NULL
|
|
|| pSourceUrlLen == NULL
|
|
|| (pSourceUrlBuf == NULL && *pSourceUrlLen != 0))
|
|
{
|
|
DbgTrace(0, "-GetSourceUrl- Invalid parameter\n", 0);
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INVALID_PARAMETER);
|
|
goto exit;
|
|
}
|
|
|
|
// Determine if the caller's buffer is large enough
|
|
if (*pSourceUrlLen >= pIdenTokenIfInstance->identSourceUrlLen)
|
|
{
|
|
// Return the data to the caller
|
|
memcpy(pSourceUrlBuf, pIdenTokenIfInstance->pIdentSourceUrl, pIdenTokenIfInstance->identSourceUrlLen);
|
|
|
|
// Success
|
|
retStatus = CASA_STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_BUFFER_OVERFLOW);
|
|
}
|
|
|
|
// Return the lenght of the source url
|
|
*pSourceUrlLen = pIdenTokenIfInstance->identSourceUrlLen;
|
|
|
|
exit:
|
|
|
|
DbgTrace(2, "-GetSourceUrl- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
CasaStatus SSCS_CALL
|
|
AttributeEnumerate(
|
|
IN const void *pIfInstance,
|
|
INOUT int *pEnumHandle,
|
|
INOUT char *pAttribNameBuf,
|
|
INOUT int *pAttribNameLen,
|
|
INOUT char *pAttribValueBuf,
|
|
INOUT int *pAttribValueLen)
|
|
//
|
|
// Arguments:
|
|
// pIfInstance -
|
|
// Pointer to interface object.
|
|
//
|
|
// pEnumHandle -
|
|
// Pointer to enumeration handle. Must be set to 0 to start an
|
|
// enumeration. Note the enumeration handle advances if the
|
|
// function returns success.
|
|
//
|
|
// pAttribNameBuf -
|
|
// Pointer to buffer that will receive the identity attribute name. The
|
|
// returned name will be in the form of a NULL terminated string.
|
|
//
|
|
// pAttribNameLen -
|
|
// Pointer to variable with the length of the buffer pointed by
|
|
// pAttribNameBuf. On exit it contains the length of the returned
|
|
// name (including the NULL terminator).
|
|
//
|
|
// pAttribValueBuf -
|
|
// Pointer to buffer that will receive the identity attribute value. The
|
|
// returned value will be in the form of a NULL terminated string.
|
|
//
|
|
// pAttribValueLen -
|
|
// Pointer to variable with the length of the buffer pointed by
|
|
// pAttribValueBuf. On exit it contains the length of the returned
|
|
// value (including the NULL terminator).
|
|
//
|
|
//
|
|
// Returns:
|
|
// Casa Status
|
|
//
|
|
// Description:
|
|
// Enumerates through the attributes associated with the identity token.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
CasaStatus retStatus;
|
|
IdenTokenIfInstance *pIdenTokenIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenIfInstance, idenTokenIf);
|
|
LIST_ENTRY *pListEntry;
|
|
int i;
|
|
Attribute *pAttribute;
|
|
|
|
DbgTrace(2, "-AttributeEnumerate- Start\n", 0);
|
|
|
|
// Check the input parameters
|
|
if (pIfInstance == NULL
|
|
|| pEnumHandle == NULL
|
|
|| pAttribNameLen == NULL
|
|
|| pAttribValueLen == NULL
|
|
|| (pAttribNameBuf == NULL && *pAttribNameLen != 0)
|
|
|| (pAttribValueBuf == NULL && *pAttribValueLen != 0))
|
|
{
|
|
DbgTrace(0, "-AttributeEnumerate- Invalid parameter\n", 0);
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INVALID_PARAMETER);
|
|
goto exit;
|
|
}
|
|
|
|
// Find the appropriate attribute based on the enum handle which is used as
|
|
// an index.
|
|
i = 0;
|
|
pAttribute = NULL;
|
|
pListEntry = pIdenTokenIfInstance->attributeListHead.Flink;
|
|
while (pListEntry != &pIdenTokenIfInstance->attributeListHead)
|
|
{
|
|
// Is this the attribute needed
|
|
if (i == *pEnumHandle)
|
|
{
|
|
// This is the attribute needed
|
|
pAttribute = CONTAINING_RECORD(pListEntry, Attribute, listEntry);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// No, try the next one.
|
|
pListEntry = pListEntry->Flink;
|
|
i++;
|
|
}
|
|
}
|
|
|
|
// Check if we found an attribute for the indicated enum handle
|
|
if (pAttribute)
|
|
{
|
|
// Try to return the attribute name
|
|
if (*pAttribNameLen >= pAttribute->attribNameLen)
|
|
{
|
|
// Return the attribute name
|
|
memcpy(pAttribNameBuf, pAttribute->pAttribName, pAttribute->attribNameLen);
|
|
|
|
// Now, try to return the attribute value
|
|
if (*pAttribValueLen >= pAttribute->attribValueLen)
|
|
{
|
|
// Return the attribute value
|
|
memcpy(pAttribValueBuf, pAttribute->pAttribValue, pAttribute->attribValueLen);
|
|
|
|
// Success
|
|
retStatus = CASA_STATUS_SUCCESS;
|
|
|
|
// Advance the enum handle
|
|
*pEnumHandle = *pEnumHandle + 1;
|
|
}
|
|
else
|
|
{
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_BUFFER_OVERFLOW);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_BUFFER_OVERFLOW);
|
|
}
|
|
|
|
// Return the attribute lengths
|
|
*pAttribNameLen = pAttribute->attribNameLen;
|
|
*pAttribValueLen = pAttribute->attribValueLen;
|
|
}
|
|
else
|
|
{
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_NO_MORE_ENTRIES);
|
|
}
|
|
|
|
exit:
|
|
|
|
DbgTrace(2, "-AttributeEnumerate- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
CasaStatus
|
|
GetIdenTokenInterface(
|
|
IN const char *pTokenBuf,
|
|
IN const int tokenLen,
|
|
INOUT IdenTokenIf **ppIdenTokenIf)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
// Casa Status
|
|
//
|
|
// Description:
|
|
// Get principal interface instanced for the identity associated
|
|
// with specified identity token.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
IdenTokenIfInstance *pIdenTokenIfInstance;
|
|
CasaStatus retStatus;
|
|
|
|
DbgTrace(2, "-GetIdenTokenInterface- Start\n", 0);
|
|
|
|
// Create a IdenTokenIfInstance object for it.
|
|
pIdenTokenIfInstance = malloc(sizeof(*pIdenTokenIfInstance));
|
|
if (pIdenTokenIfInstance)
|
|
{
|
|
XML_Parser p;
|
|
IdenTokenParse idenTokenParse = {0};
|
|
|
|
/*
|
|
* CASA identity tokens have the following format:
|
|
*
|
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
|
* <casa_ident_tok>
|
|
* <id>identity id</id>
|
|
* <source_name>identity data source name</source_name>
|
|
* <source_url>identity data source url</source_url>
|
|
* <target_service>target service name</target_service>
|
|
* <target_host>target host name</target_host>
|
|
* <attributes>
|
|
* <attribute name> attribute value</attribute name>
|
|
* <attribute2 name> attribute value</attribute2 name>
|
|
* ...
|
|
* </attributes>
|
|
* </casa_ident_tok>
|
|
*
|
|
*/
|
|
|
|
// Initialize the IdentTokenIfInstance object and set it in the
|
|
// idenTokenParse object.
|
|
memset(pIdenTokenIfInstance, 0, sizeof(*pIdenTokenIfInstance));
|
|
InitializeListHead(&pIdenTokenIfInstance->attributeListHead);
|
|
pIdenTokenIfInstance->idenTokenIf.addReference = AddReference;
|
|
pIdenTokenIfInstance->idenTokenIf.releaseReference = ReleaseReference;
|
|
pIdenTokenIfInstance->idenTokenIf.getIdentityId = GetIdentityId;
|
|
pIdenTokenIfInstance->idenTokenIf.getSourceName = GetSourceName;
|
|
pIdenTokenIfInstance->idenTokenIf.getSourceUrl = GetSourceUrl;
|
|
pIdenTokenIfInstance->idenTokenIf.attributeEnumerate = AttributeEnumerate;
|
|
|
|
idenTokenParse.pIdenTokenIfInstance = pIdenTokenIfInstance;
|
|
|
|
// Create parser
|
|
p = XML_ParserCreate(NULL);
|
|
if (p)
|
|
{
|
|
// Keep track of the parser in our parse object
|
|
idenTokenParse.p = p;
|
|
|
|
// Initialize the status within the parse object
|
|
idenTokenParse.status = CASA_STATUS_SUCCESS;
|
|
|
|
// Set the start and end element handlers
|
|
XML_SetElementHandler(p,
|
|
IdenTokenStartElementHandler,
|
|
IdenTokenEndElementHandler);
|
|
|
|
// Set the character data handler
|
|
XML_SetCharacterDataHandler(p, IdenTokenCharDataHandler);
|
|
|
|
|
|
// Set our user data
|
|
XML_SetUserData(p, &idenTokenParse);
|
|
|
|
// Parse the document
|
|
if (XML_Parse(p, pTokenBuf, tokenLen, 1) == XML_STATUS_OK)
|
|
{
|
|
// Verify that the parse operation completed successfully
|
|
if (idenTokenParse.state == DONE_PARSING)
|
|
{
|
|
// The parse operation succeded.
|
|
retStatus = CASA_STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetIdenTokenInterface- Parse operation did not complete\n", 0);
|
|
|
|
// Check if a status has been recorded
|
|
if (idenTokenParse.status != CASA_STATUS_SUCCESS)
|
|
{
|
|
retStatus = idenTokenParse.status;
|
|
}
|
|
else
|
|
{
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_PROTOCOL_ERROR);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetIdenTokenInterface- Parse error %d\n", XML_GetErrorCode(p));
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_PROTOCOL_ERROR);
|
|
}
|
|
|
|
// Free the parser
|
|
XML_ParserFree(p);
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-CreateAuthToken- Parser creation error\n", 0);
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
|
|
|
|
// Return the Identity Token Interface to the caller if successful
|
|
if (CASA_SUCCESS(retStatus))
|
|
{
|
|
// Return the IdenTokenIf associated with the instance data after
|
|
// incrementing its reference count.
|
|
pIdenTokenIfInstance->refCount ++;
|
|
*ppIdenTokenIf = &pIdenTokenIfInstance->idenTokenIf;
|
|
|
|
// Bump up our interface instance count
|
|
PlatAcquireMutex(g_idenTokenIfMutex);
|
|
g_numIdenTokenIfObjs ++;
|
|
PlatReleaseMutex(g_idenTokenIfMutex);
|
|
}
|
|
else
|
|
{
|
|
FreeIdenTokenIfInstance(pIdenTokenIfInstance);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetIdenTokenInterface- Buffer allocation failure\n", 0);
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
|
|
DbgTrace(2, "-GetIdenTokenInterface- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
CasaStatus
|
|
IdenTokenIfInit(void)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
// Casa Status
|
|
//
|
|
// Description:
|
|
// Initializes the identity token interface complex.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
CasaStatus retStatus;
|
|
|
|
DbgTrace(1, "-IdenTokenIfInit- Start\n", 0);
|
|
|
|
// Allocate mutex
|
|
if ((g_idenTokenIfMutex = PlatAllocMutex()) != NULL)
|
|
retStatus = CASA_STATUS_SUCCESS;
|
|
else
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
DbgTrace(1, "-IdenTokenIfInit- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
void
|
|
IdenTokenIfUninit(void)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
// Casa Status
|
|
//
|
|
// Description:
|
|
// Uninitializes the configuration interface complex.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
DbgTrace(1, "-IdenTokenIfUninit- Start\n", 0);
|
|
|
|
// Free mutex if necessary
|
|
if (g_idenTokenIfMutex)
|
|
{
|
|
PlatDestroyMutex(g_idenTokenIfMutex);
|
|
g_idenTokenIfMutex = NULL;
|
|
}
|
|
|
|
DbgTrace(1, "-IdenTokenIfUninit- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
|