2006-08-07 21:12:49 +02:00
|
|
|
/***********************************************************************
|
|
|
|
*
|
|
|
|
* 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 ]==================================================
|
|
|
|
|
|
|
|
//
|
|
|
|
// Parse states
|
|
|
|
//
|
|
|
|
#define AWAITING_ROOT_ELEMENT_START 0x0
|
|
|
|
#define AWAITING_ROOT_ELEMENT_END 0x1
|
|
|
|
#define AWAITING_AUTH_POLICY_ELEMENT_START 0x2
|
|
|
|
#define AWAITING_AUTH_POLICY_ELEMENT_END 0x3
|
|
|
|
#define AWAITING_AUTH_POLICY_DATA 0x4
|
|
|
|
#define AWAITING_AUTH_SOURCE_ELEMENT_START 0x5
|
|
|
|
#define AWAITING_AUTH_SOURCE_ELEMENT_END 0x6
|
|
|
|
#define AWAITING_AUTH_SOURCE_CHILD_START 0x7
|
|
|
|
#define AWAITING_REALM_DATA 0x8
|
|
|
|
#define AWAITING_REALM_ELEMENT_END 0x9
|
|
|
|
#define AWAITING_MECHANISM_DATA 0xA
|
|
|
|
#define AWAITING_MECHANISM_ELEMENT_END 0xB
|
|
|
|
#define AWAITING_MECHANISM_INFO_DATA 0xC
|
|
|
|
#define AWAITING_MECHANISM_INFO_ELEMENT_END 0xD
|
|
|
|
#define AWAITING_UNKNOWN_DATA 0xE
|
|
|
|
#define AWAITING_UNKNOWN_ELEMENT_END 0xF
|
|
|
|
#define DONE_PARSING 0x10
|
|
|
|
|
|
|
|
//
|
|
|
|
// Authentication Policy Parse Structure
|
|
|
|
//
|
|
|
|
typedef struct _AuthPolicyParse
|
|
|
|
{
|
|
|
|
XML_Parser p;
|
|
|
|
int state;
|
|
|
|
int elementDataProcessed;
|
|
|
|
AuthPolicy *pAuthPolicy;
|
|
|
|
CasaStatus status;
|
|
|
|
|
|
|
|
} AuthPolicyParse, *PAuthPolicyParse;
|
|
|
|
|
|
|
|
|
|
|
|
//===[ Function prototypes ]===============================================
|
|
|
|
|
|
|
|
//===[ Global variables ]==================================================
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
static
|
|
|
|
void XMLCALL
|
|
|
|
AuthPolicyStartElementHandler(
|
|
|
|
IN AuthPolicyParse *pAuthPolicyParse,
|
|
|
|
IN const XML_Char *name,
|
|
|
|
IN const XML_Char **atts)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(2, "-AuthPolicyStartElementHandler- Start\n", 0);
|
|
|
|
|
|
|
|
// Proceed based on the state
|
|
|
|
switch (pAuthPolicyParse->state)
|
|
|
|
{
|
|
|
|
case AWAITING_ROOT_ELEMENT_START:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the Authentication
|
|
|
|
// Policy Element.
|
|
|
|
if (strcmp(name, AUTH_POLICY_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Good, advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_ELEMENT_START;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-AuthPolicyStartElementHandler- Un-expected start element\n", 0);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_AUTH_SOURCE_ELEMENT_START:
|
|
|
|
case AWAITING_ROOT_ELEMENT_END:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the start of an Authentication
|
|
|
|
// Source Element.
|
|
|
|
if (strcmp(name, AUTH_SOURCE_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
AuthContext *pAuthContext;
|
|
|
|
|
|
|
|
// Create an authentication context structure
|
|
|
|
pAuthContext = (AuthContext*) malloc(sizeof(AuthContext));
|
|
|
|
if (pAuthContext)
|
|
|
|
{
|
|
|
|
// Initialize the allocated AuthContext structure and associate it
|
|
|
|
// with the AuthPolicy structure.
|
|
|
|
memset(pAuthContext, 0, sizeof(*pAuthContext));
|
|
|
|
InsertTailList(&pAuthPolicyParse->pAuthPolicy->authContextListHead, &pAuthContext->listEntry);
|
|
|
|
|
|
|
|
// Good, advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-AuthPolicyStartElementHandler- Buffer allocation error\n", 0);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-AuthPolicyStartElementHandler- Un-expected start element\n", 0);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_AUTH_SOURCE_CHILD_START:
|
|
|
|
|
|
|
|
// Proceed based on the name of the element
|
|
|
|
if (strcmp(name, REALM_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_REALM_DATA;
|
|
|
|
}
|
|
|
|
else if (strcmp(name, MECHANISM_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_MECHANISM_DATA;
|
|
|
|
}
|
|
|
|
else if (strcmp(name, MECHANISM_INFO_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_MECHANISM_INFO_DATA;
|
|
|
|
}
|
|
|
|
else if (strcmp(name, AUTH_SOURCE_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// We are starting a new auth source entry, create an authentication
|
|
|
|
// context structure to hold its information.
|
|
|
|
AuthContext *pAuthContext;
|
|
|
|
|
|
|
|
// Create an authentication context structure
|
|
|
|
pAuthContext = (AuthContext*) malloc(sizeof(AuthContext));
|
|
|
|
if (pAuthContext)
|
|
|
|
{
|
|
|
|
// Initialize the allocated AuthContext structure and associate it
|
|
|
|
// with the AuthPolicy structure.
|
|
|
|
memset(pAuthContext, 0, sizeof(*pAuthContext));
|
|
|
|
InsertTailList(&pAuthPolicyParse->pAuthPolicy->authContextListHead, &pAuthContext->listEntry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-AuthPolicyStartElementHandler- Buffer allocation error\n", 0);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_UNKNOWN_DATA;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DbgTrace(0, "-AuthPolicyStartElementHandler- Un-expected state = %d\n", pAuthPolicyParse->state);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(2, "-AuthPolicyStartElementHandler- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
static
|
|
|
|
CasaStatus
|
|
|
|
ConsumeElementData(
|
|
|
|
IN AuthPolicyParse *pAuthPolicyParse,
|
|
|
|
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
|
|
|
|
pAuthPolicyParse->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 = pAuthPolicyParse->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(pAuthPolicyParse->elementDataProcessed + len + 1);
|
|
|
|
if (pNewBuf)
|
|
|
|
{
|
|
|
|
memset(pNewBuf,
|
|
|
|
0,
|
|
|
|
pAuthPolicyParse->elementDataProcessed + len + 1);
|
|
|
|
memcpy(pNewBuf,
|
|
|
|
*ppElementData,
|
|
|
|
pAuthPolicyParse->elementDataProcessed);
|
|
|
|
memcpy(pNewBuf + pAuthPolicyParse->elementDataProcessed, s, len);
|
|
|
|
pAuthPolicyParse->elementDataProcessed += len;
|
|
|
|
|
|
|
|
// Swap the buffers
|
|
|
|
free(*ppElementData);
|
|
|
|
*ppElementData = pNewBuf;
|
|
|
|
|
|
|
|
// Return the length of the element data buffer
|
|
|
|
*pElementDataLen = pAuthPolicyParse->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
|
|
|
|
AuthPolicyCharDataHandler(
|
|
|
|
IN AuthPolicyParse *pAuthPolicyParse,
|
|
|
|
IN const XML_Char *s,
|
|
|
|
IN int len)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
AuthContext *pAuthContext;
|
|
|
|
|
|
|
|
DbgTrace(2, "-AuthPolicyCharDataHandler- Start\n", 0);
|
|
|
|
|
|
|
|
// Just exit if being called to process white space
|
|
|
|
if (*s == '\n' || *s == '\r' || *s == '\t' || *s == ' ')
|
|
|
|
{
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Proceed based on the state
|
|
|
|
switch (pAuthPolicyParse->state)
|
|
|
|
{
|
|
|
|
case AWAITING_REALM_DATA:
|
|
|
|
|
|
|
|
// Get access to the AuthContext at the tail of the list
|
|
|
|
pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink,
|
|
|
|
AuthContext,
|
|
|
|
listEntry);
|
|
|
|
|
|
|
|
// Consume the data
|
|
|
|
pAuthPolicyParse->status = ConsumeElementData(pAuthPolicyParse,
|
|
|
|
s,
|
|
|
|
len,
|
|
|
|
&pAuthContext->pContext,
|
|
|
|
&pAuthContext->contextLen);
|
|
|
|
if (CASA_SUCCESS(pAuthPolicyParse->status))
|
|
|
|
{
|
|
|
|
// Advanced to the next state
|
|
|
|
pAuthPolicyParse->state = AWAITING_REALM_ELEMENT_END;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_MECHANISM_DATA:
|
2006-11-03 14:35:36 +01:00
|
|
|
case AWAITING_MECHANISM_ELEMENT_END:
|
2006-08-07 21:12:49 +02:00
|
|
|
|
|
|
|
// Get access to the AuthContext at the tail of the list
|
|
|
|
pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink,
|
|
|
|
AuthContext,
|
|
|
|
listEntry);
|
|
|
|
|
|
|
|
// Consume the data
|
|
|
|
pAuthPolicyParse->status = ConsumeElementData(pAuthPolicyParse,
|
|
|
|
s,
|
|
|
|
len,
|
|
|
|
&pAuthContext->pMechanism,
|
|
|
|
&pAuthContext->mechanismLen);
|
|
|
|
if (CASA_SUCCESS(pAuthPolicyParse->status))
|
|
|
|
{
|
|
|
|
// Advanced to the next state
|
|
|
|
pAuthPolicyParse->state = AWAITING_MECHANISM_ELEMENT_END;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_MECHANISM_INFO_DATA:
|
2006-11-03 14:35:36 +01:00
|
|
|
case AWAITING_MECHANISM_INFO_ELEMENT_END:
|
2006-08-07 21:12:49 +02:00
|
|
|
|
|
|
|
// Get access to the AuthContext at the tail of the list
|
|
|
|
pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink,
|
|
|
|
AuthContext,
|
|
|
|
listEntry);
|
|
|
|
|
|
|
|
// Consume the data
|
|
|
|
pAuthPolicyParse->status = ConsumeElementData(pAuthPolicyParse,
|
|
|
|
s,
|
|
|
|
len,
|
|
|
|
&pAuthContext->pMechInfo,
|
|
|
|
&pAuthContext->mechInfoLen);
|
|
|
|
if (CASA_SUCCESS(pAuthPolicyParse->status))
|
|
|
|
{
|
|
|
|
// Advanced to the next state
|
|
|
|
pAuthPolicyParse->state = AWAITING_MECHANISM_INFO_ELEMENT_END;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_UNKNOWN_DATA:
|
2006-11-03 14:35:36 +01:00
|
|
|
case AWAITING_UNKNOWN_ELEMENT_END:
|
2006-08-07 21:12:49 +02:00
|
|
|
|
|
|
|
// Just advance the state
|
|
|
|
pAuthPolicyParse->state = AWAITING_UNKNOWN_ELEMENT_END;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DbgTrace(0, "-AuthPolicyCharDataHandler- Un-expected state = %d\n", pAuthPolicyParse->state);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
|
|
|
|
DbgTrace(2, "-AuthPolicyCharDataHandler- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
static
|
|
|
|
void XMLCALL
|
|
|
|
AuthPolicyEndElementHandler(
|
|
|
|
IN AuthPolicyParse *pAuthPolicyParse,
|
|
|
|
IN const XML_Char *name)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
AuthContext *pAuthContext;
|
|
|
|
|
|
|
|
DbgTrace(2, "-AuthPolicyEndElementHandler- Start\n", 0);
|
|
|
|
|
|
|
|
// Proceed based on the state
|
|
|
|
switch (pAuthPolicyParse->state)
|
|
|
|
{
|
|
|
|
case AWAITING_ROOT_ELEMENT_END:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the Authentication
|
|
|
|
// Policy Element.
|
|
|
|
if (strcmp(name, AUTH_POLICY_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Done.
|
|
|
|
pAuthPolicyParse->state = DONE_PARSING;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_AUTH_SOURCE_CHILD_START:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the Authentication
|
|
|
|
// Source Response Element.
|
|
|
|
if (strcmp(name, AUTH_SOURCE_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Good, advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_ROOT_ELEMENT_END;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-AuthPolicyEndHandler- Un-expected end element\n", 0);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_REALM_ELEMENT_END:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the Realm Element.
|
|
|
|
if (strcmp(name, REALM_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Good, advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_MECHANISM_ELEMENT_END:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the Mechanism Element.
|
|
|
|
if (strcmp(name, MECHANISM_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Good, advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_MECHANISM_INFO_DATA:
|
|
|
|
|
|
|
|
// Get access to the AuthContext at the tail of the list
|
|
|
|
pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink,
|
|
|
|
AuthContext,
|
|
|
|
listEntry);
|
|
|
|
|
|
|
|
// There was no mechanism info data. Set it to an empty string.
|
|
|
|
pAuthContext->pMechInfo = (char*) malloc(1);
|
|
|
|
if (pAuthContext->pMechInfo)
|
|
|
|
{
|
|
|
|
*pAuthContext->pMechInfo = '\0';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-AuthPolicyEndElementHandler- Buffer allocation failure\n", 0);
|
|
|
|
pAuthPolicyParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Fall through
|
|
|
|
|
|
|
|
case AWAITING_MECHANISM_INFO_ELEMENT_END:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the Mechanism Info Element.
|
|
|
|
if (strcmp(name, MECHANISM_INFO_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Good, advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_UNKNOWN_ELEMENT_END:
|
|
|
|
|
|
|
|
// Advance to the next state.
|
|
|
|
pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected state = %d\n", pAuthPolicyParse->state);
|
|
|
|
XML_StopParser(pAuthPolicyParse->p, XML_FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(2, "-AuthPolicyEndElementHandler- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
CasaStatus
|
|
|
|
CreateAuthPolicy(
|
|
|
|
IN char *pEncodedData,
|
|
|
|
IN int encodedDataLen,
|
|
|
|
INOUT AuthPolicy **ppAuthPolicy)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
CasaStatus retStatus;
|
|
|
|
AuthPolicy *pAuthPolicy = NULL;
|
|
|
|
AuthPolicyParse authPolicyParse = {0};
|
|
|
|
char *pData = NULL;
|
|
|
|
int dataLen = 0;
|
|
|
|
|
|
|
|
DbgTrace(1, "-CreateAuthPolicy- Start\n", 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* An authentication policy document has the following format:
|
|
|
|
*
|
|
|
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
|
|
|
* <auth_policy>
|
|
|
|
* <auth_source>
|
|
|
|
* <realm>realm name</realm>
|
|
|
|
* <mechanism>authentication mechanism type</mechanism>
|
|
|
|
* <mechanism_info>authentication mechanism context data</mechanism_info>
|
|
|
|
* </auth_source>
|
|
|
|
* ...
|
|
|
|
* </auth_policy>
|
|
|
|
*
|
|
|
|
* The authentication policy document can contain multiple auth_source
|
|
|
|
* elements. These auth_source elements can be for different authentication
|
|
|
|
* sources or for the same authentication source but specifying a different
|
2006-11-03 14:35:36 +01:00
|
|
|
* authentication mechanism. The mechanism_info element is optional.
|
2006-08-07 21:12:49 +02:00
|
|
|
*
|
|
|
|
* The following is a sample authentication policy document:
|
|
|
|
*
|
|
|
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
|
|
|
* <auth_policy>
|
|
|
|
* <auth_source>
|
|
|
|
* <realm>Corp_eDirTree</realm>
|
|
|
|
* <mechanism>Krb5Authenticate</mechanism>
|
|
|
|
* <mechanism_info>host/hostname</mechanism_info>
|
|
|
|
* </auth_source>
|
|
|
|
* <auth_source>
|
|
|
|
* <realm>Corp_eDirTree</realm>
|
|
|
|
* <mechanism>PwdAuthenticate</mechanism>
|
|
|
|
* <mechanism_info></mechanism_info>
|
|
|
|
* </auth_source>
|
|
|
|
* </auth_policy>
|
|
|
|
*
|
|
|
|
* This authentication policy would tell the CASA client that it can
|
|
|
|
* authenticate to the CASA Authentication Token Service using
|
|
|
|
* credentials for the Corp_eDirTree and utilizing either the
|
|
|
|
* Krb5 authentication mechanism or the Pwd authentication mechanism.
|
|
|
|
* The Krb5 authentication mechanism context data specifies the
|
|
|
|
* name of the Kerberos service principal.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Initialize output parameter
|
|
|
|
*ppAuthPolicy = NULL;
|
|
|
|
|
|
|
|
// Decode the data
|
|
|
|
retStatus = DecodeData(pEncodedData,
|
|
|
|
encodedDataLen,
|
2006-10-06 22:13:14 +02:00
|
|
|
(void**) &pData,
|
2006-08-07 21:12:49 +02:00
|
|
|
&dataLen);
|
|
|
|
if (CASA_SUCCESS(retStatus))
|
|
|
|
{
|
|
|
|
// Allocate space for the AuthPolicy structure
|
|
|
|
pAuthPolicy = (AuthPolicy*) malloc(sizeof(*pAuthPolicy));
|
|
|
|
if (pAuthPolicy)
|
|
|
|
{
|
|
|
|
XML_Parser p;
|
|
|
|
|
|
|
|
// Initialize the AuthPolicy object
|
|
|
|
memset(pAuthPolicy, 0, sizeof(*pAuthPolicy));
|
|
|
|
InitializeListHead(&pAuthPolicy->authContextListHead);
|
|
|
|
|
|
|
|
// Set the AuthPolicy object in the parse object
|
|
|
|
authPolicyParse.pAuthPolicy = pAuthPolicy;
|
|
|
|
|
|
|
|
// Create parser
|
|
|
|
p = XML_ParserCreate(NULL);
|
|
|
|
if (p)
|
|
|
|
{
|
|
|
|
// Keep track of the parser in our parse object
|
|
|
|
authPolicyParse.p = p;
|
|
|
|
|
|
|
|
// Initialize the status within the parse object
|
|
|
|
authPolicyParse.status = CASA_STATUS_SUCCESS;
|
|
|
|
|
|
|
|
// Set the start and end element handlers
|
|
|
|
XML_SetElementHandler(p,
|
2006-10-06 22:13:14 +02:00
|
|
|
(XML_StartElementHandler) AuthPolicyStartElementHandler,
|
|
|
|
(XML_EndElementHandler) AuthPolicyEndElementHandler);
|
2006-08-07 21:12:49 +02:00
|
|
|
|
|
|
|
// Set the character data handler
|
2006-10-06 22:13:14 +02:00
|
|
|
XML_SetCharacterDataHandler(p, (XML_CharacterDataHandler) AuthPolicyCharDataHandler);
|
2006-08-07 21:12:49 +02:00
|
|
|
|
|
|
|
// Set our user data
|
|
|
|
XML_SetUserData(p, &authPolicyParse);
|
|
|
|
|
|
|
|
// Parse the document
|
|
|
|
if (XML_Parse(p, pData, dataLen, 1) == XML_STATUS_OK)
|
|
|
|
{
|
|
|
|
// Verify that the parse operation completed successfully
|
|
|
|
if (authPolicyParse.state == DONE_PARSING)
|
|
|
|
{
|
|
|
|
// The parse operation succeded
|
|
|
|
retStatus = CASA_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthPolicy- Parse operation did not complete\n", 0);
|
|
|
|
|
|
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_PROTOCOL_ERROR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthPolicy- 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, "-CreateAuthPolicy- Parser creation error\n", 0);
|
|
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the AuthPolicy object to the caller if necessary
|
|
|
|
if (CASA_SUCCESS(retStatus))
|
|
|
|
{
|
|
|
|
*ppAuthPolicy = pAuthPolicy;
|
|
|
|
|
|
|
|
// Forget about the AuthPolicy object so that it is not release down below
|
|
|
|
pAuthPolicy = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthPolicy- Buffer allocation error\n", 0);
|
|
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthPolicy- Buffer allocation error\n", 0);
|
|
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release necessary allocated resources
|
|
|
|
if (pAuthPolicy)
|
|
|
|
RelAuthPolicy(pAuthPolicy);
|
|
|
|
|
|
|
|
if (pData)
|
|
|
|
free(pData);
|
|
|
|
|
|
|
|
DbgTrace(1, "-CreateAuthPolicy- End, retStatus = %08X\n", retStatus);
|
|
|
|
|
|
|
|
return retStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
RelAuthPolicy(
|
|
|
|
IN AuthPolicy *pAuthPolicy)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
LIST_ENTRY *pListEntry;
|
|
|
|
|
|
|
|
DbgTrace(1, "-RelAuthPolicy- Start\n", 0);
|
|
|
|
|
|
|
|
// Free all of the associated AuthContexts
|
|
|
|
pListEntry = pAuthPolicy->authContextListHead.Flink;
|
|
|
|
while (pListEntry != &pAuthPolicy->authContextListHead)
|
|
|
|
{
|
|
|
|
AuthContext *pAuthContext;
|
|
|
|
|
|
|
|
// Get pointer to AuthContext structure
|
|
|
|
pAuthContext = CONTAINING_RECORD(pListEntry, AuthContext, listEntry);
|
|
|
|
|
|
|
|
// Free associated buffers
|
|
|
|
if (pAuthContext->pContext)
|
|
|
|
free(pAuthContext->pContext);
|
|
|
|
|
|
|
|
if (pAuthContext->pMechanism)
|
|
|
|
free(pAuthContext->pMechanism);
|
|
|
|
|
|
|
|
if (pAuthContext->pMechInfo)
|
|
|
|
free(pAuthContext->pMechInfo);
|
|
|
|
|
|
|
|
// Remove the entry from the list
|
|
|
|
RemoveEntryList(&pAuthContext->listEntry);
|
|
|
|
|
|
|
|
// Free the AuthContext
|
|
|
|
free(pAuthContext);
|
|
|
|
|
|
|
|
// Advance to the next entry
|
|
|
|
pListEntry = pAuthPolicy->authContextListHead.Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Free the AuthPolicy
|
|
|
|
free(pAuthPolicy);
|
|
|
|
|
|
|
|
DbgTrace(1, "-RelAuthPolicy- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
//++=======================================================================
|
|
|
|
//++=======================================================================
|
|
|
|
|