CASA/CASA-auth-token/client/library/engine.c

1194 lines
43 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 ]==================================================
#define DEFAULT_RETRY_LIFETIME 5 // seconds
#define LOG_FILE_NAME "\\casaauthtoken.log"
//===[ Function prototypes ]===============================================
int
InitializeLibrary(void);
//===[ Global variables ]==================================================
//
// Debug tracing level and debug log file path.
//
int DebugLevel = 0;
char *g_pDebugLogFilePath = NULL;
//
// Operating parameter
//
bool g_bInitialized = false;
long g_rpcFlags = SECURE_RPC_FLAG | ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG;
char *g_pATSHostName = NULL;
uint16_t g_ATSPort = 2645;
//++=======================================================================
static
CasaStatus
ObtainSessionToken(
IN RpcSession *pRpcSession,
IN AuthPolicy *pAuthPolicy,
IN const char *pHostName,
IN void *pCredStoreScope,
INOUT char **ppSessionToken,
INOUT AuthContext **ppSessionTokenAuthContext)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
LIST_ENTRY *pListEntry;
AuthCacheEntry *pCacheEntry = NULL;
AuthContext *pAuthContext = NULL;
DbgTrace(1, "-ObtainSessionToken- Start\n", 0);
// Initialize output parameter
*ppSessionToken = NULL;
// Look in our cache for an entry that matches one of the auth
// contexts specified in the AuthPolicy object.
pListEntry = pAuthPolicy->authContextListHead.Flink;
while (pListEntry != &pAuthPolicy->authContextListHead)
{
// Get pointer to AuthContext structure
pAuthContext = CONTAINING_RECORD(pListEntry, AuthContext, listEntry);
// Try to find a cache entry for the auth context
pCacheEntry = FindSessionTokenEntryInCache(pAuthContext->pContext,
pCredStoreScope);
if (pCacheEntry != NULL)
{
// Cache entry found, check if it is of use to us.
if (CASA_SUCCESS(pCacheEntry->status))
{
// This entry can be used, stop looking.
retStatus = pCacheEntry->status;
break;
}
else
{
// Free the entry
FreeAuthCacheEntry(pCacheEntry);
}
}
// Advance to the next entry
pListEntry = pListEntry->Flink;
}
// If we did not find a cache entry that we can use, then try to create one.
pListEntry = pAuthPolicy->authContextListHead.Flink;
while (!CASA_SUCCESS(retStatus)
&& pListEntry != &pAuthPolicy->authContextListHead)
{
char *pAuthMechToken;
// Get pointer to AuthContext structure
pAuthContext = CONTAINING_RECORD(pListEntry, AuthContext, listEntry);
// Only try to create cache entry for the auth context if there is not
// one already.
pCacheEntry = FindSessionTokenEntryInCache(pAuthContext->pContext,
pCredStoreScope);
if (pCacheEntry == NULL)
{
char *pReqMsg = NULL;
char *pRespMsg = NULL;
size_t respLen;
// Get authentication mechanism token
retStatus = GetAuthMechToken(pAuthContext,
pHostName,
pCredStoreScope,
&pAuthMechToken);
if (!CASA_SUCCESS(retStatus))
{
// We were not able to obtain an authentication mechanism token
// for the context.
//
// Advance to the next entry
pListEntry = pListEntry->Flink;
continue;
}
// Authenticate to the ATS
pReqMsg = BuildAuthenticateMsg(pAuthContext, pAuthMechToken);
if (pReqMsg)
{
// Issue rpc
retStatus = Rpc(pRpcSession,
"Authenticate",
g_rpcFlags,
pReqMsg,
&pRespMsg,
&respLen);
if (CASA_SUCCESS(retStatus))
{
if (pRespMsg
&& respLen != 0)
{
AuthenticateResp *pAuthenticateResp;
// Create Authenticate response object
retStatus = CreateAuthenticateResp(pRespMsg, respLen, &pAuthenticateResp);
if (CASA_SUCCESS(retStatus))
{
// Return the auth token to the caller
pCacheEntry = CreateSessionTokenCacheEntry(pAuthContext->pContext,
retStatus,
pAuthenticateResp->pToken,
pAuthenticateResp->tokenLifetime,
pCredStoreScope);
pAuthenticateResp->pToken = NULL; // To keep us from freeing the buffer
// Free the Authenticate response object
RelAuthenticateResp(pAuthenticateResp);
}
}
else
{
DbgTrace(0, "-ObtainSessionToken- Did not receive Authenticate Response data\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_SERVER_ERROR);
}
}
else
{
DbgTrace(0, "-ObtainSessionToken- Authenticate Rpc failure, error = %08X\n", retStatus);
}
// Free resources that may be hanging around
if (pRespMsg)
{
// Clear and free the memory associated with the response since it may contain
// security sensitive data.
memset(pRespMsg, 0, respLen);
free(pRespMsg);
}
// Clear and free the memory associated with the request message since
// it may contain security sensitive information.
memset(pReqMsg, 0, strlen(pReqMsg));
free(pReqMsg);
}
else
{
DbgTrace(0, "-ObtainSessionToken- Error building Authenticate msg\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
// Add the entry to the cache if the reason that we failed was because
// the server was unavailable.
if (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE)
{
pCacheEntry = CreateSessionTokenCacheEntry(pAuthContext->pContext,
retStatus,
NULL,
DEFAULT_RETRY_LIFETIME,
pCredStoreScope);
}
// Release the cache entry if the resulting status is not successful
if (pCacheEntry)
{
if (!CASA_SUCCESS(retStatus))
{
FreeAuthCacheEntry(pCacheEntry);
}
}
// Free up the buffer associated with the authentication mechanism token
// after clearing it since it may contain sensitive information.
memset(pAuthMechToken, 0, strlen(pAuthMechToken));
free(pAuthMechToken);
}
else
{
// Free the entry
FreeAuthCacheEntry(pCacheEntry);
}
// Advance to the next entry
pListEntry = pListEntry->Flink;
}
// Return session token if successful
if (CASA_SUCCESS(retStatus))
{
// Allocate a buffer for the return token
*ppSessionToken = (char*) malloc(strlen(pCacheEntry->token) + 1);
if (*ppSessionToken)
{
// Copy the token onto the allocated buffer
strcpy(*ppSessionToken, pCacheEntry->token);
// Return pointer to AuthContext associated with the session token
*ppSessionTokenAuthContext = pAuthContext;
}
else
{
DbgTrace(0, "-ObtainSessionToken- Buffer allocation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
FreeAuthCacheEntry(pCacheEntry);
}
DbgTrace(1, "-ObtainSessionToken- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
static
CasaStatus
ObtainAuthTokenFromServer(
IN const char *pServiceName,
IN const char *pHostName,
IN const char *pNormalizedHostName,
2007-04-03 00:16:07 +02:00
IN const void *pCredStoreScope,
INOUT char **ppAuthToken,
INOUT int *pTokenLifetime,
2007-04-03 00:16:07 +02:00
INOUT bool *pAdvisedToRetry)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
CasaStatus retStatus = CASA_STATUS_SUCCESS;
RpcSession *pRpcSession;
DbgTrace(1, "-ObtainAuthTokenFromServer- Start\n", 0);
2007-04-03 00:16:07 +02:00
// Initialize output parameters
*ppAuthToken = NULL;
2007-04-03 00:16:07 +02:00
*pAdvisedToRetry = false;
// Open Rpc Session to the auth service at the specified host
pRpcSession = OpenRpcSession((g_pATSHostName != NULL) ? g_pATSHostName : pHostName,
g_ATSPort);
if (pRpcSession)
{
char *pReqMsg = NULL;
char *pRespMsg = NULL;
size_t respLen;
AuthPolicy *pAuthPolicy = NULL;
GetAuthPolicyResp *pGetAuthPolicyResp = NULL;
GetAuthTokenResp *pGetAuthTokenResp = NULL;
char *pSessionToken = NULL;
// Request the auth parameters associated with this service
pReqMsg = BuildGetAuthPolicyMsg(pServiceName, "localhost"); // tbd - This will be changed in the future so that we can support services residing in a different host than the ATS
if (pReqMsg)
{
// Issue rpc
retStatus = Rpc(pRpcSession,
"GetAuthPolicy",
g_rpcFlags,
pReqMsg,
&pRespMsg,
&respLen);
if (CASA_SUCCESS(retStatus))
{
if (pRespMsg
&& respLen != 0)
{
// Create GetAuthPolicy response object
retStatus = CreateGetAuthPolicyResp(pRespMsg, respLen, &pGetAuthPolicyResp);
if (CASA_SUCCESS(retStatus))
{
// Create the AuthPolicy object
retStatus = CreateAuthPolicy(pGetAuthPolicyResp->pPolicy,
pGetAuthPolicyResp->policyLen,
&pAuthPolicy);
if (CASA_SUCCESS(retStatus))
{
AuthContext *pSessionTokenAuthContext = NULL;
// Now try to obtain a session token
retStatus = ObtainSessionToken(pRpcSession,
pAuthPolicy,
(g_pATSHostName != NULL) ? g_pATSHostName : pHostName,
pCredStoreScope,
&pSessionToken,
&pSessionTokenAuthContext);
if (CASA_SUCCESS(retStatus))
{
// Request auth token for the service
free(pReqMsg);
pReqMsg = BuildGetAuthTokenMsg(pServiceName, "localhost", pSessionToken); // tbd - This will be changed in the future so that we can support services residing in a different host than the ATS
if (pReqMsg)
{
// Free the previous response msg buffer
free(pRespMsg);
pRespMsg = NULL;
// Issue rpc
retStatus = Rpc(pRpcSession,
"GetAuthToken",
g_rpcFlags,
pReqMsg,
&pRespMsg,
&respLen);
if (CASA_SUCCESS(retStatus))
{
if (pRespMsg
&& respLen != 0)
{
// Create GetAuthPolicy response object
retStatus = CreateGetAuthTokenResp(pRespMsg, respLen, &pGetAuthTokenResp);
if (CASA_SUCCESS(retStatus))
{
// Return the auth token to the caller
*ppAuthToken = pGetAuthTokenResp->pToken;
pGetAuthTokenResp->pToken = NULL; // To keep us from freeing the buffer
*pTokenLifetime = pGetAuthTokenResp->tokenLifetime;
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- Failed to create GetAuthTokenResp object, error = %08X\n", retStatus);
// Remove the session token from the cache in case that it was due to a bad session token
if (pSessionTokenAuthContext)
{
RemoveSessionTokenEntryInCache(pSessionTokenAuthContext->pContext,
pCredStoreScope);
2007-04-03 00:16:07 +02:00
// Advice that a retry should be attempted
*pAdvisedToRetry = true;
}
}
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- Did not receive GetAuthToken Response data\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_SERVER_ERROR);
}
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- GetAuthToken Rpc failure, error = %08X\n", retStatus);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_SERVER_ERROR);
}
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- Error building GetAuthToken msg\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- Failed to obtain session token, error = %08X\n", retStatus);
}
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- Failed to create AuthPolicy object, error = %08X\n", retStatus);
}
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- Failed to create GetAuthPolicyResp object, error = %08X\n", retStatus);
}
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- Did not receive GetAuthPolicy Response data\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_SERVER_ERROR);
}
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- GetAuthPolicy Rpc failure, error = %08X\n", retStatus);
}
// Free resources that may be hanging around
if (pReqMsg)
{
// Clear the memory before freeing up the request message since it
// may contain security sensitive data.
memset(pReqMsg, 0, strlen(pReqMsg));
free(pReqMsg);
}
if (pRespMsg)
{
// Clear the memory before freeing up the response message since it
// may contain security sensitive data.
memset(pRespMsg, 0, respLen);
free(pRespMsg);
}
if (pSessionToken)
{
// Clear the memory before freeing up the token since it is
// security sensitive data.
memset(pSessionToken, 0, strlen(pSessionToken));
free(pSessionToken);
}
if (pGetAuthTokenResp)
RelGetAuthTokenResp(pGetAuthTokenResp);
if (pGetAuthPolicyResp)
RelGetAuthPolicyResp(pGetAuthPolicyResp);
if (pAuthPolicy)
RelAuthPolicy(pAuthPolicy);
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- Error building GetAuthPolicy msg\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
// Close the Rpc Session
CloseRpcSession(pRpcSession);
}
else
{
DbgTrace(0, "-ObtainAuthTokenFromServer- Error opening Rpc session\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
DbgTrace(1, "-ObtainAuthTokenFromServer- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
CasaStatus
ObtainAuthTokenInt(
IN const char *pServiceName,
IN const char *pHostName,
2007-04-03 00:16:07 +02:00
IN const void *pCredStoreScope,
INOUT char *pAuthTokenBuf,
2007-04-03 00:16:07 +02:00
INOUT int *pAuthTokenBufLen)
//
// Arguments:
// pServiceName -
// Pointer to NULL terminated string that contains the
// name of the service to which the client is trying to
// authenticate.
//
// pHostName -
// Pointer to NULL terminated string that contains the
// name of the host where resides the service to which the
// client is trying to authenticate. Note that the name
// can either be a DNS name or a dotted IP address.
//
2007-04-03 00:16:07 +02:00
// pCredStoreScope -
// Pointer to CASA structure for scoping credential store access
// to specific users. This can only be leveraged by applications
// running in the context of System.
//
// pAuthTokenBuf -
// Pointer to buffer that will receive the authentication
// token. The length of this buffer is specified by the
// pAuthTokenBufLen parameter. Note that the the authentication
// token will be in the form of a NULL terminated string.
//
// pAuthTokenBufLen -
// Pointer to integer that contains the length of the
// buffer pointed at by pAuthTokenBuf. Upon return of the
// function, the integer will contain the actual length
// of the authentication token if the function successfully
// completes or the buffer length required if the function
// fails because the buffer pointed at by pAuthTokenBuf is
// not large enough.
2007-04-03 00:16:07 +02:00
//
// Returns:
// Casa Status
//
// Description:
// Get authentication token to authenticate user to specified
// service at host. The user is scoped using the info associated
// with the magic cookie.
//
// L2
//=======================================================================--
{
CasaStatus retStatus = CASA_STATUS_SUCCESS;
AuthCacheEntry *pCacheEntry;
char *pNormalizedHostName;
char *pToken;
HANDLE hUserMutex = NULL;
DbgTrace(1, "-ObtainAuthTokenInt- Start\n", 0);
// Verify the input parameters
if (pServiceName == NULL
|| pHostName == NULL
|| pAuthTokenBufLen == NULL
|| (*pAuthTokenBufLen != 0 && pAuthTokenBuf == NULL))
{
DbgTrace(0, "-ObtainAuthTokenInt- Invalid parameter\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INVALID_PARAMETER);
goto exit;
}
DbgTrace(1, "-ObtainAuthTokenInt- ServiceName = %s\n", pServiceName);
DbgTrace(1, "-ObtainAuthTokenInt- HostName = %s\n", pHostName);
DbgTrace(1, "-ObtainAuthTokenInt- BufferLength = %d\n", *pAuthTokenBufLen);
// Obtain our synchronization mutex
AcquireModuleMutex;
// Create user synchronization mutex
retStatus = CreateUserMutex(&hUserMutex);
if (retStatus != CASA_STATUS_SUCCESS)
{
DbgTrace(0, "-ObtainAuthTokenInt- Error creating mutex for the user\n", 0);
goto exit;
}
// Make sure we are fully initialized
if (g_bInitialized == false)
{
retStatus = InitializeLibrary();
if (retStatus == CASA_STATUS_SUCCESS)
{
g_bInitialized = true;
}
else
{
goto exit;
}
}
// Release our synchronization mutex
ReleaseModuleMutex;
// Normalize the host name
pNormalizedHostName = NormalizeHostName(pHostName);
if (pNormalizedHostName)
{
// Start user process synchronization
AcquireUserMutex(hUserMutex);
// Try to find a cache entry for the service
pCacheEntry = FindAuthTokenEntryInCache(pServiceName,
pNormalizedHostName,
pCredStoreScope);
if (pCacheEntry == NULL)
{
// Initialize to retry in case of failure
int cacheEntryLifetime = DEFAULT_RETRY_LIFETIME;
2007-04-03 00:16:07 +02:00
bool advisedToRetry;
// Cache entry created, now try to obtain auth token from the CASA Server
pToken = NULL;
retStatus = ObtainAuthTokenFromServer(pServiceName,
pHostName,
pNormalizedHostName,
2007-04-03 00:16:07 +02:00
pCredStoreScope,
&pToken,
&cacheEntryLifetime,
2007-04-03 00:16:07 +02:00
&advisedToRetry);
// Retry if not successful and if advised to do so
if (!CASA_SUCCESS(retStatus)
&& advisedToRetry)
{
retStatus = ObtainAuthTokenFromServer(pServiceName,
pHostName,
pNormalizedHostName,
pCredStoreScope,
&pToken,
&cacheEntryLifetime,
&advisedToRetry);
}
// Add the entry to the cache if successful or if the reason that we failed
// was because the server was un-available.
if (CASA_SUCCESS(retStatus)
|| CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE)
{
pCacheEntry = CreateAuthTokenCacheEntry(pServiceName,
pNormalizedHostName,
retStatus,
pToken,
cacheEntryLifetime,
pCredStoreScope);
if (pCacheEntry)
{
// Release the cache entry if the resulting status is not successful
if (!CASA_SUCCESS(retStatus))
{
FreeAuthCacheEntry(pCacheEntry);
}
}
}
// Release authentication token if present
if (pToken)
{
// Clear the memory before releasing the buffer since it contains
// security sensitive data.
memset(pToken, 0, strlen(pToken));
free(pToken);
}
}
else
{
// Cache entry found, update the return status with the information saved in it
// and release it if its status is not successful.
if (!CASA_SUCCESS(retStatus = pCacheEntry->status))
{
FreeAuthCacheEntry(pCacheEntry);
}
}
// Try to return auth token if we have one to return
if (CASA_SUCCESS(retStatus))
{
int tokenLen = (int) strlen(pCacheEntry->token) + 1;
// We have an authentication token, try to return it to the caller
// after verifying that the supplied buffer is big enough.
if (*pAuthTokenBufLen >= tokenLen)
{
// Return the auth token to the caller
DbgTrace(2, "-ObtainAuthTokenInt- Copying the token into the callers buffer\n", 0);
strcpy(pAuthTokenBuf, pCacheEntry->token);
}
else
{
if (*pAuthTokenBufLen != 0)
{
DbgTrace(0, "-ObtainAuthTokenInt- The supplied buffer is not large enough", 0);
}
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_BUFFER_OVERFLOW);
}
// Return the token length to the caller
*pAuthTokenBufLen = tokenLen;
FreeAuthCacheEntry(pCacheEntry);
}
// Stop user process synchronization
ReleaseUserMutex(hUserMutex);
// Free the space allocated for the normalized host name
free(pNormalizedHostName);
}
else
{
DbgTrace(0, "-ObtainAuthTokenInt- Host name normalization failed\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_NAME_RESOLVE_ERROR);
}
exit:
if (hUserMutex != NULL)
{
DestroyUserMutex(hUserMutex);
}
DbgTrace(1, "-ObtainAuthTokenInt- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
CasaStatus SSCS_CALL
ObtainAuthToken(
IN const char *pServiceName,
IN const char *pHostName,
INOUT char *pAuthTokenBuf,
INOUT int *pAuthTokenBufLen)
//
// Arguments:
// pServiceName -
// Pointer to NULL terminated string that contains the
// name of the service to which the client is trying to
// authenticate.
//
// pHostName -
// Pointer to NULL terminated string that contains the
// name of the host where resides the service to which the
// client is trying to authenticate. Note that the name
// can either be a DNS name or a dotted IP address.
//
// pAuthTokenBuf -
// Pointer to buffer that will receive the authentication
// token. The length of this buffer is specified by the
// pAuthTokenBufLen parameter. Note that the the authentication
// token will be in the form of a NULL terminated string.
//
// pAuthTokenBufLen -
// Pointer to integer that contains the length of the
// buffer pointed at by pAuthTokenBuf. Upon return of the
// function, the integer will contain the actual length
// of the authentication token if the function successfully
// completes or the buffer length required if the function
// fails because the buffer pointed at by pAuthTokenBuf is
// not large enough.
//
// Returns:
// Casa Status
//
// Description:
// Get authentication token to authenticate user to specified
// service at host.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
DbgTrace(1, "-ObtainAuthToken- Start\n", 0);
// Call our internal worker
retStatus = ObtainAuthTokenInt(pServiceName,
pHostName,
2007-04-03 00:16:07 +02:00
NULL,
pAuthTokenBuf,
2007-04-03 00:16:07 +02:00
pAuthTokenBufLen);
DbgTrace(1, "-ObtainAuthToken- End, retStatus = %08X\n", retStatus);
return retStatus;
}
2007-04-13 21:21:40 +02:00
//++=======================================================================
void
CleanUpAuthTokenCacheInt(
IN const void *pCredStoreScope)
//
// Arguments:
// pCredStoreScope -
// Pointer to CASA structure for scoping credential store access
// to specific users. This can only be leveraged by applications
// running in the context of System.
//
// Returns:
// Nothing
//
// Description:
// Flush the AuthToken cache.
//=======================================================================--
{
CasaStatus retStatus;
HANDLE hUserMutex = NULL;
DbgTrace(1, "-CleanUpAuthTokenCacheInt- Start\n", 0);
// Obtain our synchronization mutex
AcquireModuleMutex;
// Create user synchronization mutex
retStatus = CreateUserMutex(&hUserMutex);
if (retStatus != CASA_STATUS_SUCCESS)
{
DbgTrace(0, "-CleanUpAuthTokenCacheInt- Error creating mutex for the user\n", 0);
goto exit;
}
// Make sure we are fully initialized
if (g_bInitialized == false)
{
retStatus = InitializeLibrary();
if (retStatus == CASA_STATUS_SUCCESS)
{
g_bInitialized = true;
}
else
{
goto exit;
}
}
// Release our synchronization mutex
ReleaseModuleMutex;
// Start user process synchronization
AcquireUserMutex(hUserMutex);
// Delete all of the tokens in our cache
DeleteAuthTokenEntriesInCache(pCredStoreScope);
DeleteSessionTokenEntriesInCache(pCredStoreScope);
// Stop user process synchronization
ReleaseUserMutex(hUserMutex);
exit:
if (hUserMutex != NULL)
{
DestroyUserMutex(hUserMutex);
}
DbgTrace(1, "-CleanUpAuthTokenCacheInt- End\n", 0);
}
//++=======================================================================
void SSCS_CALL
CleanUpAuthTokenCache(void)
//
// Arguments: None.
//
// Returns:
// Nothing
//
// Description:
// Flush the AuthToken cache.
//=======================================================================--
{
DbgTrace(1, "-CleanUpAuthTokenCache- Start\n", 0);
// Call our internal worker
CleanUpAuthTokenCacheInt(NULL);
DbgTrace(1, "-CleanUpAuthTokenCache- End\n", 0);
}
//++=======================================================================
int
InitializeLibrary(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
int retStatus = -1;
int getConfigStatus = -1;
ConfigIf *pClientConfigIf;
char *pDebugLevelSetting;
char *pDebugLogFolderPathSetting;
char *pATSPortSetting;
char *pATSHostNameSetting;
char *pDisableSecureConnections;
char *pAllowInvalidCerts;
char *pUsersCannotAllowInvalidCerts;
DbgTrace(1, "-InitializeLibrary- Start\n", 0);
// Try to obtain client configuration settings
getConfigStatus = GetConfigInterface(clientConfigFolder,
"client",
&pClientConfigIf);
if (CASA_SUCCESS(getConfigStatus)
&& CasaStatusCode(getConfigStatus) != CASA_STATUS_OBJECT_NOT_FOUND)
{
// Check if a DebugLevel has been configured
pDebugLevelSetting = pClientConfigIf->getEntryValue(pClientConfigIf, "DebugLevel");
if (pDebugLevelSetting != NULL)
{
DbgTrace(0, "-InitializeLibrary- DebugLevel configured = %s\n", pDebugLevelSetting);
// Convert the number to hex
DebugLevel = (int) dtoul(pDebugLevelSetting, strlen(pDebugLevelSetting));
// Free the buffer holding the debug level
pClientConfigIf->freeValueString(pClientConfigIf, pDebugLevelSetting);
}
// Check if a DebugLogFolderPath has been configured
pDebugLogFolderPathSetting = pClientConfigIf->getEntryValue(pClientConfigIf, "DebugLogFolderPath");
if (pDebugLogFolderPathSetting != NULL)
{
DbgTrace(0, "-InitializeLibrary- DebugLogFolderPath configured = %s\n", pDebugLogFolderPathSetting);
// Use the setting to come up with the path to the debug log file
g_pDebugLogFilePath = malloc(strlen(LOG_FILE_NAME) + strlen(pDebugLogFolderPathSetting) + 1);
if (g_pDebugLogFilePath)
{
strcpy(g_pDebugLogFilePath, pDebugLogFolderPathSetting);
strcat(g_pDebugLogFilePath, LOG_FILE_NAME);
}
else
{
DbgTrace(0, "-InitializeLibrary- Failed to allocate buffer for debug file path\n", 0);
}
// Free the buffer holding the debug folder path
pClientConfigIf->freeValueString(pClientConfigIf, pDebugLogFolderPathSetting);
}
// Check if an ATS hostname has been configured
pATSHostNameSetting = pClientConfigIf->getEntryValue(pClientConfigIf, "ATS-hostname");
if (pATSHostNameSetting != NULL)
{
DbgTrace(0, "-InitializeLibrary- ATS hostname configured = %s\n", pATSHostNameSetting);
// Remember the ATS host name
g_pATSHostName = malloc(strlen(pATSHostNameSetting) + 1);
if (g_pATSHostName)
{
strcpy(g_pATSHostName, pATSHostNameSetting);
}
else
{
DbgTrace(0, "-InitializeLibrary- Failed to allocate buffer for ATS host name\n", 0);
}
// Free the buffer holding the ats host name setting
pClientConfigIf->freeValueString(pClientConfigIf, pATSHostNameSetting);
}
// Check if the DisableSecureConnections setting has been configured
pDisableSecureConnections = pClientConfigIf->getEntryValue(pClientConfigIf, "DisableSecureConnections");
if (pDisableSecureConnections != NULL)
{
DbgTrace(0, "-InitializeLibrary- DisableSecureConnections setting configured = %s\n", pDisableSecureConnections);
// Adjust the g_rpcFlags variable based on the setting
2007-04-03 00:16:07 +02:00
if (_stricmp(pDisableSecureConnections, "true") == 0)
{
g_rpcFlags &= ~SECURE_RPC_FLAG;
}
2007-04-03 00:16:07 +02:00
else if (_stricmp(pDisableSecureConnections, "false") == 0)
{
g_rpcFlags |= SECURE_RPC_FLAG;
}
// Free the buffer holding the DisableSecureConnections setting
pClientConfigIf->freeValueString(pClientConfigIf, pDisableSecureConnections);
}
// Check the AllowUntrustedCerts setting if using secure connections
if (g_rpcFlags & SECURE_RPC_FLAG)
{
// Check if the AllowUntrustedCerts setting has been configured
pAllowInvalidCerts = pClientConfigIf->getEntryValue(pClientConfigIf, "AllowUntrustedCerts");
if (pAllowInvalidCerts != NULL)
{
DbgTrace(0, "-InitializeLibrary- AllowUntrustedCerts setting configured = %s\n", pAllowInvalidCerts);
// Adjust the g_rpcFlags variable based on the setting
if (stricmp(pAllowInvalidCerts, "false") == 0)
{
g_rpcFlags &= ~ALLOW_INVALID_CERTS_RPC_FLAG;
}
else if (stricmp(pAllowInvalidCerts, "true") == 0)
{
g_rpcFlags |= ALLOW_INVALID_CERTS_RPC_FLAG;
}
// Free the buffer holding the AllowInvalidCerts setting
pClientConfigIf->freeValueString(pClientConfigIf, pAllowInvalidCerts);
}
// Check the UsersCannotAllowInvalidCerts setting if not allowing invalid certs.
if ((g_rpcFlags & ALLOW_INVALID_CERTS_RPC_FLAG) == 0)
{
// Check if the UsersCannotAllowInvalidCerts setting has been configured
pUsersCannotAllowInvalidCerts = pClientConfigIf->getEntryValue(pClientConfigIf, "UsersCannotAllowInvalidCerts");
if (pUsersCannotAllowInvalidCerts != NULL)
{
DbgTrace(0, "-InitializeLibrary- UsersCannotAllowInvalidCerts setting configured = %s\n", pUsersCannotAllowInvalidCerts);
// Adjust the g_rpcFlags variable based on the setting
if (stricmp(pUsersCannotAllowInvalidCerts, "false") == 0)
{
g_rpcFlags |= ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG;
}
else if (stricmp(pUsersCannotAllowInvalidCerts, "true") == 0)
{
g_rpcFlags &= ~ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG;
}
// Free the buffer holding the UsersCannotAllowInvalidCerts setting
pClientConfigIf->freeValueString(pClientConfigIf, pUsersCannotAllowInvalidCerts);
}
}
}
// Check if an ATS port number has been configured
pATSPortSetting = pClientConfigIf->getEntryValue(pClientConfigIf, "ATS-port");
if (pATSPortSetting != NULL)
{
DbgTrace(0, "-InitializeLibrary- ATS port number configured = %s\n", pATSPortSetting);
// Convert the number to hex
g_ATSPort = (int) dtoul(pATSPortSetting, strlen(pATSPortSetting));
// Free the buffer holding the port number
pClientConfigIf->freeValueString(pClientConfigIf, pATSPortSetting);
}
// Release config interface instance
pClientConfigIf->releaseReference(pClientConfigIf);
}
// Initialize the host name normalization
retStatus = InitializeHostNameNormalization();
if (CASA_SUCCESS(retStatus))
{
// Normalize ATS host name if configured
if (g_pATSHostName)
{
char *pNormalizedHostName = NormalizeHostName(g_pATSHostName);
if (pNormalizedHostName)
{
// Use this name instead of the one that we already have
free(g_pATSHostName);
g_pATSHostName = pNormalizedHostName;
}
else
{
DbgTrace(0, "-InitializeLibrary- ATS Hostname normalization failed\n", 0);
}
}
// Initialize the auth cache
retStatus = InitializeAuthCache();
if (CASA_SUCCESS(retStatus))
{
retStatus = InitializeRpc();
}
else
{
DbgTrace(0, "-InitializeLibrary- Auth cache intialization failed\n", 0);
}
}
else
{
DbgTrace(0, "-InitializeLibrary- HostName Normalizer intialization failed\n", 0);
}
DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
void
UnInitializeLibrary(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
DbgTrace(1, "-UnInitializeLibrary- Start\n", 0);
// Un-initialize the host name normalization
UnInitializeHostNameNormalization();
// Un-initialize the auth cache
UnInitializeAuthCache();
// Un-initialize the Rpc engine
UnInitializeRpc();
// Free necessary buffers
if (g_pDebugLogFilePath)
{
char *pBuffer = g_pDebugLogFilePath;
g_pDebugLogFilePath = NULL;
free(pBuffer);
}
if (g_pATSHostName)
free(g_pATSHostName);
DbgTrace(1, "-UnInitializeLibrary- End\n", 0);
}
//++=======================================================================
//++=======================================================================
//++=======================================================================