b9fa3eab0c
1. Provided SetATSHostList() API for changing the ATS address dynamically 2. Not using CASA enabled server as ATS. ATS address has to be explicitly set in client.conf or through SetATSHostList() 3. Not normalizing CASA enabled server's host name while obtaining CASA tokens. Callers of ObtainAuthTokenEx() have to pass normalized name as argument
1409 lines
49 KiB
C
1409 lines
49 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 ]==================================================
|
|
|
|
#define DEFAULT_RETRY_LIFETIME 300 // seconds
|
|
|
|
#define BAD_CACHE_TRIGER_TIME 30 // seconds
|
|
|
|
#define DEFAULT_ATS_PORT 2645
|
|
|
|
#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;
|
|
LIST_ENTRY g_ATSHostList;
|
|
|
|
|
|
//++=======================================================================
|
|
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,
|
|
IN const ATSHostEntry *pATSHost,
|
|
IN const void *pCredStoreScope,
|
|
INOUT char **ppAuthToken,
|
|
INOUT int *pTokenLifetime,
|
|
INOUT bool *pAdvisedToRetry)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
|
RpcSession *pRpcSession;
|
|
|
|
DbgTrace(1, "-ObtainAuthTokenFromServer- Start\n", 0);
|
|
|
|
// Initialize output parameters
|
|
*ppAuthToken = NULL;
|
|
*pAdvisedToRetry = false;
|
|
|
|
// Open Rpc Session to the auth service at the specified host
|
|
DbgTrace(3, "-ObtainAuthTokenFromServer- Hostname = %s\n", pATSHost->pName);
|
|
DbgTrace(3, "-ObtainAuthTokenFromServer- port = %d\n", pATSHost->port);
|
|
pRpcSession = OpenRpcSession(pATSHost->pName,
|
|
pATSHost->port);
|
|
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
|
|
if (strcmp(pHostName, pATSHost->pName) == 0
|
|
|| strcmp(pNormalizedHostName, pATSHost->pName) == 0)
|
|
{
|
|
pReqMsg = BuildGetAuthPolicyMsg(pServiceName, "localhost");
|
|
}
|
|
else
|
|
{
|
|
pReqMsg = BuildGetAuthPolicyMsg(pServiceName, pNormalizedHostName);
|
|
}
|
|
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,
|
|
(const char*) pATSHost->pName,
|
|
pCredStoreScope,
|
|
&pSessionToken,
|
|
&pSessionTokenAuthContext);
|
|
if (CASA_SUCCESS(retStatus))
|
|
{
|
|
free(pReqMsg);
|
|
|
|
// Request auth token for the service
|
|
if (strcmp(pHostName, pATSHost->pName) == 0
|
|
|| strcmp(pNormalizedHostName, pATSHost->pName) == 0)
|
|
{
|
|
pReqMsg = BuildGetAuthTokenMsg(pServiceName, "localhost", pSessionToken);
|
|
}
|
|
else
|
|
{
|
|
pReqMsg = BuildGetAuthTokenMsg(pServiceName, pNormalizedHostName, pSessionToken);
|
|
}
|
|
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);
|
|
|
|
// 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,
|
|
IN const void *pCredStoreScope,
|
|
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.
|
|
//
|
|
// 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.
|
|
//
|
|
// 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 *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;
|
|
|
|
{
|
|
LIST_ENTRY *pListEntry;
|
|
ATSHostEntry *pHostEntryInUse;
|
|
|
|
// Start user process synchronization
|
|
AcquireUserMutex(hUserMutex);
|
|
|
|
// Now try to obtain an authentication token using the
|
|
// host entries at our disposal.
|
|
pListEntry = g_ATSHostList.Flink;
|
|
while(pListEntry != &g_ATSHostList)
|
|
{
|
|
// Get pointer to the host entry
|
|
pHostEntryInUse = CONTAINING_RECORD(pListEntry, ATSHostEntry, listEntry);
|
|
|
|
// Try to find a cache entry for the service
|
|
pCacheEntry = FindAuthTokenEntryInCache(pServiceName,
|
|
pHostName,
|
|
pHostEntryInUse,
|
|
pCredStoreScope);
|
|
if (pCacheEntry == NULL)
|
|
{
|
|
// Initialize to retry in case of failure
|
|
int cacheEntryLifetime = DEFAULT_RETRY_LIFETIME;
|
|
bool advisedToRetry;
|
|
DWORD opStartTime = GetTickCount();
|
|
|
|
// Cache entry created, now try to obtain auth token from the CASA Server
|
|
pToken = NULL;
|
|
retStatus = ObtainAuthTokenFromServer(pServiceName,
|
|
pHostName,
|
|
pHostName,
|
|
pHostEntryInUse,
|
|
pCredStoreScope,
|
|
&pToken,
|
|
&cacheEntryLifetime,
|
|
&advisedToRetry);
|
|
|
|
// Retry if not successful and if advised to do so
|
|
if (!CASA_SUCCESS(retStatus)
|
|
&& advisedToRetry)
|
|
{
|
|
retStatus = ObtainAuthTokenFromServer(pServiceName,
|
|
pHostName,
|
|
pHostName,
|
|
pHostEntryInUse,
|
|
pCredStoreScope,
|
|
&pToken,
|
|
&cacheEntryLifetime,
|
|
&advisedToRetry);
|
|
}
|
|
|
|
// Try to add the entry to the cache if we did not fail due
|
|
// to authentication failure.
|
|
if (CasaStatusCode(retStatus) != CASA_STATUS_AUTHENTICATION_FAILURE)
|
|
{
|
|
DWORD opEndTime = GetTickCount();
|
|
|
|
// We only want to cache bad results if the operation took a
|
|
// considerable amount of time.
|
|
if (CASA_SUCCESS(retStatus)
|
|
|| opEndTime >= (opStartTime + (BAD_CACHE_TRIGER_TIME * 1000)))
|
|
{
|
|
pCacheEntry = CreateAuthTokenCacheEntry(pServiceName,
|
|
pHostName,
|
|
pHostEntryInUse,
|
|
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);
|
|
|
|
// No need to loop any longer
|
|
break;
|
|
}
|
|
|
|
// Advance to the next host entry
|
|
pListEntry = pListEntry->Flink;
|
|
}
|
|
|
|
// Stop user process synchronization
|
|
ReleaseUserMutex(hUserMutex);
|
|
}
|
|
|
|
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,
|
|
NULL,
|
|
pAuthTokenBuf,
|
|
pAuthTokenBufLen);
|
|
|
|
DbgTrace(1, "-ObtainAuthToken- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
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);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
void
|
|
CreateATSHostEntry(
|
|
IN const char *pHostName,
|
|
IN uint16_t port)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
ATSHostEntry *pHostEntry;
|
|
|
|
DbgTrace(1, "-CreateATSHostEntry- Start\n", 0);
|
|
|
|
// Create host entry
|
|
pHostEntry = malloc(sizeof(ATSHostEntry));
|
|
if (pHostEntry != NULL)
|
|
{
|
|
// Allocate buffers to keep copies of the strings provided
|
|
pHostEntry->pNameAndPort = malloc(strlen(pHostName) + 7);
|
|
pHostEntry->pName = malloc(strlen(pHostName) + 1);
|
|
if (pHostEntry->pNameAndPort != NULL
|
|
&& pHostEntry->pName != NULL)
|
|
{
|
|
// Setup the strings into the corresponding buffers
|
|
sprintf(pHostEntry->pNameAndPort, "%s:%d", pHostName, port);
|
|
strcpy(pHostEntry->pName, pHostName);
|
|
|
|
// Save host port in entry
|
|
pHostEntry->port = port;
|
|
|
|
// Insert the entry at the tail of the list
|
|
InsertTailList(&g_ATSHostList, &pHostEntry->listEntry);
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-CreateATSHostEntry- Failed to allocate buffer\n", 0);
|
|
if (pHostEntry->pNameAndPort)
|
|
free(pHostEntry->pNameAndPort);
|
|
if (pHostEntry->pName)
|
|
free(pHostEntry->pName);
|
|
free(pHostEntry);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-CreateATSHostEntry- Failed to allocate buffer for host entry\n", 0);
|
|
}
|
|
|
|
DbgTrace(1, "-CreateATSHostEntry- Exit\n", 0);
|
|
}
|
|
|
|
//++=======================================================================
|
|
CasaStatus SSCS_CALL
|
|
SetATSHostList(
|
|
IN const char * const ATSHostList[])
|
|
//
|
|
// Arguments:
|
|
// ATSHostList -
|
|
// Pointer to NULL terminated array of ATS servers of form <server>:<port>
|
|
//
|
|
// Returns:
|
|
// Casa Status
|
|
//
|
|
// Description:
|
|
// Set the list of ATS servers contacted. Can be used to override the
|
|
// 'ATSHostList' parameter in client.conf.
|
|
//=======================================================================--
|
|
{
|
|
int i, retStatus = CASA_STATUS_SUCCESS;
|
|
uint16_t port;
|
|
char address[256];
|
|
LIST_ENTRY *pListEntry;
|
|
ATSHostEntry *pHostEntry;
|
|
HANDLE hUserMutex = NULL;
|
|
|
|
DbgTrace(1, "-SetATSHostList- Start\n", 0);
|
|
|
|
for (i = 0; ATSHostList[i] != NULL; i++) {
|
|
int ret;
|
|
ret = sscanf(ATSHostList[i], "%[^:]:%hu", address, &port);
|
|
if (ret != 2) {
|
|
DbgTrace(0, "-SetATSHostList- Invalid entry: %s\n", ATSHostList[i]);
|
|
retStatus = CASA_STATUS_INVALID_PARAMETER;
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
/* Obtain our synchronization mutex */
|
|
AcquireModuleMutex;
|
|
|
|
/* Create user synchronization mutex */
|
|
retStatus = CreateUserMutex(&hUserMutex);
|
|
if (retStatus != CASA_STATUS_SUCCESS)
|
|
{
|
|
DbgTrace(0, "-SetATSHostList- 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;
|
|
|
|
AcquireUserMutex(hUserMutex);
|
|
|
|
/* Cleanup the old ATS list */
|
|
pListEntry = g_ATSHostList.Flink;
|
|
if (pListEntry)
|
|
{
|
|
DbgTrace(0, "-SetATSHostList- Flushing ATS host list\n", 0);
|
|
while (pListEntry != &g_ATSHostList) {
|
|
pHostEntry = CONTAINING_RECORD(pListEntry, ATSHostEntry, listEntry);
|
|
RemoveEntryList(pListEntry);
|
|
free(pHostEntry->pNameAndPort);
|
|
free(pHostEntry->pName);
|
|
free(pHostEntry);
|
|
pListEntry = g_ATSHostList.Flink;
|
|
}
|
|
}
|
|
InitializeListHead(&g_ATSHostList);
|
|
|
|
for (i = 0; ATSHostList[i] != NULL; i++) {
|
|
sscanf(ATSHostList[i], "%[^:]:%hu", address, &port);
|
|
CreateATSHostEntry(address, port);
|
|
DbgTrace(0, "-SetATSHostList- Adding ATS host %s\n", ATSHostList[i]);
|
|
}
|
|
|
|
ReleaseUserMutex(hUserMutex);
|
|
|
|
exit:
|
|
|
|
if (hUserMutex != NULL)
|
|
DestroyUserMutex(hUserMutex);
|
|
|
|
DbgTrace(1, "-SetATSHostList- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
//++=======================================================================
|
|
int
|
|
InitializeLibrary(void)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
int retStatus = -1;
|
|
int getConfigStatus = -1;
|
|
ConfigIf *pClientConfigIf;
|
|
char *pDebugLevelSetting;
|
|
char *pDebugLogFolderPathSetting;
|
|
char *pATSHostListSetting;
|
|
char *pDisableSecureConnections;
|
|
char *pAllowInvalidCerts;
|
|
char *pUsersCannotAllowInvalidCerts;
|
|
|
|
DbgTrace(1, "-InitializeLibrary- Start\n", 0);
|
|
|
|
// Initialize the ATSHostList
|
|
InitializeListHead(&g_ATSHostList);
|
|
|
|
// 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 Host List has been configured
|
|
pATSHostListSetting = pClientConfigIf->getEntryValue(pClientConfigIf, "ATSHostList");
|
|
if (pATSHostListSetting != NULL)
|
|
{
|
|
char *pSavePtr;
|
|
char *pHostAndPort;
|
|
|
|
DbgTrace(0, "-InitializeLibrary- ATSHostList configured = %s\n", pATSHostListSetting);
|
|
|
|
// Go through all configured host addresses
|
|
pHostAndPort = strtok_r(pATSHostListSetting, ";", &pSavePtr);
|
|
while (pHostAndPort != NULL)
|
|
{
|
|
char *pSavePtr2;
|
|
char *pHostName;
|
|
|
|
// Check if the host address includes the listen port number.
|
|
pHostName = strtok_r(pHostAndPort, ":", &pSavePtr2);
|
|
if (pHostName != NULL)
|
|
{
|
|
uint16_t port = 0;
|
|
char *pHostPort = strtok_r(NULL, ":", &pSavePtr2);
|
|
if (pHostPort != NULL)
|
|
{
|
|
// Convert the number to hex
|
|
port = (uint16_t) dtoul(pHostPort, strlen(pHostPort));
|
|
}
|
|
|
|
// Now create the necessary ATS Host entries
|
|
if (port == 0)
|
|
{
|
|
// The port number was not configured, create an ATS Host entry
|
|
// for each possible listen port.
|
|
CreateATSHostEntry(pHostName, 443);
|
|
CreateATSHostEntry(pHostName, 2645);
|
|
}
|
|
else
|
|
{
|
|
// Create ATS Host entry for configured port
|
|
CreateATSHostEntry(pHostName, port);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-InitializeLibrary- Error parsing configured host address\n", 0);
|
|
}
|
|
|
|
// Advance to the next entry
|
|
pHostAndPort = strtok_r(NULL, ";", &pSavePtr);
|
|
}
|
|
|
|
// Free the buffer holding the ats host list setting
|
|
pClientConfigIf->freeValueString(pClientConfigIf, pATSHostListSetting);
|
|
}
|
|
|
|
// 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
|
|
if (stricmp(pDisableSecureConnections, "true") == 0)
|
|
{
|
|
g_rpcFlags &= ~SECURE_RPC_FLAG;
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Release config interface instance
|
|
pClientConfigIf->releaseReference(pClientConfigIf);
|
|
}
|
|
|
|
// Initialize the host name normalization
|
|
retStatus = InitializeHostNameNormalization();
|
|
if (CASA_SUCCESS(retStatus))
|
|
{
|
|
// 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
|
|
//=======================================================================--
|
|
{
|
|
LIST_ENTRY *pListEntry;
|
|
ATSHostEntry *pHostEntry;
|
|
|
|
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);
|
|
}
|
|
|
|
pListEntry = g_ATSHostList.Flink;
|
|
if (pListEntry)
|
|
{
|
|
while (pListEntry != &g_ATSHostList)
|
|
{
|
|
pHostEntry = CONTAINING_RECORD(pListEntry, ATSHostEntry, listEntry);
|
|
RemoveEntryList(pListEntry);
|
|
free(pHostEntry->pNameAndPort);
|
|
free(pHostEntry->pName);
|
|
free(pHostEntry);
|
|
pListEntry = g_ATSHostList.Flink;
|
|
}
|
|
}
|
|
|
|
DbgTrace(1, "-UnInitializeLibrary- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
|