2c8668479c
to be able to deliver the client component onto distributions targeting desktops without having to deliver the server components. This commit is for the resulting client project.
805 lines
26 KiB
C
805 lines
26 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 ]==================================================
|
|
|
|
//
|
|
// 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:
|
|
case AWAITING_MECHANISM_ELEMENT_END:
|
|
|
|
// 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:
|
|
case AWAITING_MECHANISM_INFO_ELEMENT_END:
|
|
|
|
// 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:
|
|
case AWAITING_UNKNOWN_ELEMENT_END:
|
|
|
|
// 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
|
|
* authentication mechanism. The mechanism_info element is optional.
|
|
*
|
|
* 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,
|
|
(void**) &pData,
|
|
&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,
|
|
(XML_StartElementHandler) AuthPolicyStartElementHandler,
|
|
(XML_EndElementHandler) AuthPolicyEndElementHandler);
|
|
|
|
// Set the character data handler
|
|
XML_SetCharacterDataHandler(p, (XML_CharacterDataHandler) AuthPolicyCharDataHandler);
|
|
|
|
// 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);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
|