CASA-auth-token-client: rename lib directory to library and change in makefile
This commit is contained in:
817
CASA-auth-token/client/library/windows/rpc.c
Normal file
817
CASA-auth-token/client/library/windows/rpc.c
Normal file
@@ -0,0 +1,817 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 INITIAL_RESPONSE_DATA_BUF_SIZE 1028
|
||||
#define INCREMENT_RESPONSE_DATA_BUF_SIZE 256
|
||||
|
||||
#define MAX_RPC_RETRIES 3
|
||||
|
||||
//===[ Function prototypes ]===============================================
|
||||
|
||||
//===[ Global variables ]==================================================
|
||||
|
||||
//++=======================================================================
|
||||
static
|
||||
CasaStatus
|
||||
CopyMultiToWideAlloc(
|
||||
IN char *pMulti,
|
||||
IN int multiSize,
|
||||
INOUT LPWSTR *ppWide,
|
||||
INOUT int *pWideSize)
|
||||
//
|
||||
// Arguments:
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// Abstract:
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
int retStatus;
|
||||
int size, i;
|
||||
|
||||
DbgTrace(2, "-CopyMultiToWideAlloc- Start\n", 0);
|
||||
|
||||
size = (multiSize + 1) * sizeof(WCHAR);
|
||||
|
||||
if ((*ppWide = (PWCHAR) malloc(size)) != NULL)
|
||||
{
|
||||
for (i = 0; i < multiSize; i++)
|
||||
{
|
||||
*(*ppWide + i) = (unsigned char) *(pMulti + i);
|
||||
}
|
||||
|
||||
*(*ppWide + i) = L'\0';
|
||||
|
||||
if (pWideSize)
|
||||
{
|
||||
*pWideSize = size - sizeof(WCHAR);
|
||||
}
|
||||
|
||||
retStatus = CASA_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||
CASA_FACILITY_AUTHTOKEN,
|
||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
DbgTrace(2, "-CopyMultiToWideAlloc- End, retStatus = %08X\n", retStatus);
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
static
|
||||
CasaStatus
|
||||
CopyWideToMultiAlloc(
|
||||
IN LPWSTR pWide,
|
||||
IN int wideSize,
|
||||
INOUT char **ppMulti,
|
||||
INOUT int *pMultiSize)
|
||||
//
|
||||
// Arguments:
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// Abstract:
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
int retStatus;
|
||||
int size, i;
|
||||
|
||||
DbgTrace(2, "-CopyWideToMultiAlloc- Start\n", 0);
|
||||
|
||||
size = wideSize + 1;
|
||||
|
||||
if ((*ppMulti = malloc(size)) != NULL)
|
||||
{
|
||||
for (i = 0; i < wideSize; i++)
|
||||
{
|
||||
*(*ppMulti + i) = (char) *(pWide + i);
|
||||
}
|
||||
|
||||
*(*ppMulti + i) = '\0';
|
||||
|
||||
if (pMultiSize)
|
||||
{
|
||||
*pMultiSize = size - 1;
|
||||
}
|
||||
|
||||
retStatus = CASA_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||
CASA_FACILITY_AUTHTOKEN,
|
||||
CASA_STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
DbgTrace(2, "-CopyWideToMultiAlloc- End, retStatus = %08X\n", retStatus);
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
RpcSession*
|
||||
OpenRpcSession(
|
||||
IN char *pHostName,
|
||||
IN uint16_t hostPort)
|
||||
//
|
||||
// Arguments:
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// Abstract:
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
RpcSession *pSession;
|
||||
bool success = false;
|
||||
|
||||
DbgTrace(1, "-OpenRpcSession- Start\n", 0);
|
||||
|
||||
// Allocate space for the session
|
||||
pSession = (RpcSession*) malloc(sizeof(*pSession));
|
||||
if (pSession)
|
||||
{
|
||||
// Zero the session structure
|
||||
memset(pSession, 0, sizeof(*pSession));
|
||||
|
||||
// Save copy of the hostname
|
||||
pSession->pHostName = malloc(strlen(pHostName) + 1);
|
||||
if (pSession->pHostName)
|
||||
{
|
||||
strcpy(pSession->pHostName, pHostName);
|
||||
|
||||
// Open a Winhttp session
|
||||
pSession->hSession = WinHttpOpen(L"CASA Client/1.0",
|
||||
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
||||
WINHTTP_NO_PROXY_NAME,
|
||||
WINHTTP_NO_PROXY_BYPASS,
|
||||
0);
|
||||
if (pSession->hSession)
|
||||
{
|
||||
LPWSTR pWideHostName;
|
||||
int wideHostLen;
|
||||
|
||||
// Session opened, now convert the host name to Unicode so that
|
||||
// we can open a connection.
|
||||
if (CopyMultiToWideAlloc(pHostName,
|
||||
(int) strlen(pHostName),
|
||||
&pWideHostName,
|
||||
&wideHostLen) == CASA_STATUS_SUCCESS)
|
||||
{
|
||||
// Now open connection
|
||||
pSession->hConnection = WinHttpConnect(pSession->hSession,
|
||||
pWideHostName,
|
||||
hostPort,
|
||||
0);
|
||||
if (pSession->hConnection == NULL)
|
||||
{
|
||||
DbgTrace(0, "-OpenRpcSession- Failed to open connection, error = %d\n", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
|
||||
// Free the host name wide string buffer
|
||||
free(pWideHostName);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "-OpenRpcSession- Error converting host name to wide string\n", 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "-OpenRpcSession- Failed to open session, error = %d\n", GetLastError());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for host name\n", 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for rpc session\n", 0);
|
||||
}
|
||||
|
||||
// Clean up if we did not succeed
|
||||
if (!success)
|
||||
{
|
||||
if (pSession)
|
||||
{
|
||||
if (pSession->hConnection)
|
||||
WinHttpCloseHandle(pSession->hConnection);
|
||||
|
||||
if (pSession->hSession)
|
||||
WinHttpCloseHandle(pSession->hSession);
|
||||
|
||||
if (pSession->pHostName)
|
||||
free(pSession->pHostName);
|
||||
|
||||
free(pSession);
|
||||
pSession = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DbgTrace(2, "-OpenRpcSession- End, pSession = %08X\n", pSession);
|
||||
|
||||
return pSession;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
void
|
||||
CloseRpcSession(
|
||||
IN RpcSession *pSession)
|
||||
//
|
||||
// Arguments:
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// Abstract:
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
DbgTrace(1, "-CloseRpcSession- Start\n", 0);
|
||||
|
||||
// Close the connection handle
|
||||
WinHttpCloseHandle(pSession->hConnection);
|
||||
|
||||
// Close the session handle
|
||||
WinHttpCloseHandle(pSession->hSession);
|
||||
|
||||
// Free hostname buffer if necessary
|
||||
if (pSession->pHostName)
|
||||
free(pSession->pHostName);
|
||||
|
||||
// Free the space allocated for the session
|
||||
free(pSession);
|
||||
|
||||
DbgTrace(1, "-CloseRpcSession- End\n", 0);
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
static
|
||||
void CALLBACK
|
||||
SecureFailureStatusCallback(
|
||||
IN HINTERNET hRequest,
|
||||
IN DWORD *pContext,
|
||||
IN DWORD internetStatus,
|
||||
IN LPVOID pStatusInformation,
|
||||
IN DWORD statusInformationLength)
|
||||
//
|
||||
// Arguments:
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// Abstract:
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// L0
|
||||
//=======================================================================--
|
||||
{
|
||||
DbgTrace(1, "-SecureFailureStatusCallback- Start\n", 0);
|
||||
|
||||
// Only deal with failures related to certificates
|
||||
if (internetStatus == WINHTTP_CALLBACK_STATUS_SECURE_FAILURE)
|
||||
{
|
||||
// Save the specific failure status
|
||||
*pContext = *(DWORD*) pStatusInformation;
|
||||
}
|
||||
|
||||
DbgTrace(1, "-SecureFailureStatusCallback- End\n", 0);
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
static
|
||||
CasaStatus
|
||||
InternalRpc(
|
||||
IN RpcSession *pSession,
|
||||
IN char *pMethod,
|
||||
IN long flags,
|
||||
IN char *pRequestData,
|
||||
INOUT char **ppResponseData,
|
||||
INOUT int *pResponseDataLen)
|
||||
//
|
||||
// Arguments:
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// Abstract:
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// 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
|
||||
#endif
|
||||
|
||||
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
||||
char *pRpcTarget;
|
||||
LPWSTR pWideRpcTarget;
|
||||
int wideRpcTargetLen;
|
||||
WCHAR sendHeaders[] = L"Content-Type: text/html";
|
||||
DWORD securityFailureStatusFlags;
|
||||
int retriesAllowed = 1;
|
||||
bool attemptRetry;
|
||||
|
||||
DbgTrace(1, "-InternalRpc- Start\n", 0);
|
||||
|
||||
// Initialize output parameter
|
||||
*ppResponseData = NULL;
|
||||
|
||||
// Create rpc target string and convert it to a wide string
|
||||
pRpcTarget = (char*) malloc(sizeof(RPC_TARGET_FMT_STRING) + strlen(pMethod));
|
||||
if (pRpcTarget)
|
||||
{
|
||||
sprintf(pRpcTarget, RPC_TARGET_FMT_STRING, pMethod);
|
||||
retStatus = CopyMultiToWideAlloc(pRpcTarget,
|
||||
(int) strlen(pRpcTarget),
|
||||
&pWideRpcTarget,
|
||||
&wideRpcTargetLen);
|
||||
if (CASA_SUCCESS(retStatus))
|
||||
{
|
||||
HINTERNET hRequest;
|
||||
|
||||
do
|
||||
{
|
||||
// Forget about having been told to retry
|
||||
attemptRetry = false;
|
||||
|
||||
// Open a request handle
|
||||
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);
|
||||
|
||||
// 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)))
|
||||
{
|
||||
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,
|
||||
&httpCompStatus,
|
||||
&httpCompStatusLen,
|
||||
WINHTTP_NO_HEADER_INDEX))
|
||||
{
|
||||
// Check that the request completed successfully
|
||||
if (memcmp(httpCompStatus, L"200", sizeof(httpCompStatus)) == 0)
|
||||
{
|
||||
char *pResponseData;
|
||||
int responseDataBufSize = INITIAL_RESPONSE_DATA_BUF_SIZE;
|
||||
int responseDataRead = 0;
|
||||
|
||||
// Now read the response data, to do so we need to allocate a buffer.
|
||||
pResponseData = (char*) malloc(INITIAL_RESPONSE_DATA_BUF_SIZE);
|
||||
if (pResponseData)
|
||||
{
|
||||
char *pCurrLocation = pResponseData;
|
||||
DWORD bytesRead;
|
||||
|
||||
do
|
||||
{
|
||||
bytesRead = 0;
|
||||
if (WinHttpReadData(hRequest,
|
||||
(LPVOID) pCurrLocation,
|
||||
responseDataBufSize - responseDataRead,
|
||||
&bytesRead))
|
||||
{
|
||||
pCurrLocation += bytesRead;
|
||||
responseDataRead += bytesRead;
|
||||
|
||||
// Check if we need to allocate a larger buffer
|
||||
if (responseDataRead == responseDataBufSize)
|
||||
{
|
||||
char *pTmpBuf;
|
||||
|
||||
// We need to upgrade the receive buffer
|
||||
pTmpBuf = (char*) malloc(responseDataBufSize + INCREMENT_RESPONSE_DATA_BUF_SIZE);
|
||||
if (pTmpBuf)
|
||||
{
|
||||
memcpy(pTmpBuf, pResponseData, responseDataBufSize);
|
||||
free(pResponseData);
|
||||
pResponseData = pTmpBuf;
|
||||
pCurrLocation = pResponseData + responseDataBufSize;
|
||||
responseDataBufSize += INCREMENT_RESPONSE_DATA_BUF_SIZE;
|
||||
}
|
||||
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
|
||||
{
|
||||
// Failed to receive the response data, free the allocated buffer.
|
||||
free(pResponseData);
|
||||
}
|
||||
}
|
||||
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- HTTP request did not complete successfully, status = %S\n", httpCompStatus);
|
||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||
CASA_FACILITY_AUTHTOKEN,
|
||||
CASA_STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "-InternalRpc- Unable to obtain http request completion status, error = %d\n", GetLastError());
|
||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||
CASA_FACILITY_AUTHTOKEN,
|
||||
CASA_STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "-InternalRpc- Unable to receive response, error = %d\n", GetLastError());
|
||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||
CASA_FACILITY_AUTHTOKEN,
|
||||
CASA_STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int error = GetLastError();
|
||||
|
||||
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;
|
||||
DWORD certInfoLen = sizeof(certInfo);
|
||||
|
||||
// The failure was due to an invalid CN, CA, or both.
|
||||
//
|
||||
// Obtain information about the server certificate to give user
|
||||
// the choice of accepting it.
|
||||
if (WinHttpQueryOption(hRequest,
|
||||
WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT,
|
||||
&certInfo,
|
||||
&certInfoLen)
|
||||
&& certInfo.lpszSubjectInfo != NULL
|
||||
&& certInfo.lpszIssuerInfo != NULL)
|
||||
{
|
||||
char *pSubjectInfo;
|
||||
int subjectInfoLen;
|
||||
|
||||
// Convert the subjectInfo to multi-byte
|
||||
retStatus = CopyWideToMultiAlloc(certInfo.lpszSubjectInfo,
|
||||
(int) wcslen(certInfo.lpszSubjectInfo),
|
||||
&pSubjectInfo,
|
||||
&subjectInfoLen);
|
||||
if (CASA_SUCCESS(retStatus))
|
||||
{
|
||||
char *pIssuerInfo;
|
||||
int issuerInfoLen;
|
||||
|
||||
// Convert the issuerInfo to multi-byte
|
||||
retStatus = CopyWideToMultiAlloc(certInfo.lpszIssuerInfo,
|
||||
(int) wcslen(certInfo.lpszIssuerInfo),
|
||||
&pIssuerInfo,
|
||||
&issuerInfoLen);
|
||||
if (CASA_SUCCESS(retStatus))
|
||||
{
|
||||
long invalidCertFlags = 0;
|
||||
|
||||
// Setup the invalid cert flags
|
||||
if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
|
||||
invalidCertFlags |= INVALID_CERT_CA_FLAG;
|
||||
|
||||
if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
|
||||
invalidCertFlags |= INVALID_CERT_CN_FLAG;
|
||||
|
||||
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);
|
||||
|
||||
// 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 subjectInfo
|
||||
free(pSubjectInfo);
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
DbgTrace(0, "-InternalRpc- Unable to obtain server certificate struct, error = %0x\n", GetLastError());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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
|
||||
{
|
||||
DbgTrace(0, "-InternalRpc- Unsuccessful send http request, error = %d\n", error);
|
||||
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
||||
CASA_FACILITY_AUTHTOKEN,
|
||||
CASA_STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
}
|
||||
|
||||
// Close the request handle
|
||||
WinHttpCloseHandle(hRequest);
|
||||
}
|
||||
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--);
|
||||
|
||||
// Free the rpc target wide string buffer
|
||||
free(pWideRpcTarget);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "-InternalRpc- Error converting method name to wide string\n", 0);
|
||||
}
|
||||
|
||||
// Free buffer used to hold the rpc target string
|
||||
free(pRpcTarget);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
CasaStatus
|
||||
Rpc(
|
||||
IN RpcSession *pSession,
|
||||
IN char *pMethod,
|
||||
IN long flags,
|
||||
IN char *pRequestData,
|
||||
INOUT char **ppResponseData,
|
||||
INOUT int *pResponseDataLen)
|
||||
//
|
||||
// Arguments:
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// Abstract:
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
CasaStatus retStatus;
|
||||
int retries = 0;
|
||||
|
||||
DbgTrace(1, "-Rpc- Start\n", 0);
|
||||
|
||||
// Retry the RPC as needed
|
||||
do
|
||||
{
|
||||
// Issue the RPC
|
||||
retStatus = InternalRpc(pSession,
|
||||
pMethod,
|
||||
flags,
|
||||
pRequestData,
|
||||
ppResponseData,
|
||||
pResponseDataLen);
|
||||
|
||||
// Account for this try
|
||||
retries ++;
|
||||
|
||||
} while (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE
|
||||
&& retries < MAX_RPC_RETRIES);
|
||||
|
||||
DbgTrace(1, "-Rpc- End, retStatus = %d\n", retStatus);
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
CasaStatus
|
||||
InitializeRpc(void)
|
||||
//
|
||||
// Arguments:
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// Abstract:
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
CasaStatus retStatus = CASA_STATUS_SUCCESS;
|
||||
|
||||
DbgTrace(1, "-InitializeRpc- Start\n", 0);
|
||||
|
||||
// Nothing to do for windows
|
||||
|
||||
DbgTrace(1, "-InitializeRpc- End, retStatus = %08X\n", retStatus);
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
Reference in New Issue
Block a user