Updates resulting from self-code review.
This commit is contained in:
parent
74dce09720
commit
d55ac482ac
@ -193,7 +193,10 @@ ObtainSessionToken(
|
|||||||
// Free resources that may be hanging around
|
// Free resources that may be hanging around
|
||||||
if (pRespMsg)
|
if (pRespMsg)
|
||||||
free(pRespMsg);
|
free(pRespMsg);
|
||||||
|
|
||||||
|
// Clear and free the memory associated with the request message since
|
||||||
|
// it may contain sensitive information.
|
||||||
|
memset(pReqMsg, 0, strlen(pReqMsg));
|
||||||
free(pReqMsg);
|
free(pReqMsg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -223,6 +226,8 @@ ObtainSessionToken(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Free up the buffer associated with the authentication mechanism token
|
// 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);
|
free(pAuthMechToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -101,7 +101,6 @@ AuthTokenIf_GetAuthToken(
|
|||||||
TimeStamp expiry;
|
TimeStamp expiry;
|
||||||
CredHandle hCredentials = {0};
|
CredHandle hCredentials = {0};
|
||||||
|
|
||||||
|
|
||||||
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0);
|
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0);
|
||||||
|
|
||||||
// Validate input parameters
|
// Validate input parameters
|
||||||
@ -211,7 +210,9 @@ AuthTokenIf_GetAuthToken(
|
|||||||
// Return the actual size or the size required
|
// Return the actual size or the size required
|
||||||
*pTokenBufLen = encodedTokenLen;
|
*pTokenBufLen = encodedTokenLen;
|
||||||
|
|
||||||
// Free the buffer containing the encoded token
|
// Free the buffer containing the encoded token after clearing
|
||||||
|
// its memory to avoid leaking sensitive information.
|
||||||
|
memset(pEncodedToken, 0, strlen(pEncodedToken));
|
||||||
free(pEncodedToken);
|
free(pEncodedToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +230,10 @@ AuthTokenIf_GetAuthToken(
|
|||||||
|
|
||||||
// Free any buffer associated with the sendToken
|
// Free any buffer associated with the sendToken
|
||||||
if (sendTok.pvBuffer)
|
if (sendTok.pvBuffer)
|
||||||
|
{
|
||||||
|
memset(sendTok.pvBuffer, 0, sendTok.cbBuffer);
|
||||||
FreeContextBuffer(sendTok.pvBuffer);
|
FreeContextBuffer(sendTok.pvBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
// Free the credential handle obtained
|
// Free the credential handle obtained
|
||||||
FreeCredentialsHandle(&hCredentials);
|
FreeCredentialsHandle(&hCredentials);
|
||||||
|
@ -1,362 +1,371 @@
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
* License as published by the Free Software Foundation; version 2.1
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
* of the License.
|
* of the License.
|
||||||
*
|
*
|
||||||
* This library is distributed in the hope that it will be useful,
|
* This library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* Library Lesser General Public License for more details.
|
* Library Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, Novell, Inc.
|
* License along with this library; if not, Novell, Inc.
|
||||||
*
|
*
|
||||||
* To contact Novell about this file by physical or electronic mail,
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
* you may find current contact information at www.novell.com.
|
* you may find current contact information at www.novell.com.
|
||||||
*
|
*
|
||||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
*
|
*
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
//===[ Include files ]=====================================================
|
//===[ Include files ]=====================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
//===[ Type definitions ]==================================================
|
//===[ Type definitions ]==================================================
|
||||||
|
|
||||||
//===[ Function prototypes ]===============================================
|
//===[ Function prototypes ]===============================================
|
||||||
|
|
||||||
//===[ Global variables ]==================================================
|
//===[ Global variables ]==================================================
|
||||||
|
|
||||||
|
|
||||||
//++=======================================================================
|
//++=======================================================================
|
||||||
static
|
static
|
||||||
CasaStatus
|
CasaStatus
|
||||||
GetUserCredentials(
|
GetUserCredentials(
|
||||||
IN const char *pRealm,
|
IN const char *pRealm,
|
||||||
IN void *pCredStoreScope,
|
IN void *pCredStoreScope,
|
||||||
INOUT char **ppUsername,
|
INOUT char **ppUsername,
|
||||||
INOUT char **ppPassword)
|
INOUT char **ppPassword)
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// pRealm -
|
// pRealm -
|
||||||
// The realm to which the credentials apply.
|
// The realm to which the credentials apply.
|
||||||
//
|
//
|
||||||
// pCredStoreScope -
|
// pCredStoreScope -
|
||||||
// Pointer to CASA structure for scoping credential store access
|
// Pointer to CASA structure for scoping credential store access
|
||||||
// to specific users. This can only be leveraged when running in
|
// to specific users. This can only be leveraged when running in
|
||||||
// the context of System under Windows.
|
// the context of System under Windows.
|
||||||
//
|
//
|
||||||
// ppUsername -
|
// ppUsername -
|
||||||
// Pointer to variable that will receive buffer with the username.
|
// Pointer to variable that will receive buffer with the username.
|
||||||
//
|
//
|
||||||
// ppPassword -
|
// ppPassword -
|
||||||
// Pointer to variable that will receive buffer with the password.
|
// Pointer to variable that will receive buffer with the password.
|
||||||
//
|
//
|
||||||
// Returns:
|
// Returns:
|
||||||
// Casa Status
|
// Casa Status
|
||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
// Get authentication credentials for the specified realm.
|
// Get authentication credentials for the specified realm.
|
||||||
//
|
//
|
||||||
// L2
|
// L2
|
||||||
//=======================================================================--
|
//=======================================================================--
|
||||||
{
|
{
|
||||||
CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_PWTOKEN,
|
CASA_FACILITY_PWTOKEN,
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
char *pUsername;
|
char *pUsername;
|
||||||
char *pPassword;
|
char *pPassword;
|
||||||
int rcode = NSSCS_E_OBJECT_NOT_FOUND;
|
int rcode = NSSCS_E_OBJECT_NOT_FOUND;
|
||||||
uint32_t credtype = SSCS_CRED_TYPE_BASIC_F;
|
uint32_t credtype = SSCS_CRED_TYPE_BASIC_F;
|
||||||
SSCS_BASIC_CREDENTIAL credential = {0};
|
SSCS_BASIC_CREDENTIAL credential = {0};
|
||||||
SSCS_SECRET_ID_T secretId = {0};
|
SSCS_SECRET_ID_T secretId = {0};
|
||||||
|
|
||||||
DbgTrace(1, "-GetUserCredentials- Start\n", 0);
|
DbgTrace(1, "-GetUserCredentials- Start\n", 0);
|
||||||
|
|
||||||
// Initialize output parameters
|
// Initialize output parameters
|
||||||
*ppUsername = NULL;
|
*ppUsername = NULL;
|
||||||
*ppPassword = NULL;
|
*ppPassword = NULL;
|
||||||
|
|
||||||
// Get the length of the realm string into the secret id structure
|
// Get the length of the realm string into the secret id structure
|
||||||
// and verify thatr it is not too long.
|
// and verify thatr it is not too long.
|
||||||
secretId.len = sscs_Utf8Strlen(pRealm) + 1;
|
secretId.len = sscs_Utf8Strlen(pRealm) + 1;
|
||||||
if (secretId.len <= NSSCS_MAX_SECRET_ID_LEN)
|
if (secretId.len <= NSSCS_MAX_SECRET_ID_LEN)
|
||||||
{
|
{
|
||||||
// Set the secret id in the structure
|
// Set the secret id in the structure
|
||||||
sscs_Utf8Strcpy((char*) secretId.id, pRealm);
|
sscs_Utf8Strcpy((char*) secretId.id, pRealm);
|
||||||
|
|
||||||
// Specify that we want the common name
|
// Specify that we want the common name
|
||||||
credential.unFlags = USERNAME_TYPE_CN_F;
|
credential.unFlags = USERNAME_TYPE_CN_F;
|
||||||
|
|
||||||
// Now try to get the credentials
|
// Now try to get the credentials
|
||||||
rcode = miCASAGetCredential(0,
|
rcode = miCASAGetCredential(0,
|
||||||
&secretId,
|
&secretId,
|
||||||
NULL,
|
NULL,
|
||||||
&credtype,
|
&credtype,
|
||||||
&credential,
|
&credential,
|
||||||
(SSCS_EXT_T*) pCredStoreScope);
|
(SSCS_EXT_T*) pCredStoreScope);
|
||||||
if (rcode != NSSCS_SUCCESS)
|
if (rcode != NSSCS_SUCCESS)
|
||||||
{
|
{
|
||||||
// There were no credentials for the realm, now try to obtain the
|
// There were no credentials for the realm, now try to obtain the
|
||||||
// desktop credentials.
|
// desktop credentials.
|
||||||
secretId.len = sscs_Utf8Strlen("Desktop") + 1;
|
secretId.len = sscs_Utf8Strlen("Desktop") + 1;
|
||||||
if (secretId.len <= NSSCS_MAX_SECRET_ID_LEN)
|
if (secretId.len <= NSSCS_MAX_SECRET_ID_LEN)
|
||||||
{
|
{
|
||||||
sscs_Utf8Strcpy((char*) secretId.id, "Desktop");
|
sscs_Utf8Strcpy((char*) secretId.id, "Desktop");
|
||||||
rcode = miCASAGetCredential(0,
|
rcode = miCASAGetCredential(0,
|
||||||
&secretId,
|
&secretId,
|
||||||
NULL,
|
NULL,
|
||||||
&credtype,
|
&credtype,
|
||||||
&credential,
|
&credential,
|
||||||
(SSCS_EXT_T*) pCredStoreScope);
|
(SSCS_EXT_T*) pCredStoreScope);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-GetUserCredentials- Desktop name too long\n", 0);
|
DbgTrace(0, "-GetUserCredentials- Desktop name too long\n", 0);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_PWTOKEN,
|
CASA_FACILITY_PWTOKEN,
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-GetUserCredentials- Realm name too long\n", 0);
|
DbgTrace(0, "-GetUserCredentials- Realm name too long\n", 0);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_PWTOKEN,
|
CASA_FACILITY_PWTOKEN,
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proceed based on the result of the operatiosn above
|
// Proceed based on the result of the operatiosn above
|
||||||
if (rcode == NSSCS_SUCCESS
|
if (rcode == NSSCS_SUCCESS
|
||||||
&& credential.username != NULL
|
&& credential.username != NULL
|
||||||
&& credential.password != NULL)
|
&& credential.password != NULL)
|
||||||
{
|
{
|
||||||
// Allocate a buffer to return the username
|
// Allocate a buffer to return the username
|
||||||
pUsername = (char*) malloc(strlen((char*) credential.username) + 1);
|
pUsername = (char*) malloc(strlen((char*) credential.username) + 1);
|
||||||
if (pUsername)
|
if (pUsername)
|
||||||
{
|
{
|
||||||
// Copy the username into the buffer that we will be returning
|
// Copy the username into the buffer that we will be returning
|
||||||
strcpy(pUsername, (char*) credential.username);
|
strcpy(pUsername, (char*) credential.username);
|
||||||
|
|
||||||
// Allocate a buffer to return the password
|
// Allocate a buffer to return the password
|
||||||
pPassword = (char*) malloc(strlen((char*) credential.password) + 1);
|
pPassword = (char*) malloc(strlen((char*) credential.password) + 1);
|
||||||
if (pPassword)
|
if (pPassword)
|
||||||
{
|
{
|
||||||
// Copy the password into the buffer that we will be returning
|
// Copy the password into the buffer that we will be returning
|
||||||
strcpy(pPassword, (char*) credential.password);
|
strcpy(pPassword, (char*) credential.password);
|
||||||
|
|
||||||
DbgTrace(1, "-GetUserCredentials- Username = %s\n", pUsername);
|
DbgTrace(1, "-GetUserCredentials- Username = %s\n", pUsername);
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
retStatus = CASA_STATUS_SUCCESS;
|
retStatus = CASA_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-GetUserCredentials- Buffer allocation error\n", 0);
|
DbgTrace(0, "-GetUserCredentials- Buffer allocation error\n", 0);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_PWTOKEN,
|
CASA_FACILITY_PWTOKEN,
|
||||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
|
||||||
// Free the buffer allocated for the username
|
// Free the buffer allocated for the username
|
||||||
free(pUsername);
|
free(pUsername);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-GetUserCredentials- Buffer allocation error\n", 0);
|
DbgTrace(0, "-GetUserCredentials- Buffer allocation error\n", 0);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_PWTOKEN,
|
CASA_FACILITY_PWTOKEN,
|
||||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-GetUserCredentials- Failed to obtain credentials for pw authentication\n", 0);
|
DbgTrace(0, "-GetUserCredentials- Failed to obtain credentials for pw authentication\n", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the buffers to the caller if successful
|
// Clear out the credential structure to make sure that we are not leaving sensitive
|
||||||
if (CASA_SUCCESS(retStatus))
|
// information on the stack.
|
||||||
{
|
memset(&credential, 0, sizeof(credential));
|
||||||
*ppUsername = pUsername;
|
|
||||||
*ppPassword = pPassword;
|
// Return the buffers to the caller if successful
|
||||||
}
|
if (CASA_SUCCESS(retStatus))
|
||||||
|
{
|
||||||
DbgTrace(1, "-GetUserCredentials- End, retStatus = %0X\n", retStatus);
|
*ppUsername = pUsername;
|
||||||
|
*ppPassword = pPassword;
|
||||||
return retStatus;
|
}
|
||||||
}
|
|
||||||
|
DbgTrace(1, "-GetUserCredentials- End, retStatus = %0X\n", retStatus);
|
||||||
|
|
||||||
//++=======================================================================
|
return retStatus;
|
||||||
CasaStatus SSCS_CALL
|
}
|
||||||
AuthTokenIf_GetAuthToken(
|
|
||||||
IN const void *pIfInstance,
|
|
||||||
IN const char *pContext,
|
//++=======================================================================
|
||||||
IN const char *pMechInfo,
|
CasaStatus SSCS_CALL
|
||||||
IN const char *pHostName,
|
AuthTokenIf_GetAuthToken(
|
||||||
|
IN const void *pIfInstance,
|
||||||
|
IN const char *pContext,
|
||||||
|
IN const char *pMechInfo,
|
||||||
|
IN const char *pHostName,
|
||||||
IN void *pCredStoreScope,
|
IN void *pCredStoreScope,
|
||||||
INOUT char *pTokenBuf,
|
INOUT char *pTokenBuf,
|
||||||
INOUT int *pTokenBufLen)
|
INOUT int *pTokenBufLen)
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// pIfInstance -
|
// pIfInstance -
|
||||||
// Pointer to interface object.
|
// Pointer to interface object.
|
||||||
//
|
//
|
||||||
// pContext -
|
// pContext -
|
||||||
// Pointer to null terminated string containing mechanism specific
|
// Pointer to null terminated string containing mechanism specific
|
||||||
// context information. Another name for context is Authentication
|
// context information. Another name for context is Authentication
|
||||||
// Realm.
|
// Realm.
|
||||||
//
|
//
|
||||||
// pMechInfo -
|
// pMechInfo -
|
||||||
// Pointer to null terminated string containing mechanism specific
|
// Pointer to null terminated string containing mechanism specific
|
||||||
// information. This is information is provided by the server to
|
// information. This is information is provided by the server to
|
||||||
// aid the mechanism to generate an authentication token. For
|
// aid the mechanism to generate an authentication token. For
|
||||||
// example, the mechanism information for a Kerberos mechanism
|
// example, the mechanism information for a Kerberos mechanism
|
||||||
// may be the service principal name to which the user will be
|
// may be the service principal name to which the user will be
|
||||||
// authenticating.
|
// authenticating.
|
||||||
//
|
//
|
||||||
// pHostName -
|
// pHostName -
|
||||||
// Pointer to null terminated string containing the name of the
|
// Pointer to null terminated string containing the name of the
|
||||||
// host where the ATS resides.
|
// host where the ATS resides.
|
||||||
//
|
//
|
||||||
// pCredStoreScope -
|
// pCredStoreScope -
|
||||||
// Pointer to CASA structure for scoping credential store access
|
// Pointer to CASA structure for scoping credential store access
|
||||||
// to specific users. This can only be leveraged when running in
|
// to specific users. This can only be leveraged when running in
|
||||||
// the context of System under Windows.
|
// the context of System under Windows.
|
||||||
//
|
//
|
||||||
// pTokenBuf -
|
// pTokenBuf -
|
||||||
// Pointer to buffer that will receive the authentication
|
// Pointer to buffer that will receive the authentication
|
||||||
// token. The length of this buffer is specified by the
|
// token. The length of this buffer is specified by the
|
||||||
// pTokenBufLen parameter. Note that the the authentication
|
// pTokenBufLen parameter. Note that the the authentication
|
||||||
// token will be in the form of a NULL terminated string.
|
// token will be in the form of a NULL terminated string.
|
||||||
//
|
//
|
||||||
// pTokenBufLen -
|
// pTokenBufLen -
|
||||||
// Pointer to integer that contains the length of the
|
// Pointer to integer that contains the length of the
|
||||||
// buffer pointed at by pTokenBuf. Upon return of the
|
// buffer pointed at by pTokenBuf. Upon return of the
|
||||||
// function, the integer will contain the actual length
|
// function, the integer will contain the actual length
|
||||||
// of the authentication token if the function successfully
|
// of the authentication token if the function successfully
|
||||||
// completes or the buffer length required if the function
|
// completes or the buffer length required if the function
|
||||||
// fails because the buffer pointed at by pUserNameBuf is
|
// fails because the buffer pointed at by pUserNameBuf is
|
||||||
// not large enough.
|
// not large enough.
|
||||||
//
|
//
|
||||||
// Returns:
|
// Returns:
|
||||||
// Casa Status
|
// Casa Status
|
||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
// Get authentication token to authenticate user to specified service.
|
// Get authentication token to authenticate user to specified service.
|
||||||
//
|
//
|
||||||
// L2
|
// L2
|
||||||
//=======================================================================--
|
//=======================================================================--
|
||||||
{
|
{
|
||||||
CasaStatus retStatus;
|
CasaStatus retStatus;
|
||||||
char *pUsername = NULL;
|
char *pUsername = NULL;
|
||||||
char *pPassword = NULL;
|
char *pPassword = NULL;
|
||||||
char *pToken;
|
char *pToken;
|
||||||
|
|
||||||
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0);
|
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0);
|
||||||
|
|
||||||
// Validate input parameters
|
// Validate input parameters
|
||||||
if (pIfInstance == NULL
|
if (pIfInstance == NULL
|
||||||
|| pContext == NULL
|
|| pContext == NULL
|
||||||
|| pHostName == NULL
|
|| pHostName == NULL
|
||||||
|| pTokenBufLen == NULL
|
|| pTokenBufLen == NULL
|
||||||
|| (pTokenBuf == NULL && *pTokenBufLen != 0))
|
|| (pTokenBuf == NULL && *pTokenBufLen != 0))
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-AuthTokenIf_GetAuthToken- Invalid input parameter\n", 0);
|
DbgTrace(0, "-AuthTokenIf_GetAuthToken- Invalid input parameter\n", 0);
|
||||||
|
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_PWTOKEN,
|
CASA_FACILITY_PWTOKEN,
|
||||||
CASA_STATUS_INVALID_PARAMETER);
|
CASA_STATUS_INVALID_PARAMETER);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the user credentials
|
// Get the user credentials
|
||||||
retStatus = GetUserCredentials(pContext,
|
retStatus = GetUserCredentials(pContext,
|
||||||
pCredStoreScope,
|
pCredStoreScope,
|
||||||
&pUsername,
|
&pUsername,
|
||||||
&pPassword);
|
&pPassword);
|
||||||
if (CASA_SUCCESS(retStatus))
|
if (CASA_SUCCESS(retStatus))
|
||||||
{
|
{
|
||||||
// Now construct the PW token with the following format:
|
// Now construct the PW token with the following format:
|
||||||
// "username\r\n" + "password\r\n"
|
// "username\r\n" + "password\r\n"
|
||||||
//
|
//
|
||||||
// First allocate a buffer large enough to hold the token
|
// First allocate a buffer large enough to hold the token
|
||||||
pToken = (char*) malloc(strlen(pUsername) + 2 + strlen(pPassword) + 2 + 1);
|
pToken = (char*) malloc(strlen(pUsername) + 2 + strlen(pPassword) + 2 + 1);
|
||||||
if (pToken)
|
if (pToken)
|
||||||
{
|
{
|
||||||
char *pEncodedToken;
|
char *pEncodedToken;
|
||||||
int encodedTokenLen;
|
int encodedTokenLen;
|
||||||
|
|
||||||
// Now assemble the token
|
// Now assemble the token
|
||||||
sprintf(pToken, "%s\r\n%s\r\n", pUsername, pPassword);
|
sprintf(pToken, "%s\r\n%s\r\n", pUsername, pPassword);
|
||||||
|
|
||||||
// The token has been assembled, now encode it.
|
// The token has been assembled, now encode it.
|
||||||
retStatus = EncodeData(pToken,
|
retStatus = EncodeData(pToken,
|
||||||
(const int) strlen(pToken),
|
(const int) strlen(pToken),
|
||||||
&pEncodedToken,
|
&pEncodedToken,
|
||||||
&encodedTokenLen);
|
&encodedTokenLen);
|
||||||
if (CASA_SUCCESS(retStatus))
|
if (CASA_SUCCESS(retStatus))
|
||||||
{
|
{
|
||||||
// Verify that the caller provided a buffer that is big enough
|
// Verify that the caller provided a buffer that is big enough
|
||||||
if (encodedTokenLen > *pTokenBufLen)
|
if (encodedTokenLen > *pTokenBufLen)
|
||||||
{
|
{
|
||||||
// The buffer is not big enough
|
// The buffer is not big enough
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_PWTOKEN,
|
CASA_FACILITY_PWTOKEN,
|
||||||
CASA_STATUS_BUFFER_OVERFLOW);
|
CASA_STATUS_BUFFER_OVERFLOW);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The buffer provided is large enough, copy the data.
|
// The buffer provided is large enough, copy the data.
|
||||||
memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
|
memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
retStatus = CASA_STATUS_SUCCESS;
|
retStatus = CASA_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the actual size or the size required
|
// Return the actual size or the size required
|
||||||
*pTokenBufLen = encodedTokenLen;
|
*pTokenBufLen = encodedTokenLen;
|
||||||
|
|
||||||
// Free the buffer containing the encoded token
|
// Free the buffer containing the encoded token after clearing
|
||||||
free(pEncodedToken);
|
// it to avoid leaking sensitive information.
|
||||||
}
|
memset(pEncodedToken, 0, strlen(pEncodedToken));
|
||||||
|
free(pEncodedToken);
|
||||||
// Free the buffer allocated for the token
|
}
|
||||||
free(pToken);
|
|
||||||
}
|
// Free the buffer allocated for the token after clearing it
|
||||||
else
|
// to avoid leaving sensitive information behind.
|
||||||
{
|
memset(pToken, 0, strlen(pToken));
|
||||||
DbgTrace(0, "-AuthTokenIf_GetAuthToken- Buffer allocation error\n", 0);
|
free(pToken);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
}
|
||||||
CASA_FACILITY_PWTOKEN,
|
else
|
||||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
{
|
||||||
}
|
DbgTrace(0, "-AuthTokenIf_GetAuthToken- Buffer allocation error\n", 0);
|
||||||
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
// Free allocated buffers
|
CASA_FACILITY_PWTOKEN,
|
||||||
free(pUsername);
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
free(pPassword);
|
}
|
||||||
}
|
|
||||||
else
|
// Free allocated buffers after clearing memory holding the password
|
||||||
{
|
free(pUsername);
|
||||||
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Failed to obtain the user credentials\n", 0);
|
memset(pPassword, 0, strlen(pPassword));
|
||||||
}
|
free(pPassword);
|
||||||
|
}
|
||||||
exit:
|
else
|
||||||
|
{
|
||||||
DbgTrace(1, "-AuthTokenIf_GetAuthToken- End, retStatus = %08X\n", retStatus);
|
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Failed to obtain the user credentials\n", 0);
|
||||||
|
}
|
||||||
return retStatus;
|
|
||||||
}
|
exit:
|
||||||
|
|
||||||
|
DbgTrace(1, "-AuthTokenIf_GetAuthToken- End, retStatus = %08X\n", retStatus);
|
||||||
//++=======================================================================
|
|
||||||
//++=======================================================================
|
return retStatus;
|
||||||
//++=======================================================================
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//++=======================================================================
|
||||||
|
//++=======================================================================
|
||||||
|
//++=======================================================================
|
||||||
|
|
||||||
|
@ -28,5 +28,5 @@ LibraryName \Program Files\novell\casa\lib\pwmech.dll
|
|||||||
# tools such as DbgView. Under Linux, debug statements are logged
|
# tools such as DbgView. Under Linux, debug statements are logged
|
||||||
# to /var/log/messages.
|
# to /var/log/messages.
|
||||||
#
|
#
|
||||||
#DebugLevel 0
|
#DebugLevel 0
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ BOOL APIENTRY DllMain(
|
|||||||
//=======================================================================--
|
//=======================================================================--
|
||||||
{
|
{
|
||||||
BOOL retStatus = TRUE;
|
BOOL retStatus = TRUE;
|
||||||
char programFilesFolder[MAX_PATH];
|
char programFilesFolder[MAX_PATH] = {0};
|
||||||
|
|
||||||
switch (ul_reason_for_call)
|
switch (ul_reason_for_call)
|
||||||
{
|
{
|
||||||
|
@ -54,12 +54,12 @@ static
|
|||||||
HANDLE hNormalizedHostNameCacheMutex;
|
HANDLE hNormalizedHostNameCacheMutex;
|
||||||
|
|
||||||
// Client configuration file folder
|
// Client configuration file folder
|
||||||
char clientConfigFolder[MAX_PATH];
|
|
||||||
char clientConfigFolderPartialPath[] = "Novell\\Casa\\Etc\\Auth";
|
char clientConfigFolderPartialPath[] = "Novell\\Casa\\Etc\\Auth";
|
||||||
|
char clientConfigFolder[MAX_PATH + sizeof(clientConfigFolderPartialPath)];
|
||||||
|
|
||||||
// Authentication mechanism configuration file folder
|
// Authentication mechanism configuration file folder
|
||||||
char mechConfigFolder[MAX_PATH];
|
|
||||||
char mechConfigFolderPartialPath[] = "Novell\\Casa\\Etc\\Auth\\Mechanisms";
|
char mechConfigFolderPartialPath[] = "Novell\\Casa\\Etc\\Auth\\Mechanisms";
|
||||||
|
char mechConfigFolder[MAX_PATH + sizeof(mechConfigFolderPartialPath)];
|
||||||
|
|
||||||
// Path separator
|
// Path separator
|
||||||
char pathCharString[] = "\\";
|
char pathCharString[] = "\\";
|
||||||
@ -81,6 +81,8 @@ CreateUserMutex(
|
|||||||
// L2
|
// L2
|
||||||
//=======================================================================--
|
//=======================================================================--
|
||||||
{
|
{
|
||||||
|
#define USER_MUTEX_NAME_FMT_STRING "Global\\CASA_Auth_Mutex_%s"
|
||||||
|
|
||||||
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
||||||
char *pUsername = NULL;
|
char *pUsername = NULL;
|
||||||
DWORD nameLength = 0;
|
DWORD nameLength = 0;
|
||||||
@ -99,32 +101,47 @@ CreateUserMutex(
|
|||||||
if (GetUserName(pUsername, &nameLength))
|
if (GetUserName(pUsername, &nameLength))
|
||||||
{
|
{
|
||||||
SECURITY_ATTRIBUTES mutexAttributes;
|
SECURITY_ATTRIBUTES mutexAttributes;
|
||||||
char mutexName[256];
|
char *pMutexName;
|
||||||
|
|
||||||
// Now lets create a global semaphore for the
|
// Allocate a buffer to hold the mutex name
|
||||||
// user and allow its handle to be inherited.
|
pMutexName = (char*) malloc(sizeof(USER_MUTEX_NAME_FMT_STRING) + nameLength);
|
||||||
mutexAttributes.nLength = sizeof(mutexAttributes);
|
if (pMutexName)
|
||||||
mutexAttributes.lpSecurityDescriptor = NULL;
|
|
||||||
mutexAttributes.bInheritHandle = TRUE;
|
|
||||||
if (sprintf(mutexName, "Global\\CASA_Auth_Mutex_%s", pUsername) != -1)
|
|
||||||
{
|
{
|
||||||
*phMutex = CreateMutex(&mutexAttributes,
|
// Now lets create a global semaphore for the
|
||||||
FALSE,
|
// user and allow its handle to be inherited.
|
||||||
mutexName);
|
mutexAttributes.nLength = sizeof(mutexAttributes);
|
||||||
if (*phMutex == NULL)
|
mutexAttributes.lpSecurityDescriptor = NULL;
|
||||||
|
mutexAttributes.bInheritHandle = TRUE;
|
||||||
|
if (sprintf(pMutexName, USER_MUTEX_NAME_FMT_STRING, pUsername) != -1)
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-CreateUserMutex- CreateMutex failed, error = %d\n", GetLastError());
|
*phMutex = CreateMutex(&mutexAttributes,
|
||||||
|
FALSE,
|
||||||
|
pMutexName);
|
||||||
|
if (*phMutex == NULL)
|
||||||
|
{
|
||||||
|
DbgTrace(0, "-CreateUserMutex- CreateMutex failed, error = %d\n", GetLastError());
|
||||||
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbgTrace(0, "-CreateUserMutex- sprintf failed, error = %d\n", GetLastError());
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the buffer used to hold the user mutex name
|
||||||
|
free(pMutexName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-CreateUserMutex- sprintf failed, error = %d\n", GetLastError());
|
DbgTrace(0, "-CreateUserMutex- Buffer allocation failure\n", 0);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -415,53 +432,65 @@ NormalizeHostName(
|
|||||||
|
|
||||||
// Now try to resolve the normalized name
|
// Now try to resolve the normalized name
|
||||||
pLookupResult = gethostbyname(pHostName);
|
pLookupResult = gethostbyname(pHostName);
|
||||||
if (pLookupResult && pLookupResult->h_addrtype == AF_INET)
|
if (pLookupResult
|
||||||
|
&& pLookupResult->h_addrtype == AF_INET
|
||||||
|
&& pLookupResult->h_length > 0
|
||||||
|
&& pLookupResult->h_addr_list[0] != NULL)
|
||||||
{
|
{
|
||||||
char dnsHostName[NI_MAXHOST];
|
char *pDnsHostName = (char*) malloc(NI_MAXHOST + 1);
|
||||||
|
if (pDnsHostName)
|
||||||
// Set up a sockaddr structure
|
|
||||||
sockAddr.sin_family = AF_INET;
|
|
||||||
sockAddr.sin_addr.S_un.S_addr = *((int*) pLookupResult->h_addr_list[0]);
|
|
||||||
|
|
||||||
// Now try to resolve the name using DNS
|
|
||||||
if (getnameinfo((const struct sockaddr*) &sockAddr,
|
|
||||||
sizeof(sockAddr),
|
|
||||||
dnsHostName,
|
|
||||||
sizeof(dnsHostName),
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NI_NAMEREQD) == 0)
|
|
||||||
{
|
{
|
||||||
// We resolved the address to a DNS name, use it as the normalized name.
|
// Set up a sockaddr structure
|
||||||
pEntry->buffLengthRequired = (int) strlen(dnsHostName) + 1;
|
sockAddr.sin_family = AF_INET;
|
||||||
pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired);
|
sockAddr.sin_addr.S_un.S_addr = *((int*) pLookupResult->h_addr_list[0]);
|
||||||
if (pEntry->pNormalizedHostName)
|
|
||||||
|
// Now try to resolve the name using DNS
|
||||||
|
if (getnameinfo((const struct sockaddr*) &sockAddr,
|
||||||
|
sizeof(sockAddr),
|
||||||
|
pDnsHostName,
|
||||||
|
NI_MAXHOST,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NI_NAMEREQD) == 0)
|
||||||
{
|
{
|
||||||
// Copy the dns name
|
// We resolved the address to a DNS name, use it as the normalized name.
|
||||||
strcpy(pEntry->pNormalizedHostName, dnsHostName);
|
pEntry->buffLengthRequired = (int) strlen(pDnsHostName) + 1;
|
||||||
|
pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired);
|
||||||
|
if (pEntry->pNormalizedHostName)
|
||||||
|
{
|
||||||
|
// Copy the dns name
|
||||||
|
strcpy(pEntry->pNormalizedHostName, pDnsHostName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
|
DbgTrace(0, "-NormalizeHostName- getnameInfo failed, error %d\n", WSAGetLastError());
|
||||||
|
|
||||||
|
// Not able to resolve the name in DNS, just use the host name as
|
||||||
|
// the normalized name.
|
||||||
|
pEntry->buffLengthRequired = (int) strlen(pHostName) + 1;
|
||||||
|
pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired);
|
||||||
|
if (pEntry->pNormalizedHostName)
|
||||||
|
{
|
||||||
|
// Copy the host name
|
||||||
|
strcpy(pEntry->pNormalizedHostName, pHostName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the buffer allocated to hold the DNS name
|
||||||
|
free(pDnsHostName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-NormalizeHostName- getnameInfo failed, error %d\n", WSAGetLastError());
|
DbgTrace(0, "-NormalizeHostName- Buffer allocation failure\n", 0);
|
||||||
|
|
||||||
// Not able to resolve the name in DNS, just use the host name as
|
|
||||||
// the normalized name.
|
|
||||||
pEntry->buffLengthRequired = (int) strlen(pHostName) + 1;
|
|
||||||
pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired);
|
|
||||||
if (pEntry->pNormalizedHostName)
|
|
||||||
{
|
|
||||||
// Copy the host name
|
|
||||||
strcpy(pEntry->pNormalizedHostName, pHostName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -356,10 +356,14 @@ InternalRpc(
|
|||||||
// L2
|
// L2
|
||||||
//=======================================================================--
|
//=======================================================================--
|
||||||
{
|
{
|
||||||
|
#define RPC_TARGET_FMT_STRING "CasaAuthTokenSvc/Rpc?method=%s"
|
||||||
|
|
||||||
|
#ifndef CASA_STATUS_INVALID_SERVER_CERTIFICATE
|
||||||
#define CASA_STATUS_INVALID_SERVER_CERTIFICATE CASA_STATUS_UNSUCCESSFUL // temporary until casa_status.h is updated
|
#define CASA_STATUS_INVALID_SERVER_CERTIFICATE CASA_STATUS_UNSUCCESSFUL // temporary until casa_status.h is updated
|
||||||
|
#endif
|
||||||
|
|
||||||
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
||||||
char rpcTarget[256];
|
char *pRpcTarget;
|
||||||
LPWSTR pWideRpcTarget;
|
LPWSTR pWideRpcTarget;
|
||||||
int wideRpcTargetLen;
|
int wideRpcTargetLen;
|
||||||
WCHAR sendHeaders[] = L"Content-Type: text/html";
|
WCHAR sendHeaders[] = L"Content-Type: text/html";
|
||||||
@ -373,173 +377,184 @@ InternalRpc(
|
|||||||
*ppResponseData = NULL;
|
*ppResponseData = NULL;
|
||||||
|
|
||||||
// Create rpc target string and convert it to a wide string
|
// Create rpc target string and convert it to a wide string
|
||||||
sprintf(rpcTarget, "CasaAuthTokenSvc/Rpc?method=%s", pMethod);
|
pRpcTarget = (char*) malloc(sizeof(RPC_TARGET_FMT_STRING) + strlen(pMethod));
|
||||||
retStatus = CopyMultiToWideAlloc(rpcTarget,
|
if (pRpcTarget)
|
||||||
(int) strlen(rpcTarget),
|
|
||||||
&pWideRpcTarget,
|
|
||||||
&wideRpcTargetLen);
|
|
||||||
if (CASA_SUCCESS(retStatus))
|
|
||||||
{
|
{
|
||||||
HINTERNET hRequest;
|
sprintf(pRpcTarget, RPC_TARGET_FMT_STRING, pMethod);
|
||||||
|
retStatus = CopyMultiToWideAlloc(pRpcTarget,
|
||||||
do
|
(int) strlen(pRpcTarget),
|
||||||
|
&pWideRpcTarget,
|
||||||
|
&wideRpcTargetLen);
|
||||||
|
if (CASA_SUCCESS(retStatus))
|
||||||
{
|
{
|
||||||
// Forget about having been told to retry
|
HINTERNET hRequest;
|
||||||
attemptRetry = false;
|
|
||||||
|
|
||||||
// Open a request handle
|
do
|
||||||
hRequest = WinHttpOpenRequest(pSession->hConnection,
|
|
||||||
L"POST",
|
|
||||||
pWideRpcTarget,
|
|
||||||
NULL,
|
|
||||||
WINHTTP_NO_REFERER,
|
|
||||||
WINHTTP_DEFAULT_ACCEPT_TYPES,
|
|
||||||
flags & SECURE_RPC_FLAG? WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE : WINHTTP_FLAG_REFRESH);
|
|
||||||
if (hRequest)
|
|
||||||
{
|
{
|
||||||
int reqDataLen = (int) strlen(pRequestData);
|
// Forget about having been told to retry
|
||||||
|
attemptRetry = false;
|
||||||
|
|
||||||
// Check if we need to set options to deal with secure connections
|
// Open a request handle
|
||||||
if (flags & SECURE_RPC_FLAG)
|
hRequest = WinHttpOpenRequest(pSession->hConnection,
|
||||||
{
|
L"POST",
|
||||||
// We are using secure connections, now proceed based on whether or not
|
pWideRpcTarget,
|
||||||
// we are configured to allow invalid certificates.
|
|
||||||
if (flags & ALLOW_INVALID_CERTS_RPC_FLAG
|
|
||||||
|| (flags & ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG
|
|
||||||
&& InvalidCertsFromHostAllowed(pSession->pHostName)))
|
|
||||||
{
|
|
||||||
DWORD secFlags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_UNKNOWN_CA;
|
|
||||||
|
|
||||||
// We are configured to allow invalid certificates, inform the HTTP stack.
|
|
||||||
if (WinHttpSetOption(hRequest,
|
|
||||||
WINHTTP_OPTION_SECURITY_FLAGS,
|
|
||||||
&secFlags,
|
|
||||||
sizeof(secFlags)) == FALSE)
|
|
||||||
{
|
|
||||||
DbgTrace(0, "-InternalRpc- Failed setting options to ignore invalid certs, error = %d\n", GetLastError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We are not configured to allow invalid certificates, set a callback handler
|
|
||||||
// to detect invalid certificate conditions.
|
|
||||||
if (WinHttpSetStatusCallback(hRequest,
|
|
||||||
SecureFailureStatusCallback,
|
|
||||||
WINHTTP_CALLBACK_FLAG_SECURE_FAILURE,
|
|
||||||
(DWORD_PTR) NULL) == WINHTTP_INVALID_STATUS_CALLBACK)
|
|
||||||
{
|
|
||||||
DbgTrace(0, "-InternalRpc- Failed setting status callback, error = %d\n", GetLastError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the request
|
|
||||||
securityFailureStatusFlags = 0;
|
|
||||||
if (WinHttpSendRequest(hRequest,
|
|
||||||
sendHeaders,
|
|
||||||
-1,
|
|
||||||
pRequestData,
|
|
||||||
reqDataLen,
|
|
||||||
reqDataLen,
|
|
||||||
(DWORD_PTR) &securityFailureStatusFlags))
|
|
||||||
{
|
|
||||||
// Request sent, now await for the response.
|
|
||||||
if (WinHttpReceiveResponse(hRequest, NULL))
|
|
||||||
{
|
|
||||||
WCHAR httpCompStatus[4] = {0};
|
|
||||||
DWORD httpCompStatusLen = sizeof(httpCompStatus);
|
|
||||||
|
|
||||||
// Response received, make sure that it completed successfully.
|
|
||||||
if (WinHttpQueryHeaders(hRequest,
|
|
||||||
WINHTTP_QUERY_STATUS_CODE,
|
|
||||||
NULL,
|
NULL,
|
||||||
&httpCompStatus,
|
WINHTTP_NO_REFERER,
|
||||||
&httpCompStatusLen,
|
WINHTTP_DEFAULT_ACCEPT_TYPES,
|
||||||
WINHTTP_NO_HEADER_INDEX))
|
flags & SECURE_RPC_FLAG? WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE : WINHTTP_FLAG_REFRESH);
|
||||||
|
if (hRequest)
|
||||||
|
{
|
||||||
|
int reqDataLen = (int) strlen(pRequestData);
|
||||||
|
|
||||||
|
// Check if we need to set options to deal with secure connections
|
||||||
|
if (flags & SECURE_RPC_FLAG)
|
||||||
|
{
|
||||||
|
// We are using secure connections, now proceed based on whether or not
|
||||||
|
// we are configured to allow invalid certificates.
|
||||||
|
if (flags & ALLOW_INVALID_CERTS_RPC_FLAG
|
||||||
|
|| (flags & ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG
|
||||||
|
&& InvalidCertsFromHostAllowed(pSession->pHostName)))
|
||||||
{
|
{
|
||||||
// Check that the request completed successfully
|
DWORD secFlags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_UNKNOWN_CA;
|
||||||
if (memcmp(httpCompStatus, L"200", sizeof(httpCompStatus)) == 0)
|
|
||||||
|
// We are configured to allow invalid certificates, inform the HTTP stack.
|
||||||
|
if (WinHttpSetOption(hRequest,
|
||||||
|
WINHTTP_OPTION_SECURITY_FLAGS,
|
||||||
|
&secFlags,
|
||||||
|
sizeof(secFlags)) == FALSE)
|
||||||
{
|
{
|
||||||
char *pResponseData;
|
DbgTrace(0, "-InternalRpc- Failed setting options to ignore invalid certs, error = %d\n", GetLastError());
|
||||||
int responseDataBufSize = INITIAL_RESPONSE_DATA_BUF_SIZE;
|
}
|
||||||
int responseDataRead = 0;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We are not configured to allow invalid certificates, set a callback handler
|
||||||
|
// to detect invalid certificate conditions.
|
||||||
|
if (WinHttpSetStatusCallback(hRequest,
|
||||||
|
SecureFailureStatusCallback,
|
||||||
|
WINHTTP_CALLBACK_FLAG_SECURE_FAILURE,
|
||||||
|
(DWORD_PTR) NULL) == WINHTTP_INVALID_STATUS_CALLBACK)
|
||||||
|
{
|
||||||
|
DbgTrace(0, "-InternalRpc- Failed setting status callback, error = %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Now read the response data, to do so we need to allocate a buffer.
|
// Send the request
|
||||||
pResponseData = (char*) malloc(INITIAL_RESPONSE_DATA_BUF_SIZE);
|
securityFailureStatusFlags = 0;
|
||||||
if (pResponseData)
|
if (WinHttpSendRequest(hRequest,
|
||||||
|
sendHeaders,
|
||||||
|
-1,
|
||||||
|
pRequestData,
|
||||||
|
reqDataLen,
|
||||||
|
reqDataLen,
|
||||||
|
(DWORD_PTR) &securityFailureStatusFlags))
|
||||||
|
{
|
||||||
|
// Request sent, now await for the response.
|
||||||
|
if (WinHttpReceiveResponse(hRequest, NULL))
|
||||||
|
{
|
||||||
|
WCHAR httpCompStatus[4] = {0};
|
||||||
|
DWORD httpCompStatusLen = sizeof(httpCompStatus);
|
||||||
|
|
||||||
|
// Response received, make sure that it completed successfully.
|
||||||
|
if (WinHttpQueryHeaders(hRequest,
|
||||||
|
WINHTTP_QUERY_STATUS_CODE,
|
||||||
|
NULL,
|
||||||
|
&httpCompStatus,
|
||||||
|
&httpCompStatusLen,
|
||||||
|
WINHTTP_NO_HEADER_INDEX))
|
||||||
|
{
|
||||||
|
// Check that the request completed successfully
|
||||||
|
if (memcmp(httpCompStatus, L"200", sizeof(httpCompStatus)) == 0)
|
||||||
{
|
{
|
||||||
char *pCurrLocation = pResponseData;
|
char *pResponseData;
|
||||||
DWORD bytesRead;
|
int responseDataBufSize = INITIAL_RESPONSE_DATA_BUF_SIZE;
|
||||||
|
int responseDataRead = 0;
|
||||||
|
|
||||||
do
|
// Now read the response data, to do so we need to allocate a buffer.
|
||||||
|
pResponseData = (char*) malloc(INITIAL_RESPONSE_DATA_BUF_SIZE);
|
||||||
|
if (pResponseData)
|
||||||
{
|
{
|
||||||
bytesRead = 0;
|
char *pCurrLocation = pResponseData;
|
||||||
if (WinHttpReadData(hRequest,
|
DWORD bytesRead;
|
||||||
(LPVOID) pCurrLocation,
|
|
||||||
responseDataBufSize - responseDataRead,
|
do
|
||||||
&bytesRead))
|
|
||||||
{
|
{
|
||||||
pCurrLocation += bytesRead;
|
bytesRead = 0;
|
||||||
responseDataRead += bytesRead;
|
if (WinHttpReadData(hRequest,
|
||||||
|
(LPVOID) pCurrLocation,
|
||||||
// Check if we need to allocate a larger buffer
|
responseDataBufSize - responseDataRead,
|
||||||
if (responseDataRead == responseDataBufSize)
|
&bytesRead))
|
||||||
{
|
{
|
||||||
char *pTmpBuf;
|
pCurrLocation += bytesRead;
|
||||||
|
responseDataRead += bytesRead;
|
||||||
|
|
||||||
// We need to upgrade the receive buffer
|
// Check if we need to allocate a larger buffer
|
||||||
pTmpBuf = (char*) malloc(responseDataBufSize + INCREMENT_RESPONSE_DATA_BUF_SIZE);
|
if (responseDataRead == responseDataBufSize)
|
||||||
if (pTmpBuf)
|
|
||||||
{
|
{
|
||||||
memcpy(pTmpBuf, pResponseData, responseDataBufSize);
|
char *pTmpBuf;
|
||||||
free(pResponseData);
|
|
||||||
pResponseData = pTmpBuf;
|
// We need to upgrade the receive buffer
|
||||||
pCurrLocation = pResponseData + responseDataBufSize;
|
pTmpBuf = (char*) malloc(responseDataBufSize + INCREMENT_RESPONSE_DATA_BUF_SIZE);
|
||||||
responseDataBufSize += INCREMENT_RESPONSE_DATA_BUF_SIZE;
|
if (pTmpBuf)
|
||||||
}
|
{
|
||||||
else
|
memcpy(pTmpBuf, pResponseData, responseDataBufSize);
|
||||||
{
|
free(pResponseData);
|
||||||
DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0);
|
pResponseData = pTmpBuf;
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
pCurrLocation = pResponseData + responseDataBufSize;
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
responseDataBufSize += INCREMENT_RESPONSE_DATA_BUF_SIZE;
|
||||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0);
|
||||||
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbgTrace(0, "-InternalRpc- Failed reading response data, error = %d\n", GetLastError());
|
||||||
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
} while (CASA_SUCCESS(retStatus)
|
||||||
|
&& bytesRead != 0);
|
||||||
|
|
||||||
|
// Check if the response data was successfully received
|
||||||
|
if (CASA_SUCCESS(retStatus))
|
||||||
|
{
|
||||||
|
// The response data was received, return it to the caller.
|
||||||
|
*ppResponseData = pResponseData;
|
||||||
|
*pResponseDataLen = responseDataRead;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-InternalRpc- Failed reading response data, error = %d\n", GetLastError());
|
// Failed to receive the response data, free the allocated buffer.
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
free(pResponseData);
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
}
|
||||||
} while (CASA_SUCCESS(retStatus)
|
|
||||||
&& bytesRead != 0);
|
|
||||||
|
|
||||||
// Check if the response data was successfully received
|
|
||||||
if (CASA_SUCCESS(retStatus))
|
|
||||||
{
|
|
||||||
// The response data was received, return it to the caller.
|
|
||||||
*ppResponseData = pResponseData;
|
|
||||||
*pResponseDataLen = responseDataRead;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Failed to receive the response data, free the allocated buffer.
|
DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0);
|
||||||
free(pResponseData);
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0);
|
DbgTrace(0, "-InternalRpc- HTTP request did not complete successfully, status = %S\n", httpCompStatus);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-InternalRpc- HTTP request did not complete successfully, status = %S\n", httpCompStatus);
|
DbgTrace(0, "-InternalRpc- Unable to obtain http request completion status, error = %d\n", GetLastError());
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
@ -547,7 +562,7 @@ InternalRpc(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-InternalRpc- Unable to obtain http request completion status, error = %d\n", GetLastError());
|
DbgTrace(0, "-InternalRpc- Unable to receive response, error = %d\n", GetLastError());
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
@ -555,160 +570,163 @@ InternalRpc(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-InternalRpc- Unable to receive response, error = %d\n", GetLastError());
|
int error = GetLastError();
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int error = GetLastError();
|
|
||||||
|
|
||||||
if (error == ERROR_WINHTTP_CANNOT_CONNECT)
|
if (error == ERROR_WINHTTP_CANNOT_CONNECT)
|
||||||
{
|
|
||||||
DbgTrace(0, "-InternalRpc- Unable to connect to server\n", 0);
|
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
|
||||||
CASA_STATUS_AUTH_SERVER_UNAVAILABLE);
|
|
||||||
}
|
|
||||||
else if (error == ERROR_WINHTTP_SECURE_FAILURE)
|
|
||||||
{
|
|
||||||
DbgTrace(1, "-InternalRpc- Secure connection failure, flags = %0x\n", securityFailureStatusFlags);
|
|
||||||
|
|
||||||
// Try to deal with the issue
|
|
||||||
if ((securityFailureStatusFlags & ~(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA
|
|
||||||
| WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID
|
|
||||||
| WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)) == 0
|
|
||||||
&& flags & ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG)
|
|
||||||
{
|
{
|
||||||
WINHTTP_CERTIFICATE_INFO certInfo;
|
DbgTrace(0, "-InternalRpc- Unable to connect to server\n", 0);
|
||||||
DWORD certInfoLen = sizeof(certInfo);
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
|
CASA_STATUS_AUTH_SERVER_UNAVAILABLE);
|
||||||
|
}
|
||||||
|
else if (error == ERROR_WINHTTP_SECURE_FAILURE)
|
||||||
|
{
|
||||||
|
DbgTrace(1, "-InternalRpc- Secure connection failure, flags = %0x\n", securityFailureStatusFlags);
|
||||||
|
|
||||||
// The failure was due to an invalid CN, CA, or both.
|
// Try to deal with the issue
|
||||||
//
|
if ((securityFailureStatusFlags & ~(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA
|
||||||
// Obtain information about the server certificate to give user
|
| WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID
|
||||||
// the choice of accepting it.
|
| WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)) == 0
|
||||||
if (WinHttpQueryOption(hRequest,
|
&& flags & ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG)
|
||||||
WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT,
|
|
||||||
&certInfo,
|
|
||||||
&certInfoLen)
|
|
||||||
&& certInfo.lpszSubjectInfo != NULL
|
|
||||||
&& certInfo.lpszIssuerInfo != NULL)
|
|
||||||
{
|
{
|
||||||
char *pSubjectInfo;
|
WINHTTP_CERTIFICATE_INFO certInfo;
|
||||||
int subjectInfoLen;
|
DWORD certInfoLen = sizeof(certInfo);
|
||||||
|
|
||||||
// Convert the subjectInfo to multi-byte
|
// The failure was due to an invalid CN, CA, or both.
|
||||||
retStatus = CopyWideToMultiAlloc(certInfo.lpszSubjectInfo,
|
//
|
||||||
(int) wcslen(certInfo.lpszSubjectInfo),
|
// Obtain information about the server certificate to give user
|
||||||
&pSubjectInfo,
|
// the choice of accepting it.
|
||||||
&subjectInfoLen);
|
if (WinHttpQueryOption(hRequest,
|
||||||
if (CASA_SUCCESS(retStatus))
|
WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT,
|
||||||
|
&certInfo,
|
||||||
|
&certInfoLen)
|
||||||
|
&& certInfo.lpszSubjectInfo != NULL
|
||||||
|
&& certInfo.lpszIssuerInfo != NULL)
|
||||||
{
|
{
|
||||||
char *pIssuerInfo;
|
char *pSubjectInfo;
|
||||||
int issuerInfoLen;
|
int subjectInfoLen;
|
||||||
|
|
||||||
// Convert the issuerInfo to multi-byte
|
// Convert the subjectInfo to multi-byte
|
||||||
retStatus = CopyWideToMultiAlloc(certInfo.lpszIssuerInfo,
|
retStatus = CopyWideToMultiAlloc(certInfo.lpszSubjectInfo,
|
||||||
(int) wcslen(certInfo.lpszIssuerInfo),
|
(int) wcslen(certInfo.lpszSubjectInfo),
|
||||||
&pIssuerInfo,
|
&pSubjectInfo,
|
||||||
&issuerInfoLen);
|
&subjectInfoLen);
|
||||||
if (CASA_SUCCESS(retStatus))
|
if (CASA_SUCCESS(retStatus))
|
||||||
{
|
{
|
||||||
long invalidCertFlags = 0;
|
char *pIssuerInfo;
|
||||||
|
int issuerInfoLen;
|
||||||
|
|
||||||
// Setup the invalid cert flags
|
// Convert the issuerInfo to multi-byte
|
||||||
if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
|
retStatus = CopyWideToMultiAlloc(certInfo.lpszIssuerInfo,
|
||||||
invalidCertFlags |= INVALID_CERT_CA_FLAG;
|
(int) wcslen(certInfo.lpszIssuerInfo),
|
||||||
|
&pIssuerInfo,
|
||||||
if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
|
&issuerInfoLen);
|
||||||
invalidCertFlags |= INVALID_CERT_CN_FLAG;
|
if (CASA_SUCCESS(retStatus))
|
||||||
|
|
||||||
if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)
|
|
||||||
invalidCertFlags |= INVALID_CERT_DATE_FLAG;
|
|
||||||
|
|
||||||
// Give user the choice to accept the certificate
|
|
||||||
if (UserApprovedCert(pSession->pHostName,
|
|
||||||
pSubjectInfo,
|
|
||||||
pIssuerInfo,
|
|
||||||
invalidCertFlags))
|
|
||||||
{
|
{
|
||||||
DbgTrace(1, "-InternalRpc- User approved invalid certificate from %s\n", pSession->pHostName);
|
long invalidCertFlags = 0;
|
||||||
|
|
||||||
// tbd - Investigate if there is a way to set the accepted certificate in a store so that
|
// Setup the invalid cert flags
|
||||||
// it can be utilized by the SSL stack directly. This would be a better method for dealing with
|
if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
|
||||||
// this issue.
|
invalidCertFlags |= INVALID_CERT_CA_FLAG;
|
||||||
|
|
||||||
AllowInvalidCertsFromHost(pSession->pHostName);
|
if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
|
||||||
|
invalidCertFlags |= INVALID_CERT_CN_FLAG;
|
||||||
|
|
||||||
// Try to retry the request
|
if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)
|
||||||
attemptRetry = true;
|
invalidCertFlags |= INVALID_CERT_DATE_FLAG;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DbgTrace(1, "-InternalRpc- User did not approve invalid certificate from %s\n", pSession->pHostName);
|
|
||||||
|
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
// Give user the choice to accept the certificate
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
if (UserApprovedCert(pSession->pHostName,
|
||||||
CASA_STATUS_INVALID_SERVER_CERTIFICATE);
|
pSubjectInfo,
|
||||||
|
pIssuerInfo,
|
||||||
|
invalidCertFlags))
|
||||||
|
{
|
||||||
|
DbgTrace(1, "-InternalRpc- User approved invalid certificate from %s\n", pSession->pHostName);
|
||||||
|
|
||||||
|
// tbd - Investigate if there is a way to set the accepted certificate in a store so that
|
||||||
|
// it can be utilized by the SSL stack directly. This would be a better method for dealing with
|
||||||
|
// this issue.
|
||||||
|
|
||||||
|
AllowInvalidCertsFromHost(pSession->pHostName);
|
||||||
|
|
||||||
|
// Try to retry the request
|
||||||
|
attemptRetry = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbgTrace(1, "-InternalRpc- User did not approve invalid certificate from %s\n", pSession->pHostName);
|
||||||
|
|
||||||
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
|
CASA_STATUS_INVALID_SERVER_CERTIFICATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the buffer containing the issuerInfo
|
||||||
|
free(pIssuerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the buffer containing the issuerInfo
|
// Free the buffer containing the subjectInfo
|
||||||
free(pIssuerInfo);
|
free(pSubjectInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the buffer containing the subjectInfo
|
// Free necessary certificate information
|
||||||
free(pSubjectInfo);
|
if (certInfo.lpszSubjectInfo) LocalFree(certInfo.lpszSubjectInfo);
|
||||||
|
if (certInfo.lpszIssuerInfo) LocalFree(certInfo.lpszIssuerInfo);
|
||||||
|
if (certInfo.lpszProtocolName) LocalFree(certInfo.lpszProtocolName);
|
||||||
|
if (certInfo.lpszSignatureAlgName) LocalFree(certInfo.lpszSignatureAlgName);
|
||||||
|
if (certInfo.lpszEncryptionAlgName) LocalFree(certInfo.lpszEncryptionAlgName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbgTrace(0, "-InternalRpc- Unable to obtain server certificate struct, error = %0x\n", GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free necessary certificate information
|
|
||||||
if (certInfo.lpszSubjectInfo) LocalFree(certInfo.lpszSubjectInfo);
|
|
||||||
if (certInfo.lpszIssuerInfo) LocalFree(certInfo.lpszIssuerInfo);
|
|
||||||
if (certInfo.lpszProtocolName) LocalFree(certInfo.lpszProtocolName);
|
|
||||||
if (certInfo.lpszSignatureAlgName) LocalFree(certInfo.lpszSignatureAlgName);
|
|
||||||
if (certInfo.lpszEncryptionAlgName) LocalFree(certInfo.lpszEncryptionAlgName);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-InternalRpc- Unable to obtain server certificate struct, error = %0x\n", GetLastError());
|
// Decided to no give the user a choice to accept invalid server certificate
|
||||||
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
|
CASA_STATUS_INVALID_SERVER_CERTIFICATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Decided to no give the user a choice to accept invalid server certificate
|
DbgTrace(0, "-InternalRpc- Unsuccessful send http request, error = %d\n", error);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
CASA_STATUS_INVALID_SERVER_CERTIFICATE);
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
// Close the request handle
|
||||||
DbgTrace(0, "-InternalRpc- Unsuccessful send http request, error = %d\n", error);
|
WinHttpCloseHandle(hRequest);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbgTrace(0, "-InternalRpc- Unable to open http request, error = %d\n", GetLastError());
|
||||||
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
|
CASA_STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
} while (attemptRetry && retriesAllowed--);
|
||||||
|
|
||||||
// Close the request handle
|
// Free the rpc target wide string buffer
|
||||||
WinHttpCloseHandle(hRequest);
|
free(pWideRpcTarget);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-InternalRpc- Unable to open http request, error = %d\n", GetLastError());
|
DbgTrace(0, "-InternalRpc- Error converting method name to wide string\n", 0);
|
||||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
}
|
||||||
CASA_FACILITY_AUTHTOKEN,
|
|
||||||
CASA_STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
} while (attemptRetry && retriesAllowed--);
|
|
||||||
|
|
||||||
// Free the rpc target wide string buffer
|
// Free buffer used to hold the rpc target string
|
||||||
free(pWideRpcTarget);
|
free(pRpcTarget);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgTrace(0, "-InternalRpc- Error converting method name to wide string\n", 0);
|
DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0);
|
||||||
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||||
|
CASA_FACILITY_AUTHTOKEN,
|
||||||
|
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgTrace(1, "-InternalRpc- End, retStatus = %d\n", retStatus);
|
DbgTrace(1, "-InternalRpc- End, retStatus = %d\n", retStatus);
|
||||||
|
Loading…
Reference in New Issue
Block a user