Made modifications to switch the client to communicate with ATSs over SSL. Still need to make changes to the linux rpc.c to have all of the necessary changes completed.

Also made a fix to allow credential store scoping all the way into the authentication mechanisms.
This commit is contained in:
Juan Carlos Luciani
2006-11-02 03:49:16 +00:00
parent 920c9c5dff
commit c99e319a3a
16 changed files with 814 additions and 256 deletions

View File

@@ -7,4 +7,5 @@ EXPORTS
; DllUnregisterServer PRIVATE
; DllGetClassObject PRIVATE
ObtainAuthToken PRIVATE
ObtainAuthTokenEx PRIVATE
; DllCanUnloadNow PRIVATE

View File

@@ -21,7 +21,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/D "XML_STATIC""
Optimization="0"
AdditionalIncludeDirectories=".;..\;..\..\include;"C:\Dev\casa\CASA-auth-token\non-java\include\windows";"\Program Files\novell\casa\include";"C:\Dev\Expat-2.0.0\Source\lib""
AdditionalIncludeDirectories=".;..\;..\..\include;..\..\include\windows;"\Program Files\novell\casa\include";"C:\Dev\Expat-2.0.0\Source\lib""
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
@@ -35,7 +35,7 @@
<Tool
Name="VCLinkerTool"
IgnoreImportLibrary="FALSE"
AdditionalOptions="/EXPORT:ObtainAuthToken"
AdditionalOptions="/EXPORT:ObtainAuthToken /EXPORT:ObtainAuthTokenEx"
AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib micasa.lib shlwapi.lib"
OutputFile="$(OutDir)/authtoken.dll"
LinkIncremental="1"
@@ -53,7 +53,7 @@
mkdir \&quot;Program Files&quot;\novell\casa
mkdir \&quot;Program Files&quot;\novell\casa\lib\
copy $(OutDir)\authtoken.dll \&quot;Program Files&quot;\novell\casa\lib\authtoken.dll
copy $(SolutionDir)client\windows\authtoken.lib \&quot;Program Files&quot;\novell\casa\lib\authtoken.lib
copy $(SolutionDir)\client\windows\authtoken.lib \&quot;Program Files&quot;\novell\casa\lib\authtoken.lib
"/>
<Tool
Name="VCPreBuildEventTool"/>
@@ -81,7 +81,7 @@ copy $(SolutionDir)client\windows\authtoken.lib \&quot;Program Files&quot;\novel
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;XML_STATIC&quot;"
AdditionalIncludeDirectories=".;..\;..\..\include;&quot;C:\Dev\casa\CASA-auth-token\non-java\include\windows&quot;;&quot;\Program Files\novell\casa\include&quot;;&quot;C:\Dev\Expat-2.0.0\Source\lib&quot;"
AdditionalIncludeDirectories=".;..\;..\..\include;..\..\include\windows;&quot;\Program Files\novell\casa\include&quot;;&quot;C:\Dev\Expat-2.0.0\Source\lib&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
@@ -92,7 +92,7 @@ copy $(SolutionDir)client\windows\authtoken.lib \&quot;Program Files&quot;\novel
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/EXPORT:ObtainAuthToken"
AdditionalOptions="/EXPORT:ObtainAuthToken /EXPORT:ObtainAuthTokenEx"
AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib micasa.lib shlwapi.lib"
OutputFile="$(OutDir)/authtoken.dll"
LinkIncremental="1"
@@ -111,7 +111,7 @@ copy $(SolutionDir)client\windows\authtoken.lib \&quot;Program Files&quot;\novel
mkdir \&quot;Program Files&quot;\novell\casa
mkdir \&quot;Program Files&quot;\novell\casa\lib\
copy $(OutDir)\authtoken.dll \&quot;Program Files&quot;\novell\casa\lib\authtoken.dll
copy $(SolutionDir)client\windows\authtoken.lib \&quot;Program Files&quot;\novell\casa\lib\authtoken.lib
copy $(SolutionDir)\client\windows\authtoken.lib \&quot;Program Files&quot;\novell\casa\lib\authtoken.lib
"/>
<Tool
Name="VCPreBuildEventTool"/>
@@ -148,7 +148,7 @@ copy $(SolutionDir)client\windows\authtoken.lib \&quot;Program Files&quot;\novel
RelativePath="..\authpolicy.c">
</File>
<File
RelativePath=".\win32\authtoken.def">
RelativePath=".\authtoken.def">
</File>
<File
RelativePath="..\cache.c">
@@ -171,6 +171,9 @@ copy $(SolutionDir)client\windows\authtoken.lib \&quot;Program Files&quot;\novel
<File
RelativePath="..\gettokenmsg.c">
</File>
<File
RelativePath="..\invalidcert.c">
</File>
<File
RelativePath=".\platform.c">
</File>

View File

@@ -71,6 +71,7 @@ typedef struct _RpcSession
{
HINTERNET hSession;
HINTERNET hConnection;
char *pHostName;
} RpcSession, *PRpcSession;

View File

@@ -94,6 +94,62 @@ CopyMultiToWideAlloc(
}
//++=======================================================================
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(
@@ -112,6 +168,7 @@ OpenRpcSession(
//=======================================================================--
{
RpcSession *pSession;
bool success = false;
DbgTrace(1, "-OpenRpcSession- Start\n", 0);
@@ -122,55 +179,60 @@ OpenRpcSession(
// Zero the session structure
memset(pSession, 0, sizeof(*pSession));
// 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)
// Save copy of the hostname
pSession->pHostName = malloc(strlen(pHostName) + 1);
if (pSession->pHostName)
{
LPWSTR pWideHostName;
int wideHostLen;
strcpy(pSession->pHostName, pHostName);
// 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)
// 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)
{
// Now open connection
pSession->hConnection = WinHttpConnect(pSession->hSession,
pWideHostName,
hostPort,
0);
if (pSession->hConnection == NULL)
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)
{
DbgTrace(0, "-OpenRpcSession- Failed to open connection, error = %d\n", GetLastError());
// 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 allocated resources
WinHttpCloseHandle(pSession->hSession);
free(pSession);
pSession = NULL;
// Free the host name wide string buffer
free(pWideHostName);
}
else
{
DbgTrace(0, "-OpenRpcSession- Error converting host name to wide string\n", 0);
}
// Free the host name wide string buffer
free(pWideHostName);
}
else
{
DbgTrace(0, "-OpenRpcSession- Error converting host name to wide string\n", 0);
// Free allocated resources
WinHttpCloseHandle(pSession->hSession);
free(pSession);
pSession = NULL;
DbgTrace(0, "-OpenRpcSession- Failed to open session, error = %d\n", GetLastError());
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Failed to open session, error = %d\n", GetLastError());
DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for host name\n", 0);
}
}
else
@@ -178,6 +240,25 @@ OpenRpcSession(
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;
@@ -208,6 +289,10 @@ CloseRpcSession(
// 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);
@@ -215,13 +300,47 @@ CloseRpcSession(
}
//++=======================================================================
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 bool secure,
IN long flags,
IN char *pRequestData,
INOUT char **ppResponseData,
INOUT int *pResponseDataLen)
@@ -237,11 +356,16 @@ InternalRpc(
// L2
//=======================================================================--
{
#define CASA_STATUS_INVALID_SERVER_CERTIFICATE CASA_STATUS_UNSUCCESSFUL // temporary until casa_status.h is updated
CasaStatus retStatus = CASA_STATUS_SUCCESS;
char rpcTarget[256];
LPWSTR pWideRpcTarget;
int wideRpcTargetLen;
WCHAR sendHeaders[] = L"Content-Type: text/html";
DWORD securityFailureStatusFlags;
int retriesAllowed = 1;
bool attemptRetry;
DbgTrace(1, "-InternalRpc- Start\n", 0);
@@ -258,124 +382,172 @@ InternalRpc(
{
HINTERNET hRequest;
// Open a request handle
hRequest = WinHttpOpenRequest(pSession->hConnection,
L"POST",
pWideRpcTarget,
NULL,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
secure? WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE : WINHTTP_FLAG_REFRESH);
if (hRequest)
do
{
int reqDataLen = (int) strlen(pRequestData);
// Forget about having been told to retry
attemptRetry = false;
// Send the request
if (WinHttpSendRequest(hRequest,
sendHeaders,
-1,
pRequestData,
reqDataLen,
reqDataLen,
0))
{
// 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,
// Open a request handle
hRequest = WinHttpOpenRequest(pSession->hConnection,
L"POST",
pWideRpcTarget,
NULL,
&httpCompStatus,
&httpCompStatusLen,
WINHTTP_NO_HEADER_INDEX))
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)))
{
// Check that the request completed successfully
if (memcmp(httpCompStatus, L"200", sizeof(httpCompStatus)) == 0)
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)
{
char *pResponseData;
int responseDataBufSize = INITIAL_RESPONSE_DATA_BUF_SIZE;
int responseDataRead = 0;
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());
}
}
}
// Now read the response data, to do so we need to allocate a buffer.
pResponseData = (char*) malloc(INITIAL_RESPONSE_DATA_BUF_SIZE);
if (pResponseData)
// 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 *pCurrLocation = pResponseData;
DWORD bytesRead;
char *pResponseData;
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;
if (WinHttpReadData(hRequest,
(LPVOID) pCurrLocation,
responseDataBufSize - responseDataRead,
&bytesRead))
char *pCurrLocation = pResponseData;
DWORD bytesRead;
do
{
pCurrLocation += bytesRead;
responseDataRead += bytesRead;
// Check if we need to allocate a larger buffer
if (responseDataRead == responseDataBufSize)
bytesRead = 0;
if (WinHttpReadData(hRequest,
(LPVOID) pCurrLocation,
responseDataBufSize - responseDataRead,
&bytesRead))
{
char *pTmpBuf;
pCurrLocation += bytesRead;
responseDataRead += bytesRead;
// We need to upgrade the receive buffer
pTmpBuf = (char*) malloc(responseDataBufSize + INCREMENT_RESPONSE_DATA_BUF_SIZE);
if (pTmpBuf)
// Check if we need to allocate a larger buffer
if (responseDataRead == responseDataBufSize)
{
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);
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
{
DbgTrace(0, "-InternalRpc- Failed reading response data, error = %d\n", GetLastError());
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
// Failed to receive the response data, free the allocated buffer.
free(pResponseData);
}
} 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);
DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
}
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,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
CASA_STATUS_UNSUCCESSFUL);
}
}
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,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
@@ -383,7 +555,7 @@ InternalRpc(
}
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,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
@@ -391,41 +563,141 @@ InternalRpc(
}
else
{
DbgTrace(0, "-InternalRpc- Unable to receive response, error = %d\n", GetLastError());
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
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);
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
{
int error = GetLastError();
DbgTrace(0, "-InternalRpc- Unsuccessful send http request, error = %d\n", error);
if (error == ERROR_WINHTTP_CANNOT_CONNECT)
{
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_AUTH_SERVER_UNAVAILABLE);
}
else
{
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
DbgTrace(0, "-InternalRpc- Unable to open http request, error = %d\n", GetLastError());
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);
@@ -446,7 +718,7 @@ CasaStatus
Rpc(
IN RpcSession *pSession,
IN char *pMethod,
IN bool secure,
IN long flags,
IN char *pRequestData,
INOUT char **ppResponseData,
INOUT int *pResponseDataLen)
@@ -473,7 +745,7 @@ Rpc(
// Issue the RPC
retStatus = InternalRpc(pSession,
pMethod,
secure,
flags,
pRequestData,
ppResponseData,
pResponseDataLen);