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