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.
804 lines
25 KiB
C
804 lines
25 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_STATUS_ELEMENT_START 0x2
|
|
#define AWAITING_STATUS_ELEMENT_END 0x3
|
|
#define AWAITING_STATUS_DATA 0x4
|
|
#define AWAITING_DESCRIPTION_ELEMENT_START 0x5
|
|
#define AWAITING_DESCRIPTION_ELEMENT_END 0x6
|
|
#define AWAITING_DESCRIPTION_DATA 0x7
|
|
#define AWAITING_SESSION_TOKEN_ELEMENT_START 0x8
|
|
#define AWAITING_SESSION_TOKEN_ELEMENT_END 0x9
|
|
#define AWAITING_SESSION_TOKEN_DATA 0xA
|
|
#define AWAITING_LIFETIME_DATA 0xB
|
|
#define AWAITING_LIFETIME_ELEMENT_START 0xC
|
|
#define AWAITING_LIFETIME_ELEMENT_END 0xD
|
|
#define AWAITING_AUTH_TOKEN_ELEMENT_START 0xE
|
|
#define AWAITING_AUTH_TOKEN_ELEMENT_END 0xF
|
|
#define AWAITING_AUTH_TOKEN_DATA 0x10
|
|
#define AWAITING_REALM_DATA 0x12
|
|
#define AWAITING_REALM_ELEMENT_END 0x13
|
|
#define DONE_PARSING 0x14
|
|
|
|
//
|
|
// Authentication Response Parse Structure
|
|
//
|
|
typedef struct _AuthRespParse
|
|
{
|
|
XML_Parser p;
|
|
int state;
|
|
int elementDataProcessed;
|
|
AuthenticateResp *pAuthenticateResp;
|
|
CasaStatus status;
|
|
|
|
} AuthRespParse, *PAuthRespParse;
|
|
|
|
|
|
//===[ Function prototypes ]===============================================
|
|
|
|
//===[ Global variables ]==================================================
|
|
|
|
//++=======================================================================
|
|
char*
|
|
BuildAuthenticateMsg(
|
|
IN AuthContext *pAuthContext,
|
|
IN char *pAuthMechToken)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
char *pMsg = NULL;
|
|
int bufferSize;
|
|
|
|
DbgTrace(1, "-BuildAuthenticateMsg- Start\n", 0);
|
|
|
|
/*
|
|
* The format of the authentication request message is as follows:
|
|
*
|
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
|
* <auth_req>
|
|
* <realm>realm value</realm>
|
|
* <mechanism>mechanism id value</mechanism>
|
|
* <auth_mech_token>authentication mechanism token data</auth_mech_token>
|
|
* </auth_req>
|
|
*
|
|
*/
|
|
|
|
// Determine the buffer size necessary to hold the msg
|
|
bufferSize = strlen(XML_DECLARATION)
|
|
+ 2 // crlf
|
|
+ 1 // <
|
|
+ strlen(AUTH_REQUEST_ELEMENT_NAME)
|
|
+ 3 // >crlf
|
|
+ 1 // <
|
|
+ strlen(REALM_ELEMENT_NAME)
|
|
+ 1 // >
|
|
+ strlen(pAuthContext->pContext)
|
|
+ 2 // </
|
|
+ strlen(REALM_ELEMENT_NAME)
|
|
+ 3 // >crlf
|
|
+ 1 // <
|
|
+ strlen(MECHANISM_ELEMENT_NAME)
|
|
+ 1 // >
|
|
+ strlen(pAuthContext->pMechanism)
|
|
+ 2 // </
|
|
+ strlen(MECHANISM_ELEMENT_NAME)
|
|
+ 3 // >crlf
|
|
+ 1 // <
|
|
+ strlen(AUTH_MECH_TOKEN_ELEMENT_NAME)
|
|
+ 1 // >
|
|
+ strlen(pAuthMechToken)
|
|
+ 2 // </
|
|
+ strlen(AUTH_MECH_TOKEN_ELEMENT_NAME)
|
|
+ 3 // >crlf
|
|
+ 2 // </
|
|
+ strlen(AUTH_REQUEST_ELEMENT_NAME)
|
|
+ 2; // >null
|
|
|
|
// Allocate the msg buffer
|
|
pMsg = (char*) malloc(bufferSize);
|
|
if (pMsg)
|
|
{
|
|
// Now build the message
|
|
memset(pMsg, 0, bufferSize);
|
|
strcat(pMsg, XML_DECLARATION);
|
|
strcat(pMsg, "\r\n");
|
|
strcat(pMsg, "<");
|
|
strcat(pMsg, AUTH_REQUEST_ELEMENT_NAME);
|
|
strcat(pMsg, ">\r\n");
|
|
strcat(pMsg, "<");
|
|
strcat(pMsg, REALM_ELEMENT_NAME);
|
|
strcat(pMsg, ">");
|
|
strcat(pMsg, pAuthContext->pContext);
|
|
strcat(pMsg, "</");
|
|
strcat(pMsg, REALM_ELEMENT_NAME);
|
|
strcat(pMsg, ">\r\n");
|
|
strcat(pMsg, "<");
|
|
strcat(pMsg, MECHANISM_ELEMENT_NAME);
|
|
strcat(pMsg, ">");
|
|
strcat(pMsg, pAuthContext->pMechanism);
|
|
strcat(pMsg, "</");
|
|
strcat(pMsg, MECHANISM_ELEMENT_NAME);
|
|
strcat(pMsg, ">\r\n");
|
|
strcat(pMsg, "<");
|
|
strcat(pMsg, AUTH_MECH_TOKEN_ELEMENT_NAME);
|
|
strcat(pMsg, ">");
|
|
strcat(pMsg, pAuthMechToken);
|
|
strcat(pMsg, "</");
|
|
strcat(pMsg, AUTH_MECH_TOKEN_ELEMENT_NAME);
|
|
strcat(pMsg, ">\r\n");
|
|
strcat(pMsg, "</");
|
|
strcat(pMsg, AUTH_REQUEST_ELEMENT_NAME);
|
|
strcat(pMsg, ">");
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-BuildAuthenticateMsg- Buffer allocation error\n", 0);
|
|
}
|
|
|
|
DbgTrace(1, "-BuildAuthenticateMsg- End, pMsg = %0lX\n", (long) pMsg);
|
|
|
|
return pMsg;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
void XMLCALL
|
|
AuthRespStartElementHandler(
|
|
IN AuthRespParse *pAuthRespParse,
|
|
IN const XML_Char *name,
|
|
IN const XML_Char **atts)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
DbgTrace(2, "-AuthRespStartElementHandler- Start\n", 0);
|
|
|
|
// Proceed based on the state
|
|
switch (pAuthRespParse->state)
|
|
{
|
|
case AWAITING_ROOT_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the Authentication
|
|
// Response Element.
|
|
if (strcmp(name, AUTH_RESPONSE_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pAuthRespParse->state = AWAITING_STATUS_ELEMENT_START;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_STATUS_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the Status Element.
|
|
if (strcmp(name, STATUS_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pAuthRespParse->state = AWAITING_DESCRIPTION_ELEMENT_START;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_DESCRIPTION_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the Description Element.
|
|
if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pAuthRespParse->state = AWAITING_DESCRIPTION_DATA;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_SESSION_TOKEN_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the Session Token Element.
|
|
if (strcmp(name, SESSION_TOKEN_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pAuthRespParse->state = AWAITING_LIFETIME_ELEMENT_START;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_LIFETIME_ELEMENT_START:
|
|
|
|
// In this state, we are only expecting the Lifetime Element.
|
|
if (strcmp(name, LIFETIME_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pAuthRespParse->state = AWAITING_LIFETIME_DATA;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DbgTrace(0, "-AuthRespStartElementHandler- Un-expected state = %d\n", pAuthRespParse->state);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
break;
|
|
}
|
|
|
|
DbgTrace(2, "-AuthRespStartElementHandler- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
CasaStatus
|
|
ConsumeElementData(
|
|
IN AuthRespParse *pAuthRespParse,
|
|
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
|
|
pAuthRespParse->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 = pAuthRespParse->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(pAuthRespParse->elementDataProcessed + len + 1);
|
|
if (pNewBuf)
|
|
{
|
|
memset(pNewBuf,
|
|
0,
|
|
pAuthRespParse->elementDataProcessed + len + 1);
|
|
memcpy(pNewBuf,
|
|
*ppElementData,
|
|
pAuthRespParse->elementDataProcessed);
|
|
memcpy(pNewBuf + pAuthRespParse->elementDataProcessed, s, len);
|
|
pAuthRespParse->elementDataProcessed += len;
|
|
|
|
// Swap the buffers
|
|
free(*ppElementData);
|
|
*ppElementData = pNewBuf;
|
|
|
|
// Return the length of the element data buffer
|
|
*pElementDataLen = pAuthRespParse->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
|
|
AuthRespCharDataHandler(
|
|
IN AuthRespParse *pAuthRespParse,
|
|
IN const XML_Char *s,
|
|
IN int len)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
DbgTrace(2, "-AuthRespCharDataHandler- 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 (pAuthRespParse->state)
|
|
{
|
|
case AWAITING_DESCRIPTION_DATA:
|
|
case AWAITING_DESCRIPTION_ELEMENT_END:
|
|
|
|
// Ignore the status description data for now.
|
|
// tbd
|
|
|
|
// Advanced to the next state
|
|
pAuthRespParse->state = AWAITING_DESCRIPTION_ELEMENT_END;
|
|
break;
|
|
|
|
case AWAITING_STATUS_DATA:
|
|
|
|
// Set the appropriate status in the AuthenticationResp based on the
|
|
// returned status.
|
|
if (strncmp(HTTP_OK_STATUS_CODE, s, len) == 0)
|
|
{
|
|
pAuthRespParse->status = CASA_STATUS_SUCCESS;
|
|
}
|
|
else if (strncmp(HTTP_UNAUTHORIZED_STATUS_CODE, s, len) == 0)
|
|
{
|
|
pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_AUTHENTICATION_FAILURE);
|
|
}
|
|
else if (strncmp(HTTP_NOT_FOUND_STATUS_CODE, s, len) == 0)
|
|
{
|
|
pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_CONFIGURATION_ERROR);
|
|
}
|
|
else if (strncmp(HTTP_SERVER_ERROR_STATUS_CODE, s, len) == 0)
|
|
{
|
|
pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_SERVER_ERROR);
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespCharDataHandler- Un-expected status\n", 0);
|
|
pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_UNSUCCESSFUL);
|
|
}
|
|
|
|
// Advanced to the next state
|
|
pAuthRespParse->state = AWAITING_STATUS_ELEMENT_END;
|
|
break;
|
|
|
|
case AWAITING_LIFETIME_DATA:
|
|
|
|
// Convert the lifetime string to a numeric value
|
|
pAuthRespParse->pAuthenticateResp->tokenLifetime = dtoul(s, len);
|
|
|
|
// Advanced to the next state
|
|
pAuthRespParse->state = AWAITING_LIFETIME_ELEMENT_END;
|
|
break;
|
|
|
|
case AWAITING_SESSION_TOKEN_DATA:
|
|
case AWAITING_SESSION_TOKEN_ELEMENT_END:
|
|
|
|
// Consume the data
|
|
pAuthRespParse->status = ConsumeElementData(pAuthRespParse,
|
|
s,
|
|
len,
|
|
&pAuthRespParse->pAuthenticateResp->pToken,
|
|
&pAuthRespParse->pAuthenticateResp->tokenLen);
|
|
if (CASA_SUCCESS(pAuthRespParse->status))
|
|
{
|
|
// Advanced to the next state
|
|
pAuthRespParse->state = AWAITING_SESSION_TOKEN_ELEMENT_END;
|
|
}
|
|
else
|
|
{
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DbgTrace(0, "-AuthRespCharDataHandler- Un-expected state = %d\n", pAuthRespParse->state);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
break;
|
|
}
|
|
|
|
exit:
|
|
|
|
DbgTrace(2, "-AuthRespCharDataHandler- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static
|
|
void XMLCALL
|
|
AuthRespEndElementHandler(
|
|
IN AuthRespParse *pAuthRespParse,
|
|
IN const XML_Char *name)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
DbgTrace(2, "-AuthRespEndElementHandler- Start\n", 0);
|
|
|
|
// Proceed based on the state
|
|
switch (pAuthRespParse->state)
|
|
{
|
|
case AWAITING_ROOT_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the Authentication
|
|
// Response Element.
|
|
if (strcmp(name, AUTH_RESPONSE_ELEMENT_NAME) == 0)
|
|
{
|
|
// Done.
|
|
pAuthRespParse->state = DONE_PARSING;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespEndHandler- Un-expected end element\n", 0);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_DESCRIPTION_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the Description Element.
|
|
if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pAuthRespParse->state = AWAITING_STATUS_DATA;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespEndElementHandler- Un-expected end element\n", 0);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_STATUS_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the Status Element.
|
|
if (strcmp(name, STATUS_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state based on the status code.
|
|
if (CASA_SUCCESS(pAuthRespParse->status))
|
|
{
|
|
// The request completed successfully
|
|
pAuthRespParse->state = AWAITING_SESSION_TOKEN_ELEMENT_START;
|
|
}
|
|
else
|
|
{
|
|
pAuthRespParse->state = AWAITING_ROOT_ELEMENT_END;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespEndElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_LIFETIME_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the Lifetime Element.
|
|
if (strcmp(name, LIFETIME_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pAuthRespParse->state = AWAITING_SESSION_TOKEN_DATA;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespEndElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
case AWAITING_SESSION_TOKEN_ELEMENT_END:
|
|
|
|
// In this state, we are only expecting the Session Token Element.
|
|
if (strcmp(name, SESSION_TOKEN_ELEMENT_NAME) == 0)
|
|
{
|
|
// Good, advance to the next state.
|
|
pAuthRespParse->state = AWAITING_ROOT_ELEMENT_END;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-AuthRespEndElementHandler- Un-expected start element\n", 0);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DbgTrace(0, "-AuthRespEndElementHandler- Un-expected state = %d\n", pAuthRespParse->state);
|
|
XML_StopParser(pAuthRespParse->p, XML_FALSE);
|
|
break;
|
|
}
|
|
|
|
DbgTrace(2, "-AuthRespEndElementHandler- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
CasaStatus
|
|
CreateAuthenticateResp(
|
|
IN char *pRespMsg,
|
|
IN int respLen,
|
|
INOUT AuthenticateResp **ppAuthenticateResp)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
|
AuthRespParse authRespParse = {0};
|
|
AuthenticateResp *pAuthenticateResp;
|
|
|
|
DbgTrace(1, "-CreateAuthenticateResp- Start\n", 0);
|
|
|
|
/*
|
|
* When an authentication request is processed successfully, the server replies to
|
|
* the client with a message with the following format:
|
|
*
|
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
|
* <auth_resp>
|
|
* <status><description>ok</description>200</status>
|
|
* <session_token><lifetime>lifetime value</lifetime>session token data</session_token>
|
|
* </auth_resp>
|
|
*
|
|
* When an authentication request fails to be successfully processed, the server
|
|
* responds with an error and an error description string. The message format of
|
|
* an unsuccessful reply is as follows:
|
|
*
|
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
|
* <auth_resp>
|
|
* <status><description>status description</description>status code</status>
|
|
* </auth_resp>
|
|
*
|
|
* Plase note that the protocol utilizes the status codes defined
|
|
* in the HTTP 1.1 Specification.
|
|
*
|
|
*/
|
|
|
|
// Allocate AuthenticateResp object
|
|
pAuthenticateResp = malloc(sizeof(*pAuthenticateResp));
|
|
if (pAuthenticateResp)
|
|
{
|
|
XML_Parser p;
|
|
|
|
// Initialize the AuthenticateResp object and set it in the
|
|
// authentication response parse oject.
|
|
memset(pAuthenticateResp, 0, sizeof(*pAuthenticateResp));
|
|
authRespParse.pAuthenticateResp = pAuthenticateResp;
|
|
|
|
// Create parser
|
|
p = XML_ParserCreate(NULL);
|
|
if (p)
|
|
{
|
|
// Keep track of the parser in our parse object
|
|
authRespParse.p = p;
|
|
|
|
// Initialize the status within the parse object
|
|
authRespParse.status = CASA_STATUS_SUCCESS;
|
|
|
|
// Set the start and end element handlers
|
|
XML_SetElementHandler(p,
|
|
(XML_StartElementHandler) AuthRespStartElementHandler,
|
|
(XML_EndElementHandler) AuthRespEndElementHandler);
|
|
|
|
// Set the character data handler
|
|
XML_SetCharacterDataHandler(p, (XML_CharacterDataHandler) AuthRespCharDataHandler);
|
|
|
|
|
|
// Set our user data
|
|
XML_SetUserData(p, &authRespParse);
|
|
|
|
// Parse the document
|
|
if (XML_Parse(p, pRespMsg, respLen, 1) == XML_STATUS_OK)
|
|
{
|
|
// Verify that the parse operation completed successfully
|
|
if (authRespParse.state == DONE_PARSING)
|
|
{
|
|
// The parse operation succeded, obtain the status returned
|
|
// by the server.
|
|
retStatus = authRespParse.status;
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-CreateAuthenticateResp- Parse operation did not complete\n", 0);
|
|
|
|
// Check if a status has been recorded
|
|
if (authRespParse.status != CASA_STATUS_SUCCESS)
|
|
{
|
|
retStatus = authRespParse.status;
|
|
}
|
|
else
|
|
{
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_PROTOCOL_ERROR);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-CreateAuthenticateResp- 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, "-CreateAuthenticateResp- Parser creation error\n", 0);
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
|
|
// Return the AuthenticationResp object to the caller if necessary
|
|
if (CASA_SUCCESS(retStatus))
|
|
{
|
|
*ppAuthenticateResp = pAuthenticateResp;
|
|
}
|
|
else
|
|
{
|
|
free(pAuthenticateResp);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-CreateAuthenticateResp- Memory allocation error\n", 0);
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
|
|
DbgTrace(1, "-CreateAuthenticateResp- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
void
|
|
RelAuthenticateResp(
|
|
IN AuthenticateResp *pAuthenticateResp)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
DbgTrace(1, "-RelAuthenticateResp- Start\n", 0);
|
|
|
|
// Free the resources associated with the object
|
|
if (pAuthenticateResp->pToken)
|
|
free(pAuthenticateResp->pToken);
|
|
|
|
free(pAuthenticateResp);
|
|
|
|
DbgTrace(1, "-RelAuthenticateResp- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
|