/*********************************************************************** * * 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 * ***********************************************************************/ //===[ Include files ]===================================================== #include "internal.h" //===[ Type definitions ]================================================== //===[ Function prototypes ]=============================================== //===[ Global variables ]================================================== // Debug Level int DebugLevel = 0; // // Initialization variables // static bool g_moduleInitialized = false; // // IPC Client Sub-system variables // uint32_t atvsEndPointHandle; // Authentication Token Validation Service endpoint handle //++======================================================================= CasaStatus SSCS_CALL ValidateAuthToken( IN const char *pServiceName, IN const char *pTokenBuf, IN const int tokenBufLen, INOUT PrincipalIf **ppPrincipalIf) // // Arguments: // pServiceName - // Pointer to NULL terminated string that contains the // name of the service targeted by the token. // // pTokenBuf - // Pointer to buffer that will receive the authentication // token. The length of this buffer is specified by the // pTokenBufLen parameter. Note that the the authentication // token will be in the form of a NULL terminated string. // // tokenBufLen - // Length of the data contained within the buffer pointed // at by pTokenBuf. // // ppPrincipalIf - // Pointer to variable that will receive a pointer to a principal // interface with information about the authenticated entity. // IMPORTANT NOTE: The caller is responsible for releasing the // interface after it is done with it to avoid a resource leak. // // Returns: // Casa status. // // Description: // Validates authentication token. // // L2 //=======================================================================-- { CasaStatus retStatus; char *pDecodedTokenBuf; int decodedTokenBufLen; PrincipalIf *pPrincipalIf; DbgTrace(1, "-ValidateAuthToken- Start\n", 0); // Validate input parameters if (pServiceName == NULL || pTokenBuf == NULL || tokenBufLen == 0 || ppPrincipalIf == NULL) { DbgTrace(0, "-ValidateAuthToken- Invalid input parameter\n", 0); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, 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 ConfigIf complex retStatus = ConfigIfInit(); if (CASA_SUCCESS(retStatus)) { // Initialize the PrincipalIf complex retStatus = PrincipalIfInit(); if (CASA_SUCCESS(retStatus)) { // Initialize the IdenToken complex retStatus = IdenTokenInit(); if (CASA_SUCCESS(retStatus)) { // Initialize the Client Ipc Subsystem if (IpcClientInit("CASA_AuthTokenValidate", true, DebugLevel, false) == 0) { // Open endpoint for the Authentication Token Validation Service if (IpcClientOpenInetRemoteEndPoint(5000, 0x7F000001, 0, &atvsEndPointHandle) == 0) { // Success g_moduleInitialized = true; } else { DbgTrace(0, "-ValidateAuthToken- Failed to open remote endpoint\n", 0); IpcClientShutdown(); IdenTokenUninit(); PrincipalIfUninit(); ConfigIfUninit(); } } else { DbgTrace(0, "-ValidateAuthToken- Ipc subsystem initialization failed\n", 0); IdenTokenUninit(); PrincipalIfUninit(); ConfigIfUninit(); } } else { PrincipalIfUninit(); ConfigIfUninit(); } } else { ConfigIfUninit(); } } } // Stop synchronization ReleaseModuleMutex; // Exit if we failed if (g_moduleInitialized == false) goto exit; } // First decode the token string retStatus = DecodeData(pTokenBuf, tokenBufLen, (void**) &pDecodedTokenBuf, &decodedTokenBufLen); if (CASA_SUCCESS(retStatus)) { char *pIdenTokenData; int idenTokenDataLen; // Token was decoded successfully, now submit the authentication token to the // authentication token validation service. if (IpcClientSubmitReq(atvsEndPointHandle, pDecodedTokenBuf, decodedTokenBufLen, &pIdenTokenData, &idenTokenDataLen) == 0) { // The submit succeeded, make sure that we got some identity data back. if (pIdenTokenData) { if (idenTokenDataLen != 0) { IdenTokenProviderIf *pIdenTokenProviderIf; // The authentication token was validated, now obtain // Identity Token Provider interface. retStatus = GetIdenTokenProviderInterface("CasaIdentityToken", // tbd - Hard code until we enhance the protocol with the atvs to also return this information. &pIdenTokenProviderIf); if (CASA_SUCCESS(retStatus)) { IdenTokenIf *pIdenTokenIf; // Use the Identity Token Provider to get an Identity Token Interface instance retStatus = pIdenTokenProviderIf->getIdentityTokenIf(pIdenTokenProviderIf, pIdenTokenData, idenTokenDataLen, &pIdenTokenIf); if (CASA_SUCCESS(retStatus)) { // Now create a principal interface instance with the identity information present in // the identity token. retStatus = GetPrincipalInterface(pIdenTokenIf, &pPrincipalIf); if (CASA_SUCCESS(retStatus)) { // Success, return the principal interface to the caller. *ppPrincipalIf = pPrincipalIf; } else { DbgTrace(0, "-ValidateAuthToken- Failed to instantiate principal interface\n", 0); } // Release identity token interface pIdenTokenIf->releaseReference(pIdenTokenIf); } else { DbgTrace(0, "-ValidateAuthToken- Failed to instantiate identity token\n", 0); } // Release identity token provider interface pIdenTokenProviderIf->releaseReference(pIdenTokenProviderIf); } else { DbgTrace(0, "-ValidateAuthToken- Failed to obtain identity token provider interface\n", 0); } } else { DbgTrace(0, "-ValidateAuthToken- ValidateAuthToken submit did not return identity token data\n", 0); } // Free the buffer containing the identity token data free(pIdenTokenData); } else { DbgTrace(0, "-ValidateAuthToken- ValidateAuthToken submit did not return identity token data buffer\n", 0); } } else { DbgTrace(1, "-ValidateAuthToken- ValidateAuthToken submit failed\n", 0); } // Free the decoded token buffer free(pDecodedTokenBuf); } else { DbgTrace(0, "-ValidateAuthToken- Token decode failure\n", 0); } exit: DbgTrace(1, "-ValidateAuthToken- End, retStatus = %08X\n", retStatus); return retStatus; } //++======================================================================= //++======================================================================= //++=======================================================================