CASA/CASA-auth-token/server/AuthTokenValidate/idenTokenProviders/casa/identokenprovider.c

348 lines
10 KiB
C
Raw Normal View History

/***********************************************************************
*
* 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 ]==================================================
//
// Identity Token Provider Interface instance data
//
typedef struct _IdenTokenProviderIfInstance
{
int refCount;
IdenTokenProviderIf idenTokenProviderIf;
} IdenTokenProviderIfInstance, *PIdenTokenProviderIfInstance;
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
// IdenTokenProviderIf variables
static
int g_numIdenTokenProviderIfObjs = 0;
// Debug Level
int DebugLevel = 0;
//
// Initialization variables
//
static
bool g_moduleInitialized = false;
// Synchronization mutex
static
HANDLE g_idenTokenProviderIfMutex = NULL;
//++=======================================================================
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;
IdenTokenProviderIfInstance *pIdenTokenProviderIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenProviderIfInstance, idenTokenProviderIf);
DbgTrace(2, "-AddReference- Start\n", 0);
// Increment the reference count on the object
PlatAcquireMutex(g_idenTokenProviderIfMutex);
pIdenTokenProviderIfInstance->refCount ++;
refCount = pIdenTokenProviderIfInstance->refCount;
PlatReleaseMutex(g_idenTokenProviderIfMutex);
DbgTrace(2, "-AddReference- End, refCount = %0X\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;
IdenTokenProviderIfInstance *pIdenTokenProviderIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenProviderIfInstance, idenTokenProviderIf);
DbgTrace(2, "-ReleaseReference- Start\n", 0);
// Decrement the reference count on the object and determine if it needs to
// be released.
PlatAcquireMutex(g_idenTokenProviderIfMutex);
pIdenTokenProviderIfInstance->refCount --;
if (pIdenTokenProviderIfInstance->refCount == 0)
{
// The object needs to be released, forget about it.
freeObj = true;
g_numIdenTokenProviderIfObjs --;
}
PlatReleaseMutex(g_idenTokenProviderIfMutex);
// Free object if necessary
if (freeObj)
free(pIdenTokenProviderIfInstance);
DbgTrace(2, "-ReleaseReference- End\n", 0);
}
//++=======================================================================
static
CasaStatus
GetIdentityTokenIf(
IN const void *pIfInstance,
IN const char *pTokenBuf,
IN const size_t tokenLen,
INOUT IdenTokenIf **ppIdenTokenIf)
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pTokenBuf -
// Pointer to null terminated string containing an identity token.
//
// tokenLen -
// Length of the token contained in the token buffer.
//
// ppIdenTokenIf -
// Pointer to variable that will receive pointer to identity
// token interface.
//
// Returns:
// Casa Status
//
// Description:
// Get identity token interface instance for the specified token.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
char *pDecodedTokenBuf;
uint32_t decodedTokenBufLen;
DbgTrace(2, "-GetIdentityTokenIf- Start\n", 0);
// Validate input parameters
if (pIfInstance == NULL
|| pTokenBuf == NULL
|| tokenLen > UINT32_MAX
|| tokenLen == 0
|| ppIdenTokenIf == NULL)
{
DbgTrace(0, "-GetIdentityTokenIf- Invalid input parameter\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INVALID_PARAMETER);
goto exit;
}
// First decode the token string
retStatus = DecodeData(pTokenBuf,
tokenLen,
(void**) &pDecodedTokenBuf,
&decodedTokenBufLen);
if (CASA_SUCCESS(retStatus))
{
// Get the identity token interface
retStatus = GetIdenTokenInterface(pDecodedTokenBuf,
decodedTokenBufLen,
ppIdenTokenIf);
// Free the decoded token buffer
free(pDecodedTokenBuf);
}
else
{
DbgTrace(0, "-GetIdentityTokenIf- Token decode failure\n", 0);
}
exit:
DbgTrace(2, "-GetIdentityTokenIf- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
CasaStatus SSCS_CALL
GET_IDEN_TOKEN_PROVIDER_INTERFACE_RTN(
IN const ConfigIf *pModuleConfigIf,
INOUT IdenTokenProviderIf **ppIdenTokenProviderIf)
//
// Arguments:
// pModuleConfigIf -
// Pointer to configuration interface instance for the module.
//
// ppIdenTokenProviderIf -
// Pointer to variable that will receive pointer to
// IdentityTokenProviderIf instance.
//
// Returns:
// Casa Status
//
// Description:
// Gets identity token provider interface instance.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
IdenTokenProviderIfInstance *pIdenTokenProviderIfInstance;
DbgTrace(1, "-GetIdenTokenProviderInterface- Start\n", 0);
// Validate input parameters
if (pModuleConfigIf == NULL
|| ppIdenTokenProviderIf == NULL)
{
DbgTrace(0, "-GetIdenTokenProviderInterface- Invalid input parameter\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_INVALID_PARAMETER);
goto exit;
}
// Make sure that the module has been initialized
if (g_moduleInitialized == false)
{
// The module has not been initialized, synchronize access thought this section
// to avoid having two threads performing initialization.
AcquireModuleMutex;
// Assume success
retStatus = CASA_STATUS_SUCCESS;
// Check again in case another thread pre-empted us.
if (g_moduleInitialized == false)
{
// Initialize the IdenTokenIf complex
retStatus = IdenTokenIfInit();
if (CASA_SUCCESS(retStatus))
{
// Allocate mutex
if ((g_idenTokenProviderIfMutex = PlatAllocMutex()) != NULL)
{
// Success
g_moduleInitialized = true;
}
else
{
IdenTokenIfUninit();
retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
}
}
// Stop synchronization
ReleaseModuleMutex;
// Exit if we failed
if (g_moduleInitialized == false)
goto exit;
}
// Allocate space for the interface instance
pIdenTokenProviderIfInstance = malloc(sizeof(*pIdenTokenProviderIfInstance));
if (pIdenTokenProviderIfInstance)
{
// Initialize the interface instance data
pIdenTokenProviderIfInstance->refCount = 1;
pIdenTokenProviderIfInstance->idenTokenProviderIf.addReference = AddReference;
pIdenTokenProviderIfInstance->idenTokenProviderIf.releaseReference = ReleaseReference;
pIdenTokenProviderIfInstance->idenTokenProviderIf.getIdentityTokenIf = GetIdentityTokenIf;
// Keep track of this object
PlatAcquireMutex(g_idenTokenProviderIfMutex);
g_numIdenTokenProviderIfObjs ++;
PlatReleaseMutex(g_idenTokenProviderIfMutex);
// Return the interface to the caller
*ppIdenTokenProviderIf = &pIdenTokenProviderIfInstance->idenTokenProviderIf;
// Success
retStatus = CASA_STATUS_SUCCESS;
}
else
{
DbgTrace(0, "-GetIdenTokenProviderInterface- Buffer allocation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
exit:
DbgTrace(1, "-GetIdenTokenProviderInterface- End, retStatus = %0X\n", retStatus);
return retStatus;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================