2006-11-13 06:20:43 +01: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_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_LIFETIME_DATA 0x8
|
|
|
|
#define AWAITING_LIFETIME_ELEMENT_START 0x9
|
|
|
|
#define AWAITING_LIFETIME_ELEMENT_END 0xA
|
|
|
|
#define AWAITING_AUTH_TOKEN_ELEMENT_START 0xB
|
|
|
|
#define AWAITING_AUTH_TOKEN_ELEMENT_END 0xC
|
|
|
|
#define AWAITING_AUTH_TOKEN_DATA 0xD
|
|
|
|
#define DONE_PARSING 0xE
|
|
|
|
|
|
|
|
//
|
|
|
|
// Get Authentication Token Response Parse Structure
|
|
|
|
//
|
|
|
|
typedef struct _GetAuthTokenRespParse
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
XML_Parser p;
|
|
|
|
int state;
|
|
|
|
int elementDataProcessed;
|
|
|
|
char *pStatusData;
|
|
|
|
int statusDataLen;
|
|
|
|
char *pLifetimeData;
|
|
|
|
int lifetimeDataLen;
|
|
|
|
GetAuthTokenResp *pGetAuthTokenResp;
|
|
|
|
CasaStatus status;
|
2006-11-13 06:20:43 +01:00
|
|
|
|
|
|
|
} GetAuthTokenRespParse, *PGetAuthTokenRespParse;
|
|
|
|
|
|
|
|
|
|
|
|
//===[ Function prototypes ]===============================================
|
|
|
|
|
|
|
|
//===[ Global variables ]==================================================
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
char*
|
|
|
|
BuildGetAuthTokenMsg(
|
|
|
|
IN const char *pServiceName,
|
|
|
|
IN const char *pHostName,
|
|
|
|
IN char *pSessionToken)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
char *pMsg = NULL;
|
|
|
|
int bufferSize;
|
|
|
|
|
|
|
|
DbgTrace(1, "-BuildGetAuthTokenMsg- Start\n", 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The format of the get authentication token request message
|
|
|
|
* is as follows:
|
|
|
|
*
|
|
|
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
|
|
|
* <get_auth_token_req>
|
|
|
|
* <service>service name</service>
|
|
|
|
* <host>host name</host>
|
|
|
|
* <session_token>session token data</session_token>
|
|
|
|
* </get_auth_token_req>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Determine the buffer size necessary to hold the msg
|
|
|
|
bufferSize = strlen(XML_DECLARATION)
|
|
|
|
+ 2 // crlf
|
|
|
|
+ 1 // <
|
|
|
|
+ strlen(GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME)
|
|
|
|
+ 3 // >crlf
|
|
|
|
+ 1 // <
|
|
|
|
+ strlen(SERVICE_ELEMENT_NAME)
|
|
|
|
+ 1 // >
|
|
|
|
+ strlen(pServiceName)
|
|
|
|
+ 2 // </
|
|
|
|
+ strlen(SERVICE_ELEMENT_NAME)
|
|
|
|
+ 3 // >crlf
|
|
|
|
+ 1 // <
|
|
|
|
+ strlen(HOST_ELEMENT_NAME)
|
|
|
|
+ 1 // >
|
|
|
|
+ strlen(pHostName)
|
|
|
|
+ 2 // </
|
|
|
|
+ strlen(HOST_ELEMENT_NAME)
|
|
|
|
+ 3 // >crlf
|
|
|
|
+ 1 // <
|
|
|
|
+ strlen(SESSION_TOKEN_ELEMENT_NAME)
|
|
|
|
+ 1 // >
|
|
|
|
+ strlen(pSessionToken)
|
|
|
|
+ 2 // </
|
|
|
|
+ strlen(SESSION_TOKEN_ELEMENT_NAME)
|
|
|
|
+ 3 // >crlf
|
|
|
|
+ 2 // </
|
|
|
|
+ strlen(GET_AUTH_TOKEN_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, GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME);
|
|
|
|
strcat(pMsg, ">\r\n");
|
|
|
|
strcat(pMsg, "<");
|
|
|
|
strcat(pMsg, SERVICE_ELEMENT_NAME);
|
|
|
|
strcat(pMsg, ">");
|
|
|
|
strcat(pMsg, pServiceName);
|
|
|
|
strcat(pMsg, "</");
|
|
|
|
strcat(pMsg, SERVICE_ELEMENT_NAME);
|
|
|
|
strcat(pMsg, ">\r\n");
|
|
|
|
strcat(pMsg, "<");
|
|
|
|
strcat(pMsg, HOST_ELEMENT_NAME);
|
|
|
|
strcat(pMsg, ">");
|
|
|
|
strcat(pMsg, pHostName);
|
|
|
|
strcat(pMsg, "</");
|
|
|
|
strcat(pMsg, HOST_ELEMENT_NAME);
|
|
|
|
strcat(pMsg, ">\r\n");
|
|
|
|
strcat(pMsg, "<");
|
|
|
|
strcat(pMsg, SESSION_TOKEN_ELEMENT_NAME);
|
|
|
|
strcat(pMsg, ">");
|
|
|
|
strcat(pMsg, pSessionToken);
|
|
|
|
strcat(pMsg, "</");
|
|
|
|
strcat(pMsg, SESSION_TOKEN_ELEMENT_NAME);
|
|
|
|
strcat(pMsg, ">\r\n");
|
|
|
|
strcat(pMsg, "</");
|
|
|
|
strcat(pMsg, GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME);
|
|
|
|
strcat(pMsg, ">");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-BuildGetAuthTokenMsg- Buffer allocation error\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "-BuildGetAuthTokenMsg- End, pMsg = %0lX\n", (long) pMsg);
|
|
|
|
|
|
|
|
return pMsg;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
static
|
|
|
|
void XMLCALL
|
|
|
|
GetAuthTokenRespStartElementHandler(
|
|
|
|
IN GetAuthTokenRespParse *pGetAuthTokenRespParse,
|
|
|
|
IN const XML_Char *name,
|
|
|
|
IN const XML_Char **atts)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(2, "-GetAuthTokenRespStartElementHandler- Start\n", 0);
|
|
|
|
|
|
|
|
// Proceed based on the state
|
|
|
|
switch (pGetAuthTokenRespParse->state)
|
|
|
|
{
|
|
|
|
case AWAITING_ROOT_ELEMENT_START:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the Get Authentication
|
|
|
|
// Token Response Element.
|
|
|
|
if (strcmp(name, GET_AUTH_TOKEN_RESPONSE_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Good, advance to the next state.
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_STATUS_ELEMENT_START;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected element\n", 0);
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->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.
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_DESCRIPTION_ELEMENT_START;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected element\n", 0);
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->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.
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_DESCRIPTION_DATA;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected element\n", 0);
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_AUTH_TOKEN_ELEMENT_START:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the Authentication Token Element.
|
|
|
|
if (strcmp(name, AUTH_TOKEN_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Good, advance to the next state.
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_LIFETIME_ELEMENT_START;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected element\n", 0);
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->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.
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_LIFETIME_DATA;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected element\n", 0);
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected state = %d\n", pGetAuthTokenRespParse->state);
|
|
|
|
XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(2, "-GetAuthTokenRespStartElementHandler- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
static
|
|
|
|
CasaStatus
|
|
|
|
ConsumeElementData(
|
|
|
|
IN GetAuthTokenRespParse *pGetAuthTokenRespParse,
|
|
|
|
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
|
|
|
|
pGetAuthTokenRespParse->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 = pGetAuthTokenRespParse->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(pGetAuthTokenRespParse->elementDataProcessed + len + 1);
|
|
|
|
if (pNewBuf)
|
|
|
|
{
|
|
|
|
memset(pNewBuf,
|
|
|
|
0,
|
|
|
|
pGetAuthTokenRespParse->elementDataProcessed + len + 1);
|
|
|
|
memcpy(pNewBuf,
|
|
|
|
*ppElementData,
|
|
|
|
pGetAuthTokenRespParse->elementDataProcessed);
|
|
|
|
memcpy(pNewBuf + pGetAuthTokenRespParse->elementDataProcessed, s, len);
|
|
|
|
pGetAuthTokenRespParse->elementDataProcessed += len;
|
|
|
|
|
2007-01-04 11:18:40 +01:00
|
|
|
// Swap the buffers after clearing and freeing the original
|
|
|
|
// buffer since it may contain sensitive information.
|
|
|
|
memset(*ppElementData, 0, pGetAuthTokenRespParse->elementDataProcessed - len);
|
2006-11-13 06:20:43 +01:00
|
|
|
*ppElementData = pNewBuf;
|
|
|
|
|
|
|
|
// Return the length of the element data buffer
|
|
|
|
*pElementDataLen = pGetAuthTokenRespParse->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
|
|
|
|
GetAuthTokenRespCharDataHandler(
|
|
|
|
IN GetAuthTokenRespParse *pGetAuthTokenRespParse,
|
|
|
|
IN const XML_Char *s,
|
|
|
|
IN int len)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
CasaStatus status;
|
|
|
|
|
2006-11-13 06:20:43 +01:00
|
|
|
DbgTrace(2, "-GetAuthTokenRespCharDataHandler- 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 (pGetAuthTokenRespParse->state)
|
|
|
|
{
|
|
|
|
case AWAITING_DESCRIPTION_DATA:
|
|
|
|
case AWAITING_DESCRIPTION_ELEMENT_END:
|
|
|
|
|
|
|
|
// Ignore the status description data for now.
|
|
|
|
// tbd
|
|
|
|
|
|
|
|
// Advanced to the next state
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_DESCRIPTION_ELEMENT_END;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_STATUS_DATA:
|
2006-11-30 19:21:42 +01:00
|
|
|
case AWAITING_STATUS_ELEMENT_END:
|
2006-11-13 06:20:43 +01:00
|
|
|
|
2006-11-30 19:21:42 +01:00
|
|
|
// Consume the data
|
|
|
|
status = ConsumeElementData(pGetAuthTokenRespParse,
|
|
|
|
s,
|
|
|
|
len,
|
|
|
|
&pGetAuthTokenRespParse->pStatusData,
|
|
|
|
&pGetAuthTokenRespParse->statusDataLen);
|
|
|
|
if (CASA_SUCCESS(status))
|
2006-11-13 06:20:43 +01:00
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
// Advanced to the next state
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_STATUS_ELEMENT_END;
|
2006-11-13 06:20:43 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
pGetAuthTokenRespParse->status = status;
|
|
|
|
XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
|
2006-11-13 06:20:43 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_LIFETIME_DATA:
|
2006-11-30 19:21:42 +01:00
|
|
|
case AWAITING_LIFETIME_ELEMENT_END:
|
2006-11-13 06:20:43 +01:00
|
|
|
|
2006-11-30 19:21:42 +01:00
|
|
|
// Consume the data
|
|
|
|
status = ConsumeElementData(pGetAuthTokenRespParse,
|
|
|
|
s,
|
|
|
|
len,
|
|
|
|
&pGetAuthTokenRespParse->pLifetimeData,
|
|
|
|
&pGetAuthTokenRespParse->lifetimeDataLen);
|
|
|
|
if (CASA_SUCCESS(status))
|
|
|
|
{
|
|
|
|
// Advanced to the next state
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_LIFETIME_ELEMENT_END;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pGetAuthTokenRespParse->status = status;
|
|
|
|
XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
|
|
|
|
}
|
2006-11-13 06:20:43 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_AUTH_TOKEN_DATA:
|
|
|
|
case AWAITING_AUTH_TOKEN_ELEMENT_END:
|
|
|
|
|
|
|
|
// Consume the data
|
2006-11-30 19:21:42 +01:00
|
|
|
status = ConsumeElementData(pGetAuthTokenRespParse,
|
|
|
|
s,
|
|
|
|
len,
|
|
|
|
&pGetAuthTokenRespParse->pGetAuthTokenResp->pToken,
|
|
|
|
&pGetAuthTokenRespParse->pGetAuthTokenResp->tokenLen);
|
|
|
|
if (CASA_SUCCESS(status))
|
2006-11-13 06:20:43 +01:00
|
|
|
{
|
|
|
|
// Advanced to the next state
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_AUTH_TOKEN_ELEMENT_END;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
pGetAuthTokenRespParse->status = status;
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DbgTrace(0, "-GetAuthTokenRespCharDataHandler- Un-expected state = %d\n", pGetAuthTokenRespParse->state);
|
|
|
|
XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
|
|
|
|
DbgTrace(2, "-GetAuthTokenRespCharDataHandler- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
static
|
|
|
|
void XMLCALL
|
|
|
|
GetAuthTokenRespEndElementHandler(
|
|
|
|
IN GetAuthTokenRespParse *pGetAuthTokenRespParse,
|
|
|
|
IN const XML_Char *name)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(2, "-GetAuthTokenRespEndElementHandler- Start\n", 0);
|
|
|
|
|
|
|
|
// Proceed based on the state
|
|
|
|
switch (pGetAuthTokenRespParse->state)
|
|
|
|
{
|
|
|
|
case AWAITING_ROOT_ELEMENT_END:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the Get Authentication
|
|
|
|
// Token Response Element.
|
|
|
|
if (strcmp(name, GET_AUTH_TOKEN_RESPONSE_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Done.
|
|
|
|
pGetAuthTokenRespParse->state = DONE_PARSING;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
DbgTrace(0, "-GetAuthTokenRespEndHandler- Un-expected element\n", 0);
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->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.
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_STATUS_DATA;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected element\n", 0);
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->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)
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
// Set the appropriate status in the GetAuthTokenResp based on the returned status data
|
|
|
|
if (strncmp(HTTP_OK_STATUS_CODE,
|
|
|
|
pGetAuthTokenRespParse->pStatusData,
|
|
|
|
pGetAuthTokenRespParse->statusDataLen) == 0)
|
|
|
|
{
|
|
|
|
pGetAuthTokenRespParse->status = CASA_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else if (strncmp(HTTP_UNAUTHORIZED_STATUS_CODE,
|
|
|
|
pGetAuthTokenRespParse->pStatusData,
|
|
|
|
pGetAuthTokenRespParse->statusDataLen) == 0)
|
|
|
|
{
|
|
|
|
pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_AUTHENTICATION_FAILURE);
|
|
|
|
}
|
|
|
|
else if (strncmp(HTTP_SERVER_ERROR_STATUS_CODE,
|
|
|
|
pGetAuthTokenRespParse->pStatusData,
|
|
|
|
pGetAuthTokenRespParse->statusDataLen) == 0)
|
|
|
|
{
|
|
|
|
pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_SERVER_ERROR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected status\n", 0);
|
|
|
|
pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_UNSUCCESSFUL);
|
|
|
|
}
|
|
|
|
|
2006-11-13 06:20:43 +01:00
|
|
|
// Good, advance to the next state based on the status code.
|
|
|
|
if (CASA_SUCCESS(pGetAuthTokenRespParse->status))
|
|
|
|
{
|
|
|
|
// The request completed successfully
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_AUTH_TOKEN_ELEMENT_START;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_ROOT_ELEMENT_END;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected element\n", 0);
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->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)
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
// Convert the lifetime string to a numeric value
|
|
|
|
pGetAuthTokenRespParse->pGetAuthTokenResp->tokenLifetime = dtoul(pGetAuthTokenRespParse->pLifetimeData,
|
|
|
|
pGetAuthTokenRespParse->lifetimeDataLen);
|
|
|
|
|
2006-11-13 06:20:43 +01:00
|
|
|
// Good, advance to the next state.
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_AUTH_TOKEN_DATA;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected element\n", 0);
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AWAITING_AUTH_TOKEN_ELEMENT_END:
|
|
|
|
|
|
|
|
// In this state, we are only expecting the Authentication Token Element.
|
|
|
|
if (strcmp(name, AUTH_TOKEN_ELEMENT_NAME) == 0)
|
|
|
|
{
|
|
|
|
// Good, advance to the next state.
|
|
|
|
pGetAuthTokenRespParse->state = AWAITING_ROOT_ELEMENT_END;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-30 19:21:42 +01:00
|
|
|
DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected element\n", 0);
|
2006-11-13 06:20:43 +01:00
|
|
|
XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected state = %d\n", pGetAuthTokenRespParse->state);
|
|
|
|
XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(2, "-GetAuthTokenRespEndElementHandler- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
CasaStatus
|
|
|
|
CreateGetAuthTokenResp(
|
|
|
|
IN char *pRespMsg,
|
|
|
|
IN int respLen,
|
|
|
|
INOUT GetAuthTokenResp **ppGetAuthTokenResp)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
|
|
|
GetAuthTokenRespParse getAuthTokenRespParse = {0};
|
|
|
|
GetAuthTokenResp *pGetAuthTokenResp;
|
|
|
|
|
|
|
|
DbgTrace(1, "-CreateGetAuthTokenResp- Start\n", 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* When a get authentication token 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"?>
|
|
|
|
* <get_auth_token_resp>
|
|
|
|
* <status><description>ok</description>200</status>
|
|
|
|
* <auth_token><lifetime>lifetime value</lifetime>session token data</auth_token>
|
|
|
|
* </get_auth_token_resp>
|
|
|
|
*
|
|
|
|
* When a get authentication token 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"?>
|
|
|
|
* <get_auth_token_resp>
|
|
|
|
* <status><description>status description</description>status code</status>
|
|
|
|
* </get_auth_token_resp>
|
|
|
|
*
|
|
|
|
* Plase note that the protocol utilizes the status codes defined
|
|
|
|
* in the HTTP 1.1 Specification.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Allocate GetAuthTokenResp object
|
|
|
|
pGetAuthTokenResp = malloc(sizeof(*pGetAuthTokenResp));
|
|
|
|
if (pGetAuthTokenResp)
|
|
|
|
{
|
|
|
|
XML_Parser p;
|
|
|
|
|
|
|
|
// Initialize the GetAuthTokenResp object and set it in the
|
|
|
|
// parse oject.
|
|
|
|
memset(pGetAuthTokenResp, 0, sizeof(*pGetAuthTokenResp));
|
|
|
|
getAuthTokenRespParse.pGetAuthTokenResp = pGetAuthTokenResp;
|
|
|
|
|
|
|
|
// Create parser
|
|
|
|
p = XML_ParserCreate(NULL);
|
|
|
|
if (p)
|
|
|
|
{
|
|
|
|
// Keep track of the parser in our parse object
|
|
|
|
getAuthTokenRespParse.p = p;
|
|
|
|
|
|
|
|
// Initialize the status within the parse object
|
|
|
|
getAuthTokenRespParse.status = CASA_STATUS_SUCCESS;
|
|
|
|
|
|
|
|
// Set the start and end element handlers
|
|
|
|
XML_SetElementHandler(p,
|
|
|
|
(XML_StartElementHandler) GetAuthTokenRespStartElementHandler,
|
|
|
|
(XML_EndElementHandler) GetAuthTokenRespEndElementHandler);
|
|
|
|
|
|
|
|
// Set the character data handler
|
|
|
|
XML_SetCharacterDataHandler(p, (XML_CharacterDataHandler) GetAuthTokenRespCharDataHandler);
|
|
|
|
|
|
|
|
// Set our user data
|
|
|
|
XML_SetUserData(p, &getAuthTokenRespParse);
|
|
|
|
|
|
|
|
// Parse the document
|
|
|
|
if (XML_Parse(p, pRespMsg, respLen, 1) == XML_STATUS_OK)
|
|
|
|
{
|
|
|
|
// Verify that the parse operation completed successfully
|
|
|
|
if (getAuthTokenRespParse.state == DONE_PARSING)
|
|
|
|
{
|
|
|
|
// The parse operation succeded, obtain the status returned
|
|
|
|
// by the server.
|
|
|
|
retStatus = getAuthTokenRespParse.status;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateGetAuthTokenResp- Parse operation did not complete\n", 0);
|
|
|
|
|
|
|
|
// Check if a status has been recorded
|
|
|
|
if (getAuthTokenRespParse.status != CASA_STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
retStatus = getAuthTokenRespParse.status;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_PROTOCOL_ERROR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateGetAuthTokenResp- 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);
|
2006-11-30 19:21:42 +01:00
|
|
|
|
|
|
|
// Free any buffers associated with the parse
|
|
|
|
if (getAuthTokenRespParse.pStatusData)
|
|
|
|
free(getAuthTokenRespParse.pStatusData);
|
|
|
|
|
|
|
|
if (getAuthTokenRespParse.pLifetimeData)
|
|
|
|
free(getAuthTokenRespParse.pLifetimeData);
|
2006-11-13 06:20:43 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateGetAuthTokenResp- 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))
|
|
|
|
{
|
|
|
|
*ppGetAuthTokenResp = pGetAuthTokenResp;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
free(pGetAuthTokenResp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateGetAuthTokenResp- Memory allocation error\n", 0);
|
|
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
}
|
|
|
|
DbgTrace(1, "-CreateGetAuthTokenResp- End, retStatus = %08X\n", retStatus);
|
|
|
|
|
|
|
|
return retStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
RelGetAuthTokenResp(
|
|
|
|
IN GetAuthTokenResp *pGetAuthTokenResp)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(1, "-RelGetAuthTokenResp- Start\n", 0);
|
|
|
|
|
|
|
|
// Free the resources associated with the object
|
|
|
|
if (pGetAuthTokenResp->pToken)
|
2007-01-04 11:18:40 +01:00
|
|
|
{
|
|
|
|
// Clear the memory associated with the token since it is
|
|
|
|
// sensitive data.
|
|
|
|
memset(pGetAuthTokenResp->pToken, 0, pGetAuthTokenResp->tokenLen);
|
2006-11-13 06:20:43 +01:00
|
|
|
free(pGetAuthTokenResp->pToken);
|
2007-01-04 11:18:40 +01:00
|
|
|
}
|
2006-11-13 06:20:43 +01:00
|
|
|
|
|
|
|
free(pGetAuthTokenResp);
|
|
|
|
|
|
|
|
DbgTrace(1, "-RelGetAuthTokenResp- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
//++=======================================================================
|
|
|
|
//++=======================================================================
|
|
|
|
|