summaryrefslogtreecommitdiff
path: root/usr/src/lib/libkmsagent/common/KMSClientProfile.cpp
diff options
context:
space:
mode:
authorJohn Sonnenschein <johns@joyent.com>2012-05-17 18:26:57 +0000
committerJohn Sonnenschein <johns@joyent.com>2012-05-17 18:26:57 +0000
commit04b244dd661c24b510ac22936decfc0972d202d3 (patch)
tree3ebfef98afc303fddf3415d6fba64e8682f495e8 /usr/src/lib/libkmsagent/common/KMSClientProfile.cpp
parenteac250589e41f1b705e1b7427b02b3379aac9f9e (diff)
parenta69187741b83640a90dd8586195456dd50c016a8 (diff)
downloadillumos-joyent-20120517.tar.gz
Merge git.joyent.com:illumos-joyent20120517
Diffstat (limited to 'usr/src/lib/libkmsagent/common/KMSClientProfile.cpp')
-rw-r--r--usr/src/lib/libkmsagent/common/KMSClientProfile.cpp2878
1 files changed, 0 insertions, 2878 deletions
diff --git a/usr/src/lib/libkmsagent/common/KMSClientProfile.cpp b/usr/src/lib/libkmsagent/common/KMSClientProfile.cpp
deleted file mode 100644
index cefd75a1b9..0000000000
--- a/usr/src/lib/libkmsagent/common/KMSClientProfile.cpp
+++ /dev/null
@@ -1,2878 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- */
-
-#include <stdio.h>
-#include <errno.h>
-
-#if !defined(UNIX) && !defined(METAWARE)
-#include "KMSAgent_direct.h"
-#endif
-
-#include <string.h>
-
-#include "KMSClientProfile.h"
-
-#include "KMSAgent.h"
-#include "KMS_CAStub.h"
-#include "KMS_CertificateStub.h"
-#include "KMS_DiscoveryStub.h"
-#include "KMSClientProfileImpl.h"
-#include "KMSAuditLogger.h"
-#include "KMSAgentSoapUtilities.h"
-#include "KMSAgentStringUtilities.h"
-
-
-#include "KMSAgentPKICommon.h" // must be before agentstorage
-
-#include "stdsoap2.h"
-#include "KMSAgentStorage.h" // uses KMSClientProfile
-
-
-#include "KMSAgentWebServiceNamespaces.h"
-#include "k_setupssl.h"
-#include "KMSAgentChallenge.h"
-#include "KMSAgentCryptoUtilities.h"
-#include "ApplianceParameters.h"
-#include "AutoMutex.h"
-
-#include "KMSAgentLoadBalancer.h"
-#include "KMSAgentDataUnitCache.h"
-
-#include "ClientSoapFaultCodes.h"
-#ifdef METAWARE
-#include "debug.h"
-#include "sizet.h"
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long uint64_t;
-#include "literals.h"
-#endif
-#include "KMSAgentAESKeyWrap.h"
-
-#if defined(METAWARE) && defined(DEBUG)
-#include "debug.h"
-#endif
-#include "KMSAuditLogger.h"
-#include "KMSClientProfileImpl.h"
-
-#ifdef METAWARE
-extern "C" void
-tnMsg( const char *format,
- ... );
-#endif
-
-bool g_bUseFileLog = false;
-char g_wsWorkingDirectory[KMS_MAX_PATH_LENGTH+1] = "./";
-
-
-static bool InitializeLogging(
- const utf8cstr i_wsWorkingDirectory,
- int i_bUseFileLog )
-{
- FATAL_ASSERT( !i_bUseFileLog || i_wsWorkingDirectory );
-
- bool bFileLogSuccess = true;
-
- g_bUseFileLog = ( i_bUseFileLog != 0 );
-
- // InitializeFileLogging must always be called,
- // because the file is always used by FATALs.
-
- bFileLogSuccess = InitializeFileLogging( i_wsWorkingDirectory ) ? true:false;
-
- return bFileLogSuccess;
-}
-
-static void FinalizeLogging()
-{
- // FinalizeFileLogging must always be called,
- // because the file is always used by FATALs.
- FinalizeFileLogging();
-
- return;
-}
-
-
-
-
-/*---------------------------------------------------------------------------
- * Function: KMSClient_InitializeLibrary
- *
- *--------------------------------------------------------------------------*/
-
-bool KMSClient_InitializeLibrary(
- const utf8cstr i_wsWorkingDirectory,
- int i_bUseFileLog)
-{
- bool bSuccess;
-
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_InitializeLibrary : ENTERING");
-#endif
-
- // setup SSL
- bSuccess = K_SetupSSL() == 1;
- if(!bSuccess)
- {
- return false;
- }
-
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_InitializeLibrary : set current directory");
-#endif
-
- // if i_wsWorkingDirectory is null, caller means current directory
- if ( i_wsWorkingDirectory != NULL )
- {
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_InitializeLibrary : check working directory");
-#endif
-
- // string is there but is empty or junk
- if (strlen(i_wsWorkingDirectory) <= 0)
- {
- strcpy(i_wsWorkingDirectory, ".");
- }
-
- if ( strlen(i_wsWorkingDirectory) >= KMS_MAX_PATH_LENGTH )
- {
- return false;
- }
-
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_InitializeLibrary : set global working directory");
-#endif
-
- // set global working directory to input
- strncpy(g_wsWorkingDirectory,
- i_wsWorkingDirectory,
- KMS_MAX_PATH_LENGTH);
- g_wsWorkingDirectory[KMS_MAX_PATH_LENGTH] = 0;
- }
- else
- {
- strcpy(g_wsWorkingDirectory, ".");
- }
-
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_InitializeLibrary : Initialize logging");
-#endif
-
- // initialize file logging
- bSuccess = InitializeLogging( g_wsWorkingDirectory,
- i_bUseFileLog);
-
- return bSuccess;
-}
-
-
-/*---------------------------------------------------------------------------
- * Function: KMSClient_FinalizeLibrary
- *--------------------------------------------------------------------------*/
-bool KMSClient_FinalizeLibrary()
-{
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_FinalizeLibrary : ENTERING");
-#endif
-
- K_CleanupSSL();
-
- FinalizeLogging();
-
- return true; /* always */
-}
-
-
-int LogError_lastErrno;
-
-
-/**
- * Construct a message for the KMSAuditLogger and store the message
- * in the profile as the last error message.
- */
-void LogError_function(KMSClientProfile *i_pProfile,
- int i_iErrno,
- const char* i_sOperation,
- const char* i_sEntityID,
- const char* i_sNetworkAddress,
- const char* i_sMessage )
-{
- FATAL_ASSERT( i_pProfile && i_sOperation );
-
- // save for caller's use - this shouldn't be a global, but I don't
- // want this as an item in the profile as I don't want it persisted
- LogError_lastErrno = i_iErrno;
-
- // log the message to a data file (and internal logs)
-#ifndef METAWARE
- if ( g_bUseFileLog )
-#endif
- {
- Log_function(i_iErrno,
- i_sOperation,
- i_sEntityID,
- i_sNetworkAddress,
- i_sMessage);
- }
-
-#ifdef METAWARE
- /* print this to the T10000/9840 VOP */
- /* NOTE the \n is important to VOP - leave it in */
- tnMsg("`msg`KMS2.0:msg#=%i,op=%s\r\n",
- i_iErrno,
- i_sOperation);
-
- tnMsg("`msg`msg=%s,eid=%s,addr=%s\r\n",
- i_sMessage,
- i_sEntityID,
- i_sNetworkAddress);
-
-#endif
-
- // copy the error message into the profile (for later reference)
- strncpy(i_pProfile->m_wsErrorString,
- i_sOperation,
- KMS_MAX_ERROR_STRING);
-
- // make sure to NUL out the end
- i_pProfile->m_wsErrorString[KMS_MAX_ERROR_STRING] = 0;
-
- if ( i_sEntityID )
- {
- strncat(i_pProfile->m_wsErrorString,
- i_sEntityID,
- KMS_MAX_ERROR_STRING);
- }
-
- if ( i_sNetworkAddress )
- {
- strncat(i_pProfile->m_wsErrorString,
- ",Address=",
- KMS_MAX_ERROR_STRING);
- strncat(i_pProfile->m_wsErrorString,
- i_sNetworkAddress,
- KMS_MAX_ERROR_STRING);
- }
-
- if ( i_sMessage )
- {
- strncat(i_pProfile->m_wsErrorString,
- ",Msg=",
- KMS_MAX_ERROR_STRING);
- strncat(i_pProfile->m_wsErrorString,
- i_sMessage,
- KMS_MAX_ERROR_STRING);
- }
-
- // make sure to NUL out the end
- i_pProfile->m_wsErrorString[KMS_MAX_ERROR_STRING] = 0;
-
-}
-
-// see KMSClientProfileImpl.h
-bool SSL_InvalidCertificate (const char * const i_sErrorString)
-{
- if (
- // OpenSSL generates this msg
- strstr(i_sErrorString, "sslv3 alert certificate unknown"))
- {
- return true;
- }
- return false;
-
-}
-
-// see KMSClientProfileImpl.h
-bool ServerError (const char * i_sErrorString, int i_iErrno )
-{
- // The Client Soap Fault Code returned by the KMA
- // may be at the start of i_sErrorString or immediately
- // follwing "SoapFaultString=" depending on the caller's
- // string
-
- int iErrorCode;
-
- const char* sFaultstringStart = strstr(i_sErrorString, "SoapFaultString=" );
- if ( sFaultstringStart )
- {
- iErrorCode = GET_FAULT_CODE( sFaultstringStart + strlen("SoapFaultString=") );
- }
- else
- {
- // This may be zero if there is no error code at the start of the string.
- iErrorCode = GET_FAULT_CODE( i_sErrorString );
- }
-
- // the following is commented out so the former check can be observed. This check is no longer
- // made since invalid certificate failures may be due to a KMA that is behind on
- // replication updates hence failover would succeed.
-// if (
-// // OpenSSL generates this msg
-// SSL_InvalidCertificate(i_sErrorString))
-// {
-// return false;
-// }
-
- if (
- // when the KMA is locked
- iErrorCode == CLIENT_ERROR_AGENT_APPLIANCE_LOCKED
-
- // KMS 2.2 change when the KMA is locked
- || iErrorCode == CLIENT_ERROR_MANAGER_APPLIANCE_LOCKED
-
- // KMS 2.2 change for core security internal error
- || iErrorCode == CLIENT_ERROR_MANAGER_INTERNAL
-
- // if the KMA's pre-gen'd key pool is depleted
- || iErrorCode == CLIENT_ERROR_AGENT_NO_READY_KEYS
-
- // if the KMA's HSM is broke and the KMA is in FIPS mode
- || iErrorCode == CLIENT_ERROR_SERVER_HSM_REQUIRED_BUT_MISSING
-
- // when the server is too slow
- || NULL != strstr( i_sErrorString, "Timeout" )
- || NULL != strstr( i_sErrorString, "Operation interrupted or timed out" )
-
- // The Appliance is powered down, or is not reachable
- || NULL != strstr( i_sErrorString, "Connection refused" )
-
- || NULL != strstr( i_sErrorString, "Unknown error" )
-
- // SOAP EOF
- || NULL != strstr( i_sErrorString, "End of file or no input:" )
-
- // Appliance server software is not running (while Appliance machine is OK)
- || NULL != strstr( i_sErrorString, "connect failed in tcp_connect()" )
-
- // If the server has an internal error but still responds
- || NULL != strstr( i_sErrorString, "Server Error" )
-
- // OpenSSL protocol errors (Note: the SSL_ERROR_SSL may be due
- // to invalid client-side values, but for now it's used as a
- // catch-all; a side-effect is that any actual invalid client-side
- // value will cause one audit log entry to be created on each
- // Appliance in the cluster).
- || NULL != strstr( i_sErrorString,
- "Error observed by underlying BIO: No error" )
- || NULL != strstr( i_sErrorString,
- "EOF was observed that violates the protocol" )
- || NULL != strstr( i_sErrorString,
- "SSL_ERROR_SSL" ) )
- {
- return true;
- }
-
-#ifndef WIN32
- // check for errno values that imply connection problems to the server
- switch (i_iErrno)
- {
- case ECONNABORTED : return true; // Connection aborted.
- case ECONNREFUSED : return true; // Connection refused.
- case ECONNRESET : return true; // Connection reset.
- case EHOSTUNREACH : return true; // Host is unreachable.
- case ENETDOWN : return true; // Network is down.
- case ENETRESET : return true; // Connection aborted by network.
- case ENETUNREACH : return true; // Network unreachable.
- case ENOPROTOOPT : return true; // Protocol not available.
-#ifndef METAWARE
- case ETIME : return true; // Stream ioctl() timeout.
-#endif
- case ETIMEDOUT : return true; // Connection timed out.
- }
-#endif
- // at this point we conclude its a client side issue
- return false;
-}
-
-/*---------------------------------------------------------------------------
- * Function: KMSClient_GetLastErrorMessage
- *
- *--------------------------------------------------------------------------*/
-
-// extern "C"
-utf8char * KMSClient_GetLastErrorMessage(KMSClientProfile *i_pProfile)
-{
- FATAL_ASSERT(i_pProfile);
-
- CAutoMutex oAutoMutex( 0 );
- if ( i_pProfile->m_pLock )
- {
- oAutoMutex.Lock( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
- }
-
- return i_pProfile->m_wsErrorString;
-}
-
-
-/*---------------------------------------------------------------------------
- * Function: KMSClient_RetrieveEntityCertificate
- * Get the Root CA Certificate and store it into the profile
- *--------------------------------------------------------------------------*/
-static bool KMSClient_RetrieveEntityCertificate(
- KMSClientProfile* i_pProfile,
- utf8cstr i_wsEntityID,
- utf8cstr i_wsPassphrase,
- char* const o_sHexHashedPassphrase )
-{
- FATAL_ASSERT( i_pProfile && i_wsEntityID && i_wsPassphrase );
-
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_RetrieveEntityCertificate : entered");
-#endif
-
- CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
- char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
- char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
-
- strcpy(o_sHexHashedPassphrase, "");
-
- bool bSuccess = true;
- bool bTryFailOver = false;
-
- struct soap *pstCASoap;
- pstCASoap = (struct soap *) malloc( sizeof(struct soap) );
- if(pstCASoap == NULL)
- {
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("Malloc %x pstCASoap returned null\n", sizeof(struct soap));
-#endif
- LogError(i_pProfile,
- LoadProfile_AUDIT_CLIENT_GET_ROOT_CA_CERTIFICATE_SOAP_ERROR,
- NULL,
- NULL,
- "malloc failure for pstCASoap" );
- return false;
- }
-
- // initialize the SOAP connection that will get the RootCA
- soap_init2( pstCASoap, (SOAP_XML_STRICT | SOAP_C_UTFSTRING), (SOAP_XML_STRICT | SOAP_C_UTFSTRING) );
-
-#ifdef METAWARE
- K_SetupCallbacks ( pstCASoap );
-#endif
-
- CCertificate* pRootCACertificate = 0;
- CCertificate* pEntityCertificate = 0;
- CPrivateKey* pEntityPrivateKey = 0;
-
- soap_set_namespaces( pstCASoap, KMS_CA_namespaces );
-
- pstCASoap->connect_timeout = i_pProfile->m_iTransactionTimeout;
- pstCASoap->send_timeout = i_pProfile->m_iTransactionTimeout;
- pstCASoap->recv_timeout = i_pProfile->m_iTransactionTimeout;
-
- struct soap *pstCertificateSoap;
-
- pstCertificateSoap = (struct soap *) malloc( sizeof(struct soap) );
-
- if(pstCertificateSoap == NULL)
- {
-#if defined(METAWARE)
- log_printf("Malloc %x pstCertificateSoap returned null\n",
- sizeof(struct soap));
-#endif
- soap_free( pstCASoap );
- free(pstCASoap);
- return false;
- }
-
- // initialize the SOAP connection that will get the Certificate
- soap_init2( pstCertificateSoap, (SOAP_XML_STRICT | SOAP_C_UTFSTRING), (SOAP_XML_STRICT | SOAP_C_UTFSTRING) );
-
-#ifdef METAWARE
- K_SetupCallbacks ( pstCertificateSoap );
-#endif
-
- soap_set_namespaces( pstCertificateSoap, KMS_Certificate_namespaces );
-
- pstCertificateSoap->connect_timeout = i_pProfile->m_iTransactionTimeout;
- pstCertificateSoap->send_timeout = i_pProfile->m_iTransactionTimeout;
- pstCertificateSoap->recv_timeout = i_pProfile->m_iTransactionTimeout;
-
- CAgentLoadBalancer oLoadBalancer(i_pProfile);
- int iIndex = oLoadBalancer.Balance();
-
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_RetrieveEntityCertificate : call KMS_CA__RetrieveRootCACertificate");
-#endif
-
- // get the server's URL that will provide SOAP services
- do
- {
- bSuccess = true;
- bTryFailOver = false;
- bool bFailedOnRetrieveRootCA = false;
- const char* sURL = 0;
-
- if ( bSuccess )
- {
- sURL = oLoadBalancer.GetHTTPURL(iIndex,
- i_pProfile->m_iPortForCAService);
-
- if ( !sURL )
- {
- bSuccess = false;
- }
- }
-
- if ( bSuccess )
- {
- strncpy(i_pProfile->m_sURL, sURL, KMS_MAX_URL);
- i_pProfile->m_sURL[KMS_MAX_URL] = 0;
- }
-
-
- // SOAP CALL - retrieve Root CA Certificate from the Server
- struct KMS_CA::
- KMS_CA__RetrieveRootCACertificateResponse stRootCACertificateResponse;
-
- if ( bSuccess )
- {
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_RetrieveCertificate : call KMS_CA__RetrieveRootCACertificate again");
-#endif
- bSuccess =
- KMS_CA::soap_call_KMS_CA__RetrieveRootCACertificate(
- pstCASoap,
- i_pProfile->m_sURL,
- NULL,
- i_wsEntityID,
- stRootCACertificateResponse ) == SOAP_OK;
-
- if ( !bSuccess )
- {
- GetSoapFault(sSoapFaultMsg, (struct soap*)pstCASoap);
- GetPeerNetworkAddress(sKmaAddress, pstCASoap);
- LogError(i_pProfile,
- LoadProfile_AUDIT_CLIENT_GET_ROOT_CA_CERTIFICATE_SOAP_ERROR,
- NULL,
- sKmaAddress,
- sSoapFaultMsg );
-
- bTryFailOver = ServerError(GET_SOAP_FAULTSTRING(pstCASoap), pstCASoap->errnum);
- bFailedOnRetrieveRootCA = true;
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 1\n");
- }
-#endif
-
-
- // Validate the SOAP response
- if ( bSuccess )
- {
- if ( stRootCACertificateResponse.RootCACertificate.__size < 1 ||
- stRootCACertificateResponse.RootCACertificate.__ptr == NULL ||
- stRootCACertificateResponse.AuthenticationHashIterationCount <
- MIN_AUTHENTICATION_ITERATION_COUNT ||
- stRootCACertificateResponse.AuthenticationHashIterationCount >
- MAX_AUTHENTICATION_ITERATION_COUNT ||
- stRootCACertificateResponse.ClientAuthenticationChallenge.__size !=
- AUTHENTICATION_CHALLENGE_LENGTH ||
- stRootCACertificateResponse.ClientAuthenticationChallenge.__ptr == NULL )
- {
- bSuccess = false;
-
- GetPeerNetworkAddress(sKmaAddress, pstCASoap);
- LogError(i_pProfile,
- AUDIT_CLIENT_GET_ROOT_CA_CERTIFICATE_INVALID_RESPONSE_FORMAT,
- NULL,
- sKmaAddress,
- NULL);
- }
- else
- {
- GetPeerNetworkAddress(sKmaAddress, pstCASoap);
- Log(AUDIT_CLIENT_GET_ROOT_CA_CERTIFICATE_SUCCESS,
- NULL,
- sKmaAddress,
- NULL);
- }
-
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 2\n");
- }
-#endif
-
- // build our RootCACertificate object
- if ( bSuccess )
- {
- pRootCACertificate = new CCertificate;
-
- // make sure the new was successful
- bSuccess = ( pRootCACertificate != 0 );
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 3\n");
- }
-#endif
-
- if ( bSuccess )
- {
- // OVERLOADED Load method - 3 parameters means
- // recall from BUFFER
- bSuccess =
- pRootCACertificate->Load(
- stRootCACertificateResponse.RootCACertificate.__ptr, // to here
- stRootCACertificateResponse.RootCACertificate.__size, // size
- PKI_FORMAT ); // ignored
-
- if( !bSuccess )
- {
- GetPeerNetworkAddress(sKmaAddress, pstCASoap);
- LogError(i_pProfile,
- AUDIT_CLIENT_GET_ROOT_CA_CERTIFICATE_INVALID_CA_CERTIFICATE_FORMAT,
- NULL,
- sKmaAddress,
- NULL);
- }
-
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 4\n");
- }
-#endif
-
-
- if ( bSuccess )
- {
- // save the built CACertificate object to a FILE (i_pProfile gets the
- // persistent handle to that file)
- bSuccess = StoreCACertificate( i_pProfile, pRootCACertificate );
-
- if ( !bSuccess )
- {
- LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_SAVE_CA_CERTIFICATE_FAILED,
- NULL,
- NULL,
- NULL);
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 5\n");
- }
-#endif
-
- //-------------------------------
- // Initialize SSL - use SERVER AUTH
- //-------------------------------
- if ( bSuccess )
- {
- // SERVER_AUTHENTICATION needs just the pstCertificateSoap
- bSuccess =
- K_soap_ssl_client_context(
- i_pProfile, // in ->m_wsProfileName,->m_sHexHashedPassphrase
- pstCertificateSoap, // in - soap structure
- SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION // in - flags
- ) == SOAP_OK;
-
- if ( !bSuccess )
- {
- GetSoapFault(sSoapFaultMsg, (struct soap*)pstCertificateSoap);
- GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
- LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_SOAP_ERROR,
- NULL,
- sKmaAddress,
- sSoapFaultMsg );
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 6\n");
- }
-#endif
-
- // hash the passphrase passed in
- char sHexAuthenticationSecret[2*HASH_LENGTH+1];
-
- if ( bSuccess )
- {
- bSuccess = ComputeFixedEntityHashedPassphraseAndAuthenticationSecret(
- i_wsPassphrase,
- o_sHexHashedPassphrase,
- stRootCACertificateResponse.AuthenticationHashIterationCount,
- sHexAuthenticationSecret );
-
- if ( !bSuccess )
- {
- LogError(i_pProfile,AUDIT_CLIENT_COMPUTE_FIXED_FAILED,
- NULL,
- NULL,
- NULL);
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 7\n");
- }
-#endif
-
- // copy received Root CA into buffer for input
- // into challenge-response computation
- unsigned char aRootCACertificate[MAX_CERT_SIZE];
- int iRootCACertificateLength;
-
- if ( bSuccess )
- {
- // OVERLOADED save method - save iRootCACertificateLength to aRootCACertificate
- // buffer
- bSuccess = pRootCACertificate->Save(
- aRootCACertificate,
- MAX_CERT_SIZE,
- &iRootCACertificateLength,
- PKI_FORMAT );
-
- if ( !bSuccess )
- {
- LogError(i_pProfile,AUDIT_CLIENT_SAVE_ROOTCA_FAILED,
- NULL,
- NULL,
- NULL);
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 8\n");
- }
-#endif
-
- // respond to server's challenge
- unsigned char aAuthenticationSecret[AUTHENTICATION_SECRET_LENGTH];
- unsigned char
- aClientAuthenticationChallengeResponse[AUTHENTICATION_RESPONSE_LENGTH];
-
- if ( bSuccess )
- {
- FATAL_ASSERT( AUTHENTICATION_SECRET_LENGTH ==
- ConvertUTF8HexStringToBinary(
- sHexAuthenticationSecret, NULL ) );
-
- ConvertUTF8HexStringToBinary(
- sHexAuthenticationSecret, aAuthenticationSecret );
-
- // client authentication response
- bSuccess = ComputeChallengeResponse(
- aAuthenticationSecret,
- AUTHENTICATION_SECRET_LENGTH,
- aRootCACertificate,
- iRootCACertificateLength,
- stRootCACertificateResponse.ClientAuthenticationChallenge.__ptr,
- AUTHENTICATION_CHALLENGE_LENGTH,
- aClientAuthenticationChallengeResponse,
- AUTHENTICATION_RESPONSE_LENGTH );
-
- if ( !bSuccess )
- {
- LogError(i_pProfile,AUDIT_CLIENT_COMPUTE_CHALLENGE_RESPONSE_FAILED,
- NULL,
- NULL,
- NULL);
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 9\n");
- }
-#endif
-
- struct KMS_Certificate::xsd__hexBinary stClientAuthenticationResponse;
-
- if ( bSuccess )
- {
- stClientAuthenticationResponse.__size =
- AUTHENTICATION_RESPONSE_LENGTH;
- stClientAuthenticationResponse.__ptr =
- (unsigned char*)soap_malloc(
- pstCertificateSoap, AUTHENTICATION_RESPONSE_LENGTH );
-
- if ( stClientAuthenticationResponse.__ptr != NULL )
- {
- memcpy( stClientAuthenticationResponse.__ptr,
- aClientAuthenticationChallengeResponse,
- AUTHENTICATION_RESPONSE_LENGTH );
- }
- else
- {
- bSuccess = false;
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 10\n");
- }
-#endif
-
- // generate challenge nonce
- struct KMS_Certificate::xsd__hexBinary stServerAuthenticationChallenge;
-
- if ( bSuccess )
- {
- stServerAuthenticationChallenge.__size =
- AUTHENTICATION_CHALLENGE_LENGTH;
- stServerAuthenticationChallenge.__ptr =
- (unsigned char*)soap_malloc( pstCertificateSoap,
- AUTHENTICATION_CHALLENGE_LENGTH );
-
- bSuccess = ( stServerAuthenticationChallenge.__ptr != NULL );
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 11\n");
- }
-#endif
-
- if ( bSuccess )
- {
- bSuccess = GetPseudorandomBytes(
- AUTHENTICATION_CHALLENGE_LENGTH,
- stServerAuthenticationChallenge.__ptr );
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 12\n");
- }
-#endif
-
- if ( bSuccess )
- {
- sURL = oLoadBalancer.GetHTTPSURL(iIndex,
- i_pProfile->
- m_iPortForCertificateService);
-
- if ( !sURL )
- {
- bSuccess = false;
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 13\n");
- }
-#endif
-
- // Verify that the same URL is used for Root CA Certificate
- // retrieval as for Entity Certificate retrieval
-
- if ( bSuccess )
- {
- char sTempCAURL[KMS_MAX_URL + 1];
- strncpy( sTempCAURL, i_pProfile->m_sURL, KMS_MAX_URL );
- sTempCAURL[KMS_MAX_URL] = 0;
-
- char * sRetrieveRootCACertificateURL = strtok( sTempCAURL, ":" );
-
- sRetrieveRootCACertificateURL = strtok(NULL, ":");
-
- char sTempAgentURL[KMS_MAX_URL + 1];
- strncpy( sTempAgentURL, sURL, KMS_MAX_URL );
- sTempAgentURL[KMS_MAX_URL] = 0;
- char * sRetrieveAgentCertificateURL = strtok( sTempAgentURL, ":" );
- sRetrieveAgentCertificateURL = strtok(NULL, ":");
-
- FATAL_ASSERT( strcmp( sRetrieveRootCACertificateURL,
- sRetrieveAgentCertificateURL ) == 0 );
-
- strncpy(i_pProfile->m_sURL, sURL, KMS_MAX_URL);
- i_pProfile->m_sURL[KMS_MAX_URL] = 0;
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 14\n");
- }
-#endif
-
- KMS_Certificate::KMS_Certificate__RetrieveEntityCertificateResponse
- stRetrieveEntityCertificateResponse;
-
- // SOAP - retrieve ENTITY Certificate, passing the challenge response,
- // a challenge to the server and get back the server's response
- if ( bSuccess )
- {
- bSuccess =
- KMS_Certificate::soap_call_KMS_Certificate__RetrieveEntityCertificate(
- pstCertificateSoap,
- sURL,
- NULL,
- (utf8cstr )i_wsEntityID,
- stClientAuthenticationResponse,
- stServerAuthenticationChallenge,
- stRetrieveEntityCertificateResponse ) == SOAP_OK;
-
- if( !bSuccess )
- {
- GetSoapFault(sSoapFaultMsg, (struct soap*)pstCertificateSoap);
- GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
- LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_SOAP_ERROR,
- NULL,
- sKmaAddress,
- sSoapFaultMsg );
-
- bTryFailOver = ServerError(GET_SOAP_FAULTSTRING(pstCertificateSoap),
- pstCertificateSoap->errnum);
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 15\n");
- }
-#endif
-
- // Validate the response structure
- if ( bSuccess )
- {
- if ( stRetrieveEntityCertificateResponse.
- ServerAuthenticationResponse.__ptr == NULL
-
- || stRetrieveEntityCertificateResponse.
- ServerAuthenticationResponse.__size !=
- AUTHENTICATION_RESPONSE_LENGTH
-
- || stRetrieveEntityCertificateResponse.Certificate.__size < 1
-
- || stRetrieveEntityCertificateResponse.Certificate.__ptr == 0
-
- || stRetrieveEntityCertificateResponse.
- WrappedPrivateKeyMaterial.__size < 1
-
- || stRetrieveEntityCertificateResponse.
- WrappedPrivateKeyMaterial.__ptr == 0 )
- {
- bSuccess = false;
-
- GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
- LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_INVALID_RESPONSE_FORMAT,
- NULL,
- sKmaAddress,
- NULL );
- }
- else
- {
- GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
- Log(AUDIT_CLIENT_GET_CERTIFICATE_SUCCESS,
- NULL,
- sKmaAddress,
- NULL );
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 16\n");
- }
-#endif
-
- // if valid, calculate the correct challenge-response
- unsigned char
- aServerAuthenticationChallengeResponse[AUTHENTICATION_RESPONSE_LENGTH];
-
- if ( bSuccess )
- {
- bSuccess = ComputeChallengeResponse(
- aAuthenticationSecret,
- AUTHENTICATION_SECRET_LENGTH,
- aRootCACertificate,
- iRootCACertificateLength,
- stServerAuthenticationChallenge.__ptr,
- AUTHENTICATION_CHALLENGE_LENGTH,
- aServerAuthenticationChallengeResponse,
- AUTHENTICATION_RESPONSE_LENGTH );
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 17\n");
- }
-#endif
-
- // if successful, check if the server provided the correct challenge-response
- if ( bSuccess )
- {
- if ( 0 != memcmp(
- aServerAuthenticationChallengeResponse,
- stRetrieveEntityCertificateResponse.ServerAuthenticationResponse.__ptr,
- AUTHENTICATION_RESPONSE_LENGTH ) )
- {
- bSuccess = false;
-
- GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
- LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_INVALID_CHALLENGE_RESPONSE,
- NULL,
- sKmaAddress,
- NULL );
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 18\n");
- }
-#endif
-
-
- if ( bSuccess )
- {
- pEntityCertificate = new CCertificate;
- // if certificate was obtained
- bSuccess = ( pEntityCertificate != 0 );
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 19\n");
- }
-#endif
-
- if ( bSuccess )
- {
- // Load(recall) the signed certificate using OVERLOADED load method
- // 3 parameters means load from a buffer
- bSuccess = pEntityCertificate->Load(
- stRetrieveEntityCertificateResponse.Certificate.__ptr, // load into
- stRetrieveEntityCertificateResponse.Certificate.__size,
- PKI_FORMAT );
-
- if ( !bSuccess )
- {
- GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
- LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_INVALID_CERTIFICATE_FORMAT,
- NULL,
- sKmaAddress,
- NULL );
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 20\n");
- }
-#endif
-
- if ( bSuccess )
- {
- pEntityPrivateKey = new CPrivateKey;
- bSuccess = ( pEntityPrivateKey != 0 );
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- {
- log_printf("!bSuccess 21\n");
- }
-#endif
-
-
- if ( bSuccess )
- {
- // Load the Private Key using OVERLOADED Load method - 3 parameters
- // means load from a buffer
-
- // TODO: change this when certificate service supports requesting unwrapped private keys
- bSuccess = pEntityPrivateKey->Load(
- stRetrieveEntityCertificateResponse.WrappedPrivateKeyMaterial.__ptr, // load into
- stRetrieveEntityCertificateResponse.WrappedPrivateKeyMaterial.__size,
- NULL,
- PKI_FORMAT );
-
- if (!bSuccess )
- {
-
- GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
- LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_INVALID_KEY_FORMAT,
- NULL,
- sKmaAddress,
- NULL );
- }
- }
-
- if ( bSuccess )
- {
- strncpy(i_pProfile->m_wsEntityID,
- i_wsEntityID,
- KMS_MAX_ENTITY_ID );
- i_pProfile->m_wsEntityID[KMS_MAX_ENTITY_ID] = 0;
-
- // store PKI certificates and unwrapped private key
- bSuccess = StorePKIcerts( i_pProfile,
- pRootCACertificate,
- pEntityCertificate,
- pEntityPrivateKey,
-#ifdef KMSUSERPKCS12
- i_wsPassphrase
-#else
- NULL
-#endif
- );
-#ifdef KMSUSERPKCS12
- if (bSuccess) {
- /*
- * Write out the cert and key individually so GetPKIcerts
- * can use them.
- */
- bSuccess = StoreTempAgentPKI(i_pProfile,
- pEntityCertificate, pEntityPrivateKey);
- }
-
-#endif
- }
-
- if ( !bSuccess )
- {
- if (pRootCACertificate)
- {
- delete pRootCACertificate;
- }
- if (pEntityCertificate)
- {
- delete pEntityCertificate;
- }
- if (pEntityPrivateKey)
- {
- delete pEntityPrivateKey;
- }
-
- i_pProfile->m_iEnrolled = FALSE;
-
- if ( bTryFailOver )
- {
- iIndex = oLoadBalancer.FailOver(iIndex, bFailedOnRetrieveRootCA ? pstCASoap : pstCertificateSoap);
- }
- }
- }
- while ( bTryFailOver && (iIndex >= 0) && !bSuccess );
-
- // certs are now persisted so free up space
- if ( bSuccess )
- {
- delete pRootCACertificate;
- delete pEntityCertificate;
- delete pEntityPrivateKey;
- }
-
- // Clean up SOAP resources for pstCASoap
- soap_destroy( pstCASoap );
- soap_end( pstCASoap );
- soap_done( pstCASoap );
-
- // Clean up SOAP resources for pstCertificateSoap
- soap_destroy( pstCertificateSoap );
- soap_end( pstCertificateSoap );
- soap_done( pstCertificateSoap );
-
- free(pstCASoap);
- free(pstCertificateSoap);
-
- return bSuccess;
-}
-
-/*--------------------------------------------------------------------------
- * LoadClusterInformation
- * calls GetCluster - that's it.
- * If there is no cluster file, this function will return true,
- * but o_bClusterInformationFound will be false.
- *-------------------------------------------------------------------------*/
-static bool LoadClusterInformation( KMSClientProfile* i_pProfile,
- int& o_bClusterInformationFound )
-{
- FATAL_ASSERT( i_pProfile );
-
- o_bClusterInformationFound = false;
-
- CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
-
- return GetCluster( i_pProfile, o_bClusterInformationFound ) ;
-
-}
-
-
-/*--------------------------------------------------------------------------
- * EnrollAgent
- * calls functions to perform enrollment and save PKI info to persistent storage
- * stores configuration in persistent storage
- *-------------------------------------------------------------------------*/
-
-static bool EnrollAgent( KMSClientProfile * io_pProfile,
- utf8cstr i_wsEntityID,
- utf8cstr i_wsPassphrase )
-{
- FATAL_ASSERT( io_pProfile && i_wsEntityID && i_wsPassphrase );
-
- bool bSuccess = true;
-
- // see KMSAgentCryptoUtilities for HASH_LENGTH, aka KMS_MAX_HASH_SIZE
- char sHexHashedPassphrase[2*KMS_MAX_HASH_SIZE+1];
-
- if ( bSuccess )
- {
- // performs enrollment and saves PKI info to persistent storage
- bSuccess = KMSClient_RetrieveEntityCertificate(
- io_pProfile,
- i_wsEntityID,
- i_wsPassphrase,
- sHexHashedPassphrase );
-
- // KMSClient_RetrieveCertificate logs errors
- }
-
- if (bSuccess)
- {
- strncpy(io_pProfile->m_sHexHashedPassphrase,
- sHexHashedPassphrase,
- 2*KMS_MAX_HASH_SIZE );
- io_pProfile->m_sHexHashedPassphrase[2*KMS_MAX_HASH_SIZE] = 0;
-
- // persist the profile now updated with the hashed passphrase
- bSuccess = StoreConfig( io_pProfile );
-
- if (!bSuccess)
- {
- Log(AUDIT_CLIENT_LOAD_PROFILE,
- i_wsEntityID,
- NULL,
- "store config failed following enrollment" );
- }
- }
-
- return bSuccess;
-}
-
-/*---------------------------------------------------------------------------
- * Function: KMSClient_LoadProfile
- *
- *--------------------------------------------------------------------------*/
-bool KMSClient_LoadProfile(
- KMSClientProfile *io_pProfile,
- utf8char *i_wsProfileName,
- utf8char *i_wsEntityID,
- utf8char *i_wsPassphrase,
- utf8char *i_wsApplianceAddress,
- int i_iTransactionTimeout,
- int i_iFailOverLimit,
- int i_iClusterDiscoveryFrequency,
- int i_eKMSmode)
-{
- FATAL_ASSERT(io_pProfile);
- FATAL_ASSERT(i_wsProfileName);
-
- bool bSuccess = true;
-
- char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
- char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
-
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_LoadProfile : entered");
-#endif
-
- memset( io_pProfile, 0, sizeof(KMSClientProfile) );
-
- // create lock
-
- if (bSuccess)
- {
- bSuccess =
- ( K_CreateMutex((K_MUTEX_HANDLE *)&io_pProfile->m_pLock) ==
- K_SYS_OK );
- }
-
- // initialize profile with parameters
-
- strncpy(io_pProfile->m_wsProfileName,
- i_wsProfileName,
- KMS_MAX_ENTITY_ID);
- io_pProfile->m_wsProfileName[KMS_MAX_ENTITY_ID] = 0;
-
- io_pProfile->m_iPortForCAService =
- DEFAULT_CA_SERVICE_PORT_NUMBER;
- io_pProfile->m_iPortForCertificateService =
- DEFAULT_CERTIFICATE_SERVICE_PORT_NUMBER;
- io_pProfile->m_iPortForDiscoveryService =
- DEFAULT_DISCOVERY_SERVICE_PORT_NUMBER;
- io_pProfile->m_iPortForAgentService =
- DEFAULT_AGENT_SERVICE_PORT_NUMBER;
- strncpy(io_pProfile->m_wsApplianceAddress,
- i_wsApplianceAddress,
- KMS_MAX_NETWORK_ADDRESS);
- io_pProfile->m_wsApplianceAddress[KMS_MAX_NETWORK_ADDRESS] = 0;
- io_pProfile->m_iClusterDiscoveryFrequency = i_iClusterDiscoveryFrequency;
- io_pProfile->m_iTransactionTimeout = i_iTransactionTimeout;
- io_pProfile->m_iFailoverLimit = i_iFailOverLimit;
- io_pProfile->m_eKMSmode = i_eKMSmode;
-
- // if the file isn't found, create a new one
- bool bProfileExists = ProfileExists( g_wsWorkingDirectory, /* pass in default */
- io_pProfile->m_wsProfileName );
-
-#ifdef KMSUSERPKCS12
- /*
- * Fix logic for determining if this request is for enrollment.
- * Look to see if the server cert and clientkey.p12 file exist.
- * We always expect a password for Solaris which is used to
- * validate that the user has access to the clientkey data by
- * attempting to use it to open the PKCS12 file.
- */
- bool bEnrolling = !ClientKeyP12Exists(io_pProfile->m_wsProfileName);
-#else
- bool bEnrolling = i_wsEntityID && i_wsPassphrase;
-#endif
-
- if ( bSuccess && !bEnrolling && !bProfileExists )
- {
- // when not enrolling a profile must exist
- bSuccess = false;
- Log(AUDIT_CLIENT_LOAD_PROFILE,
- i_wsProfileName,
- NULL,
- "Enrollment attempted but profile could not be found" );
- }
-
- // if the file isn't found, create a new one
- if ( bSuccess && !bProfileExists )
- {
- strncpy(io_pProfile->m_wsEntityID,
- i_wsEntityID,
- KMS_MAX_ENTITY_ID );
- io_pProfile->m_wsEntityID[KMS_MAX_ENTITY_ID] = 0;
- bSuccess = CreateProfile( io_pProfile,
- g_wsWorkingDirectory,
- io_pProfile->m_wsProfileName );
- }
-
- // load profile.cfg file
- if ( bSuccess )
- {
- bSuccess = GetConfig( io_pProfile );
-
- }
-
- // if profile settings changed then update the profile storage
- if ( bSuccess &&
- ( strncmp(io_pProfile->m_wsApplianceAddress,
- i_wsApplianceAddress, KMS_MAX_NETWORK_ADDRESS ) != 0 ||
- io_pProfile->m_iClusterDiscoveryFrequency != i_iClusterDiscoveryFrequency ||
- io_pProfile->m_iTransactionTimeout != i_iTransactionTimeout ||
- io_pProfile->m_iFailoverLimit != i_iFailOverLimit
- ))
- {
- strncpy(io_pProfile->m_wsApplianceAddress,
- i_wsApplianceAddress,
- KMS_MAX_NETWORK_ADDRESS);
- io_pProfile->m_wsApplianceAddress[KMS_MAX_NETWORK_ADDRESS] = 0;
- io_pProfile->m_iClusterDiscoveryFrequency = i_iClusterDiscoveryFrequency;
- io_pProfile->m_iTransactionTimeout = i_iTransactionTimeout;
- io_pProfile->m_iFailoverLimit = i_iFailOverLimit;
-
- bSuccess = StoreConfig( io_pProfile );
- }
-
- // get PKI info from prior enrollment
- if ( bSuccess && !bEnrolling )
- {
-#ifdef KMSUSERPKCS12
- /*
- * Decrypt the PKCS12 file with the client cert and key using
- * the given password. If it fails, then return an auth failure
- * status. If success, write the client cert and key to the client file
- * so it can be used later by the SOAP SSL functions.
- */
- CCertificate* pEntityCertificate = new CCertificate;;
- CPrivateKey* pEntityPrivateKey = new CPrivateKey;
- bSuccess = GetPKCS12CertAndKey(io_pProfile,
- i_wsPassphrase,
- pEntityCertificate,
- pEntityPrivateKey);
- if (!bSuccess) {
- Log(AUDIT_CLIENT_LOAD_PROFILE,
- i_wsProfileName,
- NULL,
- "Enrollment Certificate and Private Key "\
- "were not loaded from PKCS12" );
- } else {
- /*
- * Write out the cert and key individually so GetPKIcerts
- * can use them.
- */
- bSuccess = StoreTempAgentPKI(io_pProfile,
- pEntityCertificate, pEntityPrivateKey);
- if (!bSuccess) {
- Log(AUDIT_CLIENT_LOAD_PROFILE,
- i_wsProfileName,
- NULL,
- "Enrollment Certificate and Private Key "\
- "were not stored to file." );
- }
- }
- delete pEntityCertificate;
- delete pEntityPrivateKey;
-
-#endif
- if (bSuccess)
- bSuccess = GetPKIcerts( io_pProfile );
- }
-
- // if not enrolling then previously enrolled PKI info should now be initialized
- if ( bSuccess && !bEnrolling &&
- (!io_pProfile->m_sHexHashedPassphrase ||
- !io_pProfile->m_iEnrolled ))
- {
- bSuccess = false;
- Log(AUDIT_CLIENT_LOAD_PROFILE,
- i_wsProfileName,
- NULL,
- "Enrollment Certificates and Private Key were not loaded from profile" );
- }
-
- io_pProfile->m_bIsClusterDiscoveryCalled = false;
-
- // allocate main soap struct
- struct soap* pstSoap = 0;
-
- if ( bSuccess )
- {
- pstSoap = (struct soap*)malloc( sizeof(struct soap) );
-
- io_pProfile->m_pvSoap = pstSoap;
-
- bSuccess = ( pstSoap != NULL );
-
- if ( bSuccess )
- {
- soap_init2( pstSoap,
- (SOAP_XML_STRICT | SOAP_C_UTFSTRING ),
- (SOAP_XML_STRICT | SOAP_C_UTFSTRING) );
-
-#ifdef METAWARE
- K_SetupCallbacks ( pstSoap );
-#endif
-
- soap_set_namespaces( pstSoap, KMS_Agent_namespaces );
-
- pstSoap->connect_timeout = io_pProfile->m_iTransactionTimeout;
- pstSoap->send_timeout = io_pProfile->m_iTransactionTimeout;
- pstSoap->recv_timeout = io_pProfile->m_iTransactionTimeout;
- }
- else
- {
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("Malloc %x pstSoap returned null\n",
- sizeof(struct soap));
-#endif
-
- }
- }
-
- // delete the existing cluster config if the input IP address
- // does not match one already known to the cluster config
-
- // Note that KMSClientProfile may be too large to fit on the stack, so we're
- // going to put it on the heap.
-
- KMSClientProfile* pstTempProfile = 0;
- bool bFound = false;
- int i;
-
- if ( bSuccess )
- {
- pstTempProfile = (KMSClientProfile*)malloc( sizeof(KMSClientProfile) );
- bSuccess = (pstTempProfile != 0);
-#if defined(METAWARE)
- if (!bSuccess)
- log_printf("Malloc %x pstTempProfile returned null\n",
- sizeof(KMSClientProfile));
-#endif
-
- }
-
- int bClusterInformationFound = false;
-
- if ( bSuccess )
- {
- memcpy( pstTempProfile, io_pProfile, sizeof(KMSClientProfile) );
-
- bSuccess = LoadClusterInformation( pstTempProfile, bClusterInformationFound );
- }
-
- // got cluster info from persistent storage
- if ( bSuccess && bClusterInformationFound )
- {
- // see if address is a member of the remembered cluster or is a
- // new kma, meaning this KMA joins the cluster as the
- // discovery KMA.
- for ( i = 0; i < pstTempProfile->m_iClusterNum; i++ )
- {
- bFound = (strncmp( pstTempProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
- io_pProfile->m_wsApplianceAddress,
- KMS_MAX_NETWORK_ADDRESS) == 0);
-
- if ( bFound )
- {
- break;
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- log_printf ("KMSClient_LoadProfile : Appliance Address doesn't match");
-#endif
- }
-
- if ( !bFound )
- {
-#if defined(DEBUG) && defined(METAWARE)
- log_printf ("KMSClient_LoadProfile : delete cluster");
-#endif
- DeleteCluster( pstTempProfile );
- char msg[256];
- K_snprintf(msg, 256,
- "KMSClientProfile.LoadProfile(): deleting previous cluster config, %s not found\n",
- io_pProfile->m_wsApplianceAddress);
- Log(AUDIT_CLIENT_LOAD_PROFILE,
- i_wsProfileName,
- NULL,
- msg );
- DeleteCluster( pstTempProfile );
- }
- else
- {
- // since address is a member of the persisted cluster copy the persisted cluster info to the profile
- io_pProfile->m_iClusterNum = pstTempProfile->m_iClusterNum;
- memcpy(io_pProfile->m_aCluster,
- pstTempProfile->m_aCluster,
- sizeof(KMSClusterEntry)*io_pProfile->m_iClusterNum);
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- else
- log_printf ("KMSClient_LoadProfile : no persisted cluster information");
-#endif
-
- if ( pstTempProfile )
- {
-#if defined(DEBUG) && defined(METAWARE)
- log_printf ("KMSClient_LoadProfile : free the temporary profile");
-#endif
- free( pstTempProfile );
- pstTempProfile = 0;
- }
-
- if ( bSuccess && !io_pProfile->m_iEnrolled )
- {
-#if defined(DEBUG) && defined(METAWARE)
- log_printf ("KMSClient_LoadProfile : call EnrollAgent");
-#endif
- // enroll the agent
- bSuccess = EnrollAgent( io_pProfile,
- i_wsEntityID,
- i_wsPassphrase );
- }
-#if defined(DEBUG) && defined(METAWARE)
- else if (io_pProfile->m_iEnrolled)
- log_printf ("KMSClient_LoadProfile : Already Enrolled");
-#endif
-
-
-
- if (bSuccess)
- {
- // Initialize SSL - use CLIENT AUTH
- // CLIENT_AUTHENTICATION needs the pstSoap, and expects
- // the profile io_pProfile to be full (have the other certificates
- // and keypair)
-
- if ( bSuccess )
- {
- bSuccess =
- K_soap_ssl_client_context(
- io_pProfile, // in/out
- pstSoap, // out
- SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION // in - flags
- ) == SOAP_OK;
-
- if ( !bSuccess )
- {
-#if defined(DEBUG) && defined(METAWARE)
- if (!bSuccess)
- log_printf ("KMSClient_LoadProfile : K_soap_ssl_client_context failed");
-#endif
- GetSoapFault(sSoapFaultMsg, (struct soap*)pstSoap);
- GetPeerNetworkAddress(sKmaAddress, pstSoap);
-
- LogError(io_pProfile,
- AUDIT_CLIENT_LOAD_PROFILE_SOAP_ERROR,
- NULL,
- sKmaAddress,
- sSoapFaultMsg );
- }
- }
-
- // discover the cluster
-
- if ( bSuccess &&
- io_pProfile->m_iClusterDiscoveryFrequency > 0 )
- {
- bSuccess = ( KMSClient_GetClusterInformation(
- io_pProfile,
- io_pProfile->m_wsEntitySiteID,
- sizeof(io_pProfile->m_wsEntitySiteID),
- &(io_pProfile->m_iClusterNum),
- io_pProfile->m_aCluster,
- KMS_MAX_CLUSTER_NUM) != 0 );
- // KMSClient_GetClusterInformation logs errors
-
- if (bSuccess && i_eKMSmode == FIPS_MODE)
- {
- bSuccess = !KMSClient_NoFIPSCompatibleKMAs(io_pProfile);
- if (!bSuccess)
- {
- LogError(io_pProfile,
- AUDIT_CLIENT_AGENT_LOAD_PROFILE_NO_FIPS_COMPATIBLE_KMAS_AVAILABLE,
- NULL,
- NULL,
- NULL );
- }
- }
- }
-#if defined(DEBUG) && defined(METAWARE)
- if (!bSuccess)
- log_printf ("KMSClient_LoadProfile : getClusterInformation failed");
-#endif
-
-#ifdef KMSUSERPKCS12
- /*
- * Once the SSL context is established, delete the
- * private key file.
- */
- (void) CleanupPrivateKeyFile(io_pProfile);
-#endif
- }
-#if defined(DEBUG) && defined(METAWARE)
- else if (!bSuccess)
- log_printf ("KMSClient_LoadProfile : EnrollAgent failed");
-#endif
-
- CAgentLoadBalancer *pAgentLoadBalancer = new CAgentLoadBalancer(io_pProfile);
- if(pAgentLoadBalancer == NULL)
- {
- bSuccess = false;
- }
-
-#if defined(DEBUG) && defined(METAWARE)
- if (!bSuccess)
- log_printf ("KMSClient_LoadProfile : new CAgentLoadBalancer failed");
-#endif
-
- io_pProfile->m_pAgentLoadBalancer = pAgentLoadBalancer;
-
- // create a data unit server affinity cache for Agents
-
- if ( bSuccess )
- {
- io_pProfile->m_pDataUnitCache = new CDataUnitCache();
-
- bSuccess = ( io_pProfile->m_pDataUnitCache != NULL );
- }
-
- if ( bSuccess )
- {
-#if defined(DEBUG) && defined(METAWARE)
- log_printf ("KMSClient_LoadProfile : set version to KMS_AGENT_VERSION = %x",
- KMS_AGENT_VERSION);
- log_printf ("KMSClient_LoadProfile : profile is: %x\n", io_pProfile);
-#endif
- // this is checked later by ProfileLoaded and is taken
- // to indicate that the profile was correctly loaded
- io_pProfile->m_iVersion = KMS_AGENT_VERSION;
- }
-
- if( !bSuccess )
- {
- K_DestroyMutex((K_MUTEX_HANDLE)io_pProfile->m_pLock);
- io_pProfile->m_pLock = 0;
-
- if ( io_pProfile->m_pvSoap )
- {
- soap_destroy( (struct soap*)io_pProfile->m_pvSoap );
- soap_end( (struct soap*)io_pProfile->m_pvSoap );
- soap_done( (struct soap*)io_pProfile->m_pvSoap );
-
- free( (struct soap*)io_pProfile->m_pvSoap );
- io_pProfile->m_pvSoap = 0;
-
- if( io_pProfile->m_pAgentLoadBalancer != NULL)
- {
- delete(reinterpret_cast <CAgentLoadBalancer *>(io_pProfile->m_pAgentLoadBalancer));
- }
-
- if( io_pProfile->m_pDataUnitCache != NULL)
- {
- delete(reinterpret_cast <CDataUnitCache *>(io_pProfile->m_pDataUnitCache));
- }
-
- }
-#if defined(DEBUG) && defined(METAWARE)
- log_printf ("KMSClient_LoadProfile : failed - returning");
-#endif
- }
-
- return bSuccess;
-}
-
-/**
- * compare cluster entries having equivalent KMA names (aka Appliance alias) and
- * return true if equal. Note: KMANetworkAddress comparison is handled separately
- * due to IPv4/IPv6
- */
-static bool EqualClusterEntry(
- struct KMS_Discovery::KMS_Discovery_ClusterMember const *i_pLeft,
- KMSClusterEntry const *i_pRight)
-{
- bool bEnabled = i_pRight->m_iEnabled ? true : false;
- if ( i_pLeft->Enabled != bEnabled )
- {
- return false;
- }
- if ( i_pLeft->KMAID != i_pRight->m_lApplianceID )
- {
- return false;
- }
- if ( strncmp(i_pLeft->KMASiteID,
- i_pRight->m_wsApplianceSiteID,
- KMS_MAX_ENTITY_SITE_ID) != 0 )
- {
- return false;
- }
- // Note: we now minimize persistence of cluster changes by not saving
- // whenever m_iResponding changes
-
- return true;
-}
-/**
- * @return true if the current address matches the provided IPv6Address
- * when the i_bUseIPv6 arg is true, otherwise compare the current address
- * with the IPv4Address. If i_bUseIPv6 then i_pCurrentAddress must be
- * enclosed in brackets, i.e. as in RFC 2396.
- */
-static bool EqualKMANetworkAddress (
- bool i_bUseIPv6,
- const char * const i_pIPv6Address,
- const char * const i_pIPv4Address,
- const char * const i_pCurrentAddress
- )
-{
- bool bEqualAddress = true;
-
- if ( i_pCurrentAddress == NULL )
- {
- return false;
- }
-
- if (i_bUseIPv6)
- {
- if ( i_pIPv6Address == NULL )
- {
- return false;
- }
- char sIPv6Address[KMS_MAX_NETWORK_ADDRESS] = "[";
-
- strcat(sIPv6Address, i_pIPv6Address);
-
- char * pLoc = strchr(sIPv6Address, '/');
-
- if ( pLoc != NULL )
- {
- // remove prefix from address
- *pLoc = '\0';
- }
- strcat(sIPv6Address, "]");
- bEqualAddress = strncmp(sIPv6Address, i_pCurrentAddress, KMS_MAX_NETWORK_ADDRESS) == 0;
- }
- else
- {
- if ( i_pIPv4Address == NULL )
- {
- return false;
- }
- bEqualAddress = strncmp(i_pIPv4Address, i_pCurrentAddress, KMS_MAX_NETWORK_ADDRESS) == 0;
- }
-
- return bEqualAddress;
-}
-
-/**
- * compares the profile's current cluster state with the filtered discover
- * cluster response and returns true if the repsonse
- * differs from i_pProfile->m_aCluster. A cluster has changed if the state of any
- * cluster node has changed or if the set of cluster nodes has changed.
- * The order of nodes is immaterial.
- */
-static bool ClusterConfigChanged (
- KMSClientProfile const *i_pProfile,
- char * const i_sResponseEntitySiteID,
- struct KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers const *i_pFilteredCluster)
-{
- int i, j;
-
- FATAL_ASSERT(i_pProfile);
- FATAL_ASSERT(i_pFilteredCluster);
-
- // cardinality check
- if (i_pProfile->m_iClusterNum !=
- i_pFilteredCluster->__size)
- {
- return true;
- }
-
- // check if the agent's site ID changed
- if (strncmp(i_pProfile->m_wsEntitySiteID,
- i_sResponseEntitySiteID, KMS_MAX_ENTITY_SITE_ID) != 0)
- {
- return true;
- }
-
- // for all KMAs in filtered response check if they exist unchanged in the profile
- for (i = 0; i < i_pFilteredCluster->__size; i++)
- {
- bool bFound = false;
- for (j = 0; j < i_pProfile->m_iClusterNum; j++)
- {
- if (strncmp(i_pFilteredCluster->__ptr[i].KMAName,
- i_pProfile->m_aCluster[j].m_wsApplianceAlias,
- KMS_MAX_ENTITY_ID) == 0)
- {
- bFound = true;
- if (
- !EqualKMANetworkAddress(
- strchr(i_pProfile->m_wsApplianceAddress, ':') ? true : false,
- i_pFilteredCluster->__ptr[i].KMANetworkAddressIPv6,
- i_pFilteredCluster->__ptr[i].KMANetworkAddress,
- i_pProfile->m_aCluster[j].m_wsApplianceNetworkAddress) ||
- !EqualClusterEntry((i_pFilteredCluster->__ptr + i),
- &i_pProfile->m_aCluster[j]))
-
- {
- return true;
- }
- }
- }
- if ( !bFound )
- {
- return true;
- }
- }
- return false;
-}
-
-/**
- * returns true if the string is a valid IPv6 address syntactically
- */
-static bool ValidIPv6KMAaddress( const char * const i_pIPAddress )
-{
- FATAL_ASSERT( i_pIPAddress );
-
- if ( strlen(i_pIPAddress) <= 0 )
- {
- return false;
- }
-
- // simple check
- if ( strchr( i_pIPAddress, ':'))
- {
- return true;
- }
-
- return false;
-}
-/**
- *
- */
-static void FreeFilteredCluster (
- struct KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers * const io_stFilteredCluster,
- int iLimit )
-{
- int j = 0;
- for (; j < iLimit; j++ )
- {
- free( io_stFilteredCluster->__ptr[j].KMAName );
- free( io_stFilteredCluster->__ptr[j].KMASiteID );
- free( io_stFilteredCluster->__ptr[j].KMAHostName );
- free( io_stFilteredCluster->__ptr[j].KMANetworkAddress );
- free( io_stFilteredCluster->__ptr[j].KMAVersion );
- free( io_stFilteredCluster->__ptr[j].KMAHostNameIPv6 );
- free( io_stFilteredCluster->__ptr[j].KMANetworkAddressIPv6 );
- }
-
- free( io_stFilteredCluster->__ptr );
-}
-
-/**
- * filters the discover cluster response to be less than or equal to KMS_MAX_CLUSTER_NUM KMAs. The heuristic used to filter
- * the response is the same as used by CAgentLoadBalancer::KMSClient_SortClusterArray(), FIPS compatibility, then within site,
- * then responding and enabled KMAs.
- * @param i_stResponse pointer to gsoap discover cluster service response
- * @param io_stFilteredCluster pointer to gsoap discover cluster array to be populated with the filtered list of KMAs
- * @return true on success and io_stFilteredCluster->__size less than or equal to KMS_MAX_CLUSTER_NUM,
- * otherwise io_stFilteredCluster is undefined. io_stFilteredCluster->__ptr is populated with the array of elements
- * malloc'd.
- */
-static bool FilterCluster (struct KMS_Discovery::KMS_Discovery__DiscoverClusterResponse * const i_stResponse,
- bool i_bFIPS,
- struct KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers * const io_stFilteredCluster)
-{
- /*
- * do something like KMSAgentLoadBalancer:SortClusterArray() to the stResponse array
- * return 1st KMS_MAX_CLUSTER_NUM entries and free the rest.
- */
-
- FATAL_ASSERT(i_stResponse);
- FATAL_ASSERT(io_stFilteredCluster);
-
- io_stFilteredCluster->__size = i_stResponse->ArrayOfClusterMembers.__size;
- io_stFilteredCluster->__ptr = reinterpret_cast < struct KMS_Discovery::KMS_Discovery_ClusterMember * >
- ( calloc( io_stFilteredCluster->__size,
- sizeof (struct KMS_Discovery::KMS_Discovery_ClusterMember ) ) );
-
- if (io_stFilteredCluster->__ptr == NULL)
- {
- Log(AUDIT_CLIENT_FILTER_CLUSTER_FAILED,
- NULL,
- NULL,
- "calloc failed");
- return false;
- }
-
- if (io_stFilteredCluster->__size <= 0)
- {
- Log(AUDIT_CLIENT_FILTER_CLUSTER_FAILED,
- NULL,
- NULL,
- "returned cluster size is not positive");
- return false;
- }
-
- // copy response cluster members
- for (int i = 0; i < io_stFilteredCluster->__size; i++)
- {
- bool bSuccess = true;
-
- size_t iKMANameSize = 0, iKMASiteIDSize = 0, iKMAHostNameSize = 0,
- iKMANetworkAddressSize = 0, iKMAVersionSize = 0, iKMAHostNameIPv6Size = 0,
- iKMANetworkAddressIPv6Size = 0;
-
- // allocate storage for the various struct member's arrays
- iKMANameSize = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAName)+1;
- io_stFilteredCluster->__ptr[i].KMAName = reinterpret_cast <char *> (malloc(iKMANameSize));
-
- iKMASiteIDSize = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMASiteID)+1;
- io_stFilteredCluster->__ptr[i].KMASiteID = reinterpret_cast <char *> (malloc(iKMASiteIDSize));
-
- iKMAHostNameSize = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAHostName)+1;
- io_stFilteredCluster->__ptr[i].KMAHostName = reinterpret_cast <char *> (malloc(iKMAHostNameSize));
-
- iKMANetworkAddressSize = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMANetworkAddress)+1;
- io_stFilteredCluster->__ptr[i].KMANetworkAddress = reinterpret_cast <char *> (malloc(iKMANetworkAddressSize));
-
- // KMAVersion is an optional field derived from an xml attribute in the soap interface that will not be present in 2.0 KMAs
- if (i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAVersion)
- {
- iKMAVersionSize = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAVersion)+1;
- io_stFilteredCluster->__ptr[i].KMAVersion = reinterpret_cast <char *> (malloc(iKMAVersionSize));
- if (io_stFilteredCluster->__ptr[i].KMAVersion == NULL)
- {
- bSuccess = false;
- }
- }
- else
- {
- io_stFilteredCluster->__ptr[i].KMAVersion = NULL;
- }
-
- // KMAHostNameIPv6 is an optional field derived from an xml attribute in the soap interface that will not be present in 2.0 KMAs
- if (i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAHostNameIPv6)
- {
- iKMAHostNameIPv6Size = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAHostNameIPv6)+1;
- io_stFilteredCluster->__ptr[i].KMAHostNameIPv6 = reinterpret_cast <char *> (malloc(iKMAHostNameIPv6Size));
- if ( io_stFilteredCluster->__ptr[i].KMAHostNameIPv6 == NULL )
- {
- bSuccess = false;
- }
- }
- else
- {
- io_stFilteredCluster->__ptr[i].KMAHostNameIPv6 = NULL;
- }
-
- // KMANetworkAddressIPv6 is an optional field derived from an xml attribute in the soap interface that will not be present in 2.0 KMAs
- if (i_stResponse->ArrayOfClusterMembers.__ptr[i].KMANetworkAddressIPv6)
- {
- iKMANetworkAddressIPv6Size = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMANetworkAddressIPv6)+1;
- io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6 = reinterpret_cast <char *> (malloc(iKMANetworkAddressIPv6Size));
- if ( io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6 == NULL )
- {
- bSuccess = false;
- }
- }
- else
- {
- io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6 = NULL;
- }
-
- if ( io_stFilteredCluster->__ptr[i].KMAName == NULL ||
- io_stFilteredCluster->__ptr[i].KMASiteID == NULL ||
- io_stFilteredCluster->__ptr[i].KMAHostName == NULL ||
- io_stFilteredCluster->__ptr[i].KMANetworkAddress == NULL ||
- !bSuccess )
- {
- // cleanup and return
- FreeFilteredCluster( io_stFilteredCluster, i+1 );
- Log( AUDIT_CLIENT_FILTER_CLUSTER_FAILED,
- NULL,
- NULL,
- "malloc failed" );
- return false;
- }
-
- strncpy(io_stFilteredCluster->__ptr[i].KMAName,
- i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAName,
- iKMANameSize);
- io_stFilteredCluster->__ptr[i].KMAName[iKMANameSize-1] = '\0';
-
- strncpy(io_stFilteredCluster->__ptr[i].KMASiteID,
- i_stResponse->ArrayOfClusterMembers.__ptr[i].KMASiteID,
- iKMASiteIDSize);
- io_stFilteredCluster->__ptr[i].KMASiteID[iKMASiteIDSize-1] = '\0';
-
- strncpy(io_stFilteredCluster->__ptr[i].KMAHostName,
- i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAHostName,
- iKMAHostNameSize);
- io_stFilteredCluster->__ptr[i].KMAHostName[iKMAHostNameSize-1] = '\0';
-
- strncpy(io_stFilteredCluster->__ptr[i].KMANetworkAddress,
- i_stResponse->ArrayOfClusterMembers.__ptr[i].KMANetworkAddress,
- iKMANetworkAddressSize);
- io_stFilteredCluster->__ptr[i].KMANetworkAddress[iKMANetworkAddressSize-1] = '\0';
-
- if ( io_stFilteredCluster->__ptr[i].KMAVersion )
- {
- strncpy( io_stFilteredCluster->__ptr[i].KMAVersion,
- i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAVersion,
- iKMAVersionSize );
- io_stFilteredCluster->__ptr[i].KMAVersion[iKMAVersionSize-1] = '\0';
- }
-
- if (io_stFilteredCluster->__ptr[i].KMAHostNameIPv6)
- {
- strncpy(io_stFilteredCluster->__ptr[i].KMAHostNameIPv6,
- i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAHostNameIPv6,
- iKMAHostNameIPv6Size);
- io_stFilteredCluster->__ptr[i].KMAHostNameIPv6[iKMAHostNameIPv6Size-1] = '\0';
- }
-
- if ( io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6 )
- {
- strncpy( io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6,
- i_stResponse->ArrayOfClusterMembers.__ptr[i].KMANetworkAddressIPv6,
- iKMANetworkAddressIPv6Size );
- io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6[iKMANetworkAddressIPv6Size-1] = '\0';
- }
-
- io_stFilteredCluster->__ptr[i].KMAID = i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAID;
- io_stFilteredCluster->__ptr[i].Enabled = i_stResponse->ArrayOfClusterMembers.__ptr[i].Enabled;
- io_stFilteredCluster->__ptr[i].KMS_Discovery__Locked = i_stResponse->ArrayOfClusterMembers.__ptr[i].KMS_Discovery__Locked;
-
- // set load to zero, KMA with version <= Build600 don't initialize
- // the load field from the service network
- if ( ( io_stFilteredCluster->__ptr[i].KMAVersion &&
- strcmp( io_stFilteredCluster->__ptr[i].KMAVersion, "Build600" ) <= 0 ) ||
- io_stFilteredCluster->__ptr[i].KMAVersion == NULL )
- {
- io_stFilteredCluster->__ptr[i].Load = 0;
- }
- else
- {
- io_stFilteredCluster->__ptr[i].Load = i_stResponse->ArrayOfClusterMembers.__ptr[i].Load;
- }
-
- io_stFilteredCluster->__ptr[i].Responding = i_stResponse->ArrayOfClusterMembers.__ptr[i].Responding;
-
- if (!bSuccess)
- {
- FreeFilteredCluster( io_stFilteredCluster, i );
- Log(AUDIT_CLIENT_FILTER_CLUSTER_FAILED,
- NULL,
- NULL,
- "cluster member copy failed");
- return false;
- }
- }
-
- // is filtering necessary?
- if (io_stFilteredCluster->__size <= KMS_MAX_CLUSTER_NUM)
- {
- // no filtering required
- return true;
- }
- else
- {
- char sMesg[100];
- K_snprintf(sMesg, sizeof (sMesg), "DiscoverCluster returned %d KMAs, filtering to %d ...", io_stFilteredCluster->__size, KMS_MAX_CLUSTER_NUM);
- Log(AUDIT_CLIENT_FILTER_CLUSTER,
- NULL,
- NULL,
- sMesg);
-
- }
-
- // adjust loads according to availability, site and FIPS compatibility
- {
- int i = 0;
- for (; i < io_stFilteredCluster->__size; i++)
- {
- if (io_stFilteredCluster->__ptr[i].Enabled == false
- || io_stFilteredCluster->__ptr[i].Responding == false
- || io_stFilteredCluster->__ptr[i].KMS_Discovery__Locked == true)
- {
- io_stFilteredCluster->__ptr[i].Load += 0x40;
- }
-
- if (strcmp(io_stFilteredCluster->__ptr[i].KMASiteID,
- i_stResponse->EntitySiteID) != 0)
- {
- io_stFilteredCluster->__ptr[i].Load += 0x20;
-
- }
-
- if ( i_bFIPS &&
- !FIPScompatibleKMA(io_stFilteredCluster->__ptr[i].KMAVersion))
- {
- io_stFilteredCluster->__ptr[i].Load += 0x80;
- }
- }
- }
-
- // sort ascending by load
-
- // gnome sort: the simplest sort algoritm
- {
- int i = 0;
- while (i < io_stFilteredCluster->__size)
- {
- if (i == 0 || io_stFilteredCluster->__ptr[i - 1].Load <= io_stFilteredCluster->__ptr[i].Load)
- {
- i++;
- }
- else
- {
- struct KMS_Discovery::KMS_Discovery_ClusterMember tmp = io_stFilteredCluster->__ptr[i];
- io_stFilteredCluster->__ptr[i] = io_stFilteredCluster->__ptr[i - 1];
- io_stFilteredCluster->__ptr[--i] = tmp;
- }
- }
- }
-
- // now filter the list, freeing memory allocated for copied elements that are not being retained
- {
- int i=KMS_MAX_CLUSTER_NUM;
- for (; i < io_stFilteredCluster->__size; i++)
- {
- free(io_stFilteredCluster->__ptr[i].KMAName);
- free(io_stFilteredCluster->__ptr[i].KMASiteID);
- free(io_stFilteredCluster->__ptr[i].KMAHostName);
- free(io_stFilteredCluster->__ptr[i].KMANetworkAddress);
- free(io_stFilteredCluster->__ptr[i].KMAVersion);
- free(io_stFilteredCluster->__ptr[i].KMAHostNameIPv6);
- free(io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6);
- }
- }
-
- io_stFilteredCluster->__size = KMS_MAX_CLUSTER_NUM;
-
- Log(AUDIT_CLIENT_FILTER_CLUSTER,
- NULL,
- NULL,
- "success");
-
- return true;
-};
-
-/*---------------------------------------------------------------------------
- * Function: KMSClient_GetClusterInformation
- *
- *--------------------------------------------------------------------------*/
-bool KMSClient_GetClusterInformation(
- KMSClientProfile *i_pProfile,
- utf8char *o_wsEntitySiteID,
- int i_iEntitySiteIDSize,
- int *o_pApplianceNum,
- KMSClusterEntry *o_pClusterEntryArray,
- int i_iClusterEntryArraySize)
-{
- FATAL_ASSERT(i_pProfile);
- FATAL_ASSERT( o_wsEntitySiteID );
- FATAL_ASSERT( o_pApplianceNum );
- FATAL_ASSERT( o_pClusterEntryArray );
- FATAL_ASSERT( i_iEntitySiteIDSize <= KMS_MAX_ENTITY_ID+1 );
-
- CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
-
- bool bSuccess = true;
- char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
- char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
-
- char sURL[KMS_MAX_URL+1];
-
- // set URL from the initial appliance address
- utf8cstr sApplianceAddress = i_pProfile->m_wsApplianceAddress;
-
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_GetClusterInformation : entered");
-#endif
-
- K_snprintf(sURL,
- KMS_MAX_URL,
- "https://%s:%d",
- sApplianceAddress,
- i_pProfile->m_iPortForDiscoveryService);
- strncpy(i_pProfile->m_sURL, sURL, KMS_MAX_URL);
- i_pProfile->m_sURL[KMS_MAX_URL] = 0;
-
- // allocate and initialize a new soap env for the cluster discovery call
- struct soap *pstSoap = (struct soap*)i_pProfile->m_pvDiscoverySoap;
-
- if ( !i_pProfile->m_iEnrolled )
- {
- bSuccess = false;
- }
-
- if ( bSuccess )
- {
- // allocate discovery soap runtime
- if (pstSoap == NULL )
- {
- pstSoap = soap_new();
- i_pProfile->m_pvDiscoverySoap = pstSoap;
- /* soap_copy results in a segfault in sk_free() within libcrytpo.so
- pstSoap = soap_copy( (soap*)i_pProfile->m_pvSoap );
- */
- if (pstSoap == NULL)
- {
- bSuccess = false;
- }
- else
- {
- pstSoap->connect_timeout = i_pProfile->m_iTransactionTimeout;
- pstSoap->send_timeout = i_pProfile->m_iTransactionTimeout;
- pstSoap->recv_timeout = i_pProfile->m_iTransactionTimeout;
-
- soap_set_imode( pstSoap, (SOAP_XML_STRICT | SOAP_C_UTFSTRING) );
- soap_set_omode( pstSoap, (SOAP_XML_STRICT | SOAP_C_UTFSTRING) );
-
- soap_set_namespaces( pstSoap, KMS_Discovery_namespaces );
- bSuccess = K_soap_ssl_client_context(
- i_pProfile,
- pstSoap,
- SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION
- ) == SOAP_OK;
- if ( !bSuccess )
- {
- Log(AUDIT_CLIENT_GetClusterInformation,
- NULL,
- NULL,
- "K_soap_ssl_client_context failed");
- soap_destroy(pstSoap);
- soap_end(pstSoap);
- soap_done(pstSoap);
- }
- }
- }
- }
-
- // Discovery
- struct KMS_Discovery::KMS_Discovery__DiscoverClusterResponse stResponse;
-
-#if defined(DEBUG) && defined(METAWARE)
- log_printf("KMSClient_GetClusterInformation : call KMS_Discovery_DiscoverCluster");
-#endif
-
- // SOAP - discover cluster
- if ( bSuccess )
- {
-#ifdef DEBUG
- int iStartTickCount = K_GetTickCount();
- int iEndTickCount;
- char sDiscoverTimeMsg[100];
-#endif
- bSuccess =
- KMS_Discovery::soap_call_KMS_Discovery__DiscoverCluster(
- pstSoap,
- sURL,
- NULL,
- NULL,
- stResponse ) == SOAP_OK;
-#ifdef DEBUG
- iEndTickCount = K_GetTickCount();
- sprintf(sDiscoverTimeMsg, "DiscoverCluster soapcall elapsed time=%u ms",
- iEndTickCount-iStartTickCount);
- Log(AUDIT_CLIENT_GetClusterInformation,
- NULL,
- sApplianceAddress,
- sDiscoverTimeMsg);
-#endif
-
- if ( !bSuccess )
- {
- GetSoapFault(sSoapFaultMsg, (struct soap*)pstSoap);
- GetPeerNetworkAddress(sKmaAddress, pstSoap);
- LogError(i_pProfile,AUDIT_CLIENT_GET_CLUSTER_INFORMATION_SOAP_ERROR,
- NULL,
- sKmaAddress,
- sSoapFaultMsg );
-
- if ( !ServerError( sSoapFaultMsg, pstSoap->errnum ) )
- {
- // do not failover if error is client related
- soap_destroy( pstSoap );
- soap_end( pstSoap );
- soap_free( pstSoap );
- return false;
- }
- }
-
- // If we did not succeed to Discover from the initial appliance,
- // try to discover from other appliances that we know about that are enabled.
- // Disabled Appliances are not attempted because they may have a stale view
- // of the cluster. In particular, they themselves are not aware that they
- // are disabled.
-
- if ( !bSuccess && i_pProfile->m_iClusterNum > 0 )
- {
- // Copy the profile's cluster array so that we don't have to lock the
- // profile around a SOAP call
-
- int j = 0;
- int iClusterNum = 0;
- KMSClusterEntry* aCluster =
- (KMSClusterEntry*)malloc(sizeof(KMSClusterEntry) * KMS_MAX_CLUSTER_NUM);
-
- bSuccess = ( aCluster != 0 );
-#if defined(DEBUG) && defined(METAWARE)
- if (!bSuccess)
- log_printf("Malloc %x aCluster returned null\n",
- sizeof(KMSClusterEntry) * KMS_MAX_CLUSTER_NUM);
-#endif
-
- if ( bSuccess )
- {
- iClusterNum = i_pProfile->m_iClusterNum;
- memcpy( aCluster, i_pProfile->m_aCluster,
- sizeof(KMSClusterEntry) * iClusterNum );
-
- // initialize to false since all KMAs could be disabled
- bSuccess = false;
- for ( j = 0; j < iClusterNum; j++ )
- {
- if ( aCluster[j].m_iEnabled == FALSE )
- {
- continue;
- }
-
- sApplianceAddress = aCluster[j].m_wsApplianceNetworkAddress;
- K_snprintf(sURL,
- KMS_MAX_URL,
- "https://%s:%d",
- sApplianceAddress,
- i_pProfile->m_iPortForDiscoveryService);
-
- Log(AUDIT_CLIENT_GetClusterInformation,
- NULL,
- sApplianceAddress,
- "Failing over and trying this appliance");
-
- // SOAP - discover cluster
- bSuccess =
- KMS_Discovery::soap_call_KMS_Discovery__DiscoverCluster(
- pstSoap,
- sURL,
- NULL,
- NULL,
- stResponse ) == SOAP_OK;
-
- if ( !bSuccess )
- {
- GetSoapFault(sSoapFaultMsg, (struct soap*)pstSoap);
- GetPeerNetworkAddress(sKmaAddress, pstSoap);
- LogError(i_pProfile,AUDIT_CLIENT_GET_CLUSTER_INFORMATION_SOAP_ERROR,
- NULL,
- sKmaAddress,
- sSoapFaultMsg );
- }
- else
- {
- // The discover succeeded
- break;
- }
- }
- }
-
- if ( aCluster != 0 )
- {
- free(aCluster);
- }
-
- if ( bSuccess )
- {
- // Set the Profile's initial appliance to the Appliance
- // that we just succeeded to Discover from. KMSClient_SelectAppliance()
- // persists the updated config
- KMSClient_SelectAppliance( i_pProfile,
- i_pProfile->m_aCluster[j].m_wsApplianceNetworkAddress );
- }
- }
- }
-
- if ( bSuccess )
- {
- if (((int)strlen(stResponse.EntitySiteID) > i_iEntitySiteIDSize - 1))
- {
- bSuccess = false;
- LogError(i_pProfile,AUDIT_CLIENT_GET_CLUSTER_INFORMATION,
- NULL,
- NULL,
- "returned site id size too large" );
- }
- }
-
- // copy returned cluster information into i_pProfile->m_aCluster after
- // filtering the cluster members to a list with size <= KMS_MAX_CLUSTER_NUM
- if ( bSuccess )
- {
- KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers aFilteredCluster;
-
- bSuccess = FilterCluster(&stResponse, i_pProfile->m_eKMSmode == FIPS_MODE, &aFilteredCluster);
- if (!bSuccess )
- {
- LogError(i_pProfile, AUDIT_CLIENT_GET_CLUSTER_INFORMATION,
- NULL,
- NULL,
- "cluster response filtering failed" );
- }
-
- if(bSuccess)
- {
- int i;
- bool bPersistClusterConfig = ClusterConfigChanged(i_pProfile,
- stResponse.EntitySiteID,
- &aFilteredCluster);
-
- strncpy(o_wsEntitySiteID,stResponse.EntitySiteID, i_iEntitySiteIDSize-1 );
- o_wsEntitySiteID[i_iEntitySiteIDSize-1] = '\0';
-
- strncpy(i_pProfile->m_wsEntitySiteID, stResponse.EntitySiteID, i_iEntitySiteIDSize-1 );
- i_pProfile->m_wsEntitySiteID[i_iEntitySiteIDSize-1] = '\0';
-
- // fill the aCluster array in the i_pProfile
- i_pProfile->m_iClusterNum = aFilteredCluster.__size;
- for (i = 0; i < i_pProfile->m_iClusterNum; i++)
- {
- i_pProfile->m_aCluster[i].m_lApplianceID =
- (aFilteredCluster.__ptr+i)->KMAID;
- i_pProfile->m_aCluster[i].m_iEnabled =
- (aFilteredCluster.__ptr+i)->Enabled;
- i_pProfile->m_aCluster[i].m_iResponding =
- (aFilteredCluster.__ptr+i)->Responding;
-
- i_pProfile->m_aCluster[i].m_lLoad = (aFilteredCluster.__ptr+i)->Load;
- strncpy(i_pProfile->m_aCluster[i].m_wsApplianceAlias,
- (aFilteredCluster.__ptr+i)->KMAName,
- KMS_MAX_ENTITY_ID);
- i_pProfile->m_aCluster[i].m_wsApplianceAlias[KMS_MAX_ENTITY_ID] = '\0';
- // if the m_wsApplianceAddress is IPv6 then we'll store
- // KMA IPv6 addresses if they have one
- if ( strchr( i_pProfile->m_wsApplianceAddress, ':') )
- {
- // KMAs prior to 2.1, or 2.1 KMAs at rep schema < 10
- // will not have IPv6 attributes in the soap response
- if ( (aFilteredCluster.__ptr+i)->KMANetworkAddressIPv6 &&
- ValidIPv6KMAaddress((aFilteredCluster.__ptr+i)->KMANetworkAddressIPv6))
- {
- strcpy(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress, "[");
- char * pLoc = strchr((aFilteredCluster.__ptr+i)->KMANetworkAddressIPv6,
- '/');
- if ( pLoc != NULL )
- {
- // remove prefix from address
- *pLoc = '\0';
- strcat(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
- (aFilteredCluster.__ptr+i)->KMANetworkAddressIPv6 );
- }
- else
- {
- strcat(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
- (aFilteredCluster.__ptr + i)->KMANetworkAddressIPv6);
- }
- strcat(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress, "]");
- }
- else
- {
- // use the IPv4 address
- strncpy(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
- (aFilteredCluster.__ptr+i)->KMANetworkAddress,
- KMS_MAX_NETWORK_ADDRESS);
- }
- }
- else
- {
- strncpy(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
- (aFilteredCluster.__ptr+i)->KMANetworkAddress,
- KMS_MAX_NETWORK_ADDRESS);
- }
- i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress[KMS_MAX_NETWORK_ADDRESS] = '\0';
- strncpy(i_pProfile->m_aCluster[i].m_wsApplianceSiteID,
- (aFilteredCluster.__ptr+i)->KMASiteID,
- KMS_MAX_ENTITY_SITE_ID);
- i_pProfile->m_aCluster[i].m_wsApplianceSiteID[KMS_MAX_ENTITY_SITE_ID] = '\0';
-
- if ((aFilteredCluster.__ptr + i)->KMAVersion)
- {
- strncpy(i_pProfile->m_aCluster[i].m_sKMAVersion,
- (aFilteredCluster.__ptr + i)->KMAVersion,
- KMS_MAX_VERSION_LENGTH);
- i_pProfile->m_aCluster[i].m_sKMAVersion[KMS_MAX_VERSION_LENGTH] = '\0';
- }
- else
- {
- i_pProfile->m_aCluster[i].m_sKMAVersion[0] = '\0';
- }
-
- if ((aFilteredCluster.__ptr + i)->KMS_Discovery__Locked)
- {
- i_pProfile->m_aCluster[i].m_iKMALocked = TRUE;
- }
- else
- {
- i_pProfile->m_aCluster[i].m_iKMALocked = FALSE;
- }
- }
-
- // now release malloc'd storage from filtering the cluster response
- FreeFilteredCluster( &aFilteredCluster, aFilteredCluster.__size );
-
- // fill the array specified by the caller
- *o_pApplianceNum = i_pProfile->m_iClusterNum;
- for (i = 0; i < i_pProfile->m_iClusterNum; i++)
- {
- o_pClusterEntryArray[i].m_lApplianceID = i_pProfile->m_aCluster[i].m_lApplianceID;
- o_pClusterEntryArray[i].m_iEnabled = i_pProfile->m_aCluster[i].m_iEnabled;
- o_pClusterEntryArray[i].m_iResponding = i_pProfile->m_aCluster[i].m_iResponding;
- o_pClusterEntryArray[i].m_lLoad = i_pProfile->m_aCluster[i].m_lLoad;
- strncpy(o_pClusterEntryArray[i].m_wsApplianceAlias,
- i_pProfile->m_aCluster[i].m_wsApplianceAlias,
- KMS_MAX_ENTITY_ID);
- o_pClusterEntryArray[i].m_wsApplianceAlias[KMS_MAX_ENTITY_ID] = '\0';
- strncpy(o_pClusterEntryArray[i].m_wsApplianceNetworkAddress,
- i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
- KMS_MAX_NETWORK_ADDRESS);
- o_pClusterEntryArray[i].m_wsApplianceNetworkAddress[KMS_MAX_NETWORK_ADDRESS] = '\0';
- strncpy(o_pClusterEntryArray[i].m_wsApplianceSiteID,
- i_pProfile->m_aCluster[i].m_wsApplianceSiteID,
- KMS_MAX_ENTITY_SITE_ID);
- o_pClusterEntryArray[i].m_wsApplianceSiteID[KMS_MAX_ENTITY_SITE_ID] = '\0';
- strncpy(o_pClusterEntryArray[i].m_sKMAVersion, i_pProfile->m_aCluster[i].m_sKMAVersion,
- KMS_MAX_VERSION_LENGTH);
- o_pClusterEntryArray[i].m_sKMAVersion[KMS_MAX_VERSION_LENGTH] = '\0';
- }
-
- i_pProfile->m_iLastClusterDiscoveryTime = K_GetTickCount() / 1000;
- i_pProfile->m_bIsClusterDiscoveryCalled = true;
-
- if ( bPersistClusterConfig )
- {
- bSuccess = StoreCluster(i_pProfile);
- if (!bSuccess)
- {
- Log(AUDIT_CLIENT_GetClusterInformation,
- NULL,
- NULL,
- "Could not store cluster");
- }
- }
- }
- }
-
- // cleanup
- if (pstSoap)
- {
- soap_destroy(pstSoap);
- soap_end(pstSoap);
- if (!bSuccess)
- {
- soap_free(pstSoap);
- }
- else
- {
- // we want to persist discovery soap runtime to avoid ssl handshakes so soap_free() is not called
- }
- }
-
- // if we're enrolled but cannot get cluster information from an appliance, then we'll try to load
- // it from the profile
- if ( !bSuccess && i_pProfile->m_iEnrolled )
- {
- int bClusterInformationFound = false;
-
- bSuccess = LoadClusterInformation( i_pProfile, bClusterInformationFound );
-
- if ( bSuccess && bClusterInformationFound )
- {
- Log(AUDIT_CLIENT_GetClusterInformation,
- NULL,
- NULL,
- "Using persisted cluster information");
-
- strncpy(o_wsEntitySiteID, i_pProfile->m_wsEntitySiteID, i_iEntitySiteIDSize-1);
- o_wsEntitySiteID[i_iEntitySiteIDSize-1] = '\0';
-
- // fill the array specified by the caller
- *o_pApplianceNum = i_pProfile->m_iClusterNum;
- for (int i = 0; i < i_pProfile->m_iClusterNum; i++)
- {
- o_pClusterEntryArray[i].m_lApplianceID = i_pProfile->m_aCluster[i].m_lApplianceID;
- o_pClusterEntryArray[i].m_iEnabled = i_pProfile->m_aCluster[i].m_iEnabled;
- o_pClusterEntryArray[i].m_iResponding = TRUE; // since cluster info comes from a file, set it to TRUE
-
- o_pClusterEntryArray[i].m_lLoad = i_pProfile->m_aCluster[i].m_lLoad;
- strncpy(o_pClusterEntryArray[i].m_wsApplianceAlias,
- i_pProfile->m_aCluster[i].m_wsApplianceAlias,
- KMS_MAX_ENTITY_ID);
- o_pClusterEntryArray[i].m_wsApplianceAlias[KMS_MAX_ENTITY_ID] = '\0';
- strncpy(o_pClusterEntryArray[i].m_wsApplianceNetworkAddress,
- i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
- KMS_MAX_NETWORK_ADDRESS);
- o_pClusterEntryArray[i].m_wsApplianceNetworkAddress[KMS_MAX_NETWORK_ADDRESS] = '\0';
- strncpy(o_pClusterEntryArray[i].m_wsApplianceSiteID,
- i_pProfile->m_aCluster[i].m_wsApplianceSiteID,
- KMS_MAX_ENTITY_SITE_ID);
- o_pClusterEntryArray[i].m_wsApplianceSiteID[KMS_MAX_ENTITY_SITE_ID] = '\0';
- strncpy(o_pClusterEntryArray[i].m_sKMAVersion,
- i_pProfile->m_aCluster[i].m_sKMAVersion,
- KMS_MAX_VERSION_LENGTH);
- o_pClusterEntryArray[i].m_sKMAVersion[KMS_MAX_VERSION_LENGTH] = '\0';
- }
-
- i_pProfile->m_iLastClusterDiscoveryTime = K_GetTickCount() / 1000;
- }
- else if ( bSuccess && !bClusterInformationFound )
- {
- // if we're here, then we need to return an error
- bSuccess = false;
- }
- }
-
- return bSuccess;
-}
-
-bool KMSClient_NoFIPSCompatibleKMAs(const KMSClientProfile * const i_pProfile)
-{
- bool bNoFIPScompatibleKMA = true;
- for (int i=0; i < i_pProfile->m_iClusterNum; i++)
- {
- if ( FIPScompatibleKMA(i_pProfile->m_aCluster[i].m_sKMAVersion))
- {
- bNoFIPScompatibleKMA = false;
- break;
- }
- }
- return bNoFIPScompatibleKMA;
-}
-
-/*---------------------------------------------------------------------------
- * Function: KMSClient_SelectAppliance
- *
- *--------------------------------------------------------------------------*/
-bool KMSClient_SelectAppliance(KMSClientProfile *i_pProfile,
- utf8char *i_wsApplianceAddress)
-{
- FATAL_ASSERT(i_pProfile);
- FATAL_ASSERT(i_wsApplianceAddress);
-
- CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
-
- bool bSuccess = true;
-
- if(strlen(i_wsApplianceAddress) >= KMS_MAX_NETWORK_ADDRESS)
- {
- LogError(i_pProfile,AUDIT_CLIENT_SELECT_APPLIANCE,
- NULL,
- NULL,
- "Appliance Address too large" );
- bSuccess = false;
- }
-
- if(bSuccess)
- {
- strncpy(i_pProfile->m_wsApplianceAddress,
- i_wsApplianceAddress,
- KMS_MAX_NETWORK_ADDRESS);
- i_pProfile->m_wsApplianceAddress[KMS_MAX_NETWORK_ADDRESS] = 0;
- }
-
- bSuccess = StoreConfig( i_pProfile );
-
- return bSuccess;
-}
-
-bool KMSClient_ProfileLoaded( KMSClientProfile *i_pProfile )
-{
-
-#if defined(DEBUG) && defined(METAWARE)
- log_printf ("profile: %x", i_pProfile);
- log_printf ("profile: enrolled %x", i_pProfile->m_iEnrolled);
- log_printf ("profile: version %x", i_pProfile->m_iVersion);
-#endif
-
- // more extensive tests could be performed but this should suffice
- if ( i_pProfile &&
- i_pProfile->m_iEnrolled &&
- i_pProfile->m_iVersion == KMS_AGENT_VERSION )
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-/*---------------------------------------------------------------------------
- * Function: KMSClient_DeleteProfile
- *
- *--------------------------------------------------------------------------*/
-bool KMSClient_DeleteProfile(utf8char *i_wsProfileName)
-{
- FATAL_ASSERT( i_wsProfileName && (strlen(i_wsProfileName) > 0) );
-
- bool bSuccess = true;
-
- if (ProfileExists(g_wsWorkingDirectory, /* pass in default */
- i_wsProfileName))
- {
- bSuccess = DeleteStorageProfile(i_wsProfileName);
- }
-
- return bSuccess;
-}
-
-/*---------------------------------------------------------------------------
- * Function: KMSClient_UnloadProfile
- *
- *--------------------------------------------------------------------------*/
-bool KMSClient_UnloadProfile(KMSClientProfile *i_pProfile)
-{
- if(i_pProfile != NULL && i_pProfile->m_pLock != NULL )
- {
-#ifdef KMSUSERPKCS12
- /* Delete the private client key file if it's still around */
- CleanupPrivateKeyFile(i_pProfile);
-#endif
- if (i_pProfile->m_pAgentLoadBalancer != NULL)
- {
- delete reinterpret_cast
- <CAgentLoadBalancer *> (i_pProfile->m_pAgentLoadBalancer);
- }
- if (i_pProfile->m_pDataUnitCache != NULL)
- {
- delete reinterpret_cast<CDataUnitCache *> (i_pProfile->m_pDataUnitCache);
- }
- K_DestroyMutex((K_MUTEX_HANDLE)i_pProfile->m_pLock);
- i_pProfile->m_pLock = 0;
-
- if ( i_pProfile->m_pvSoap )
- {
- soap_destroy( (struct soap*)i_pProfile->m_pvSoap );
- soap_end( (struct soap*)i_pProfile->m_pvSoap );
- soap_done( (struct soap*)i_pProfile->m_pvSoap );
-
- free( (struct soap*)i_pProfile->m_pvSoap );
- i_pProfile->m_pvSoap = 0;
- }
-
- if ( i_pProfile->m_pvDiscoverySoap)
- {
- soap_destroy( (struct soap*)i_pProfile->m_pvDiscoverySoap );
- soap_end( (struct soap*)i_pProfile->m_pvDiscoverySoap );
- soap_done( (struct soap*)i_pProfile->m_pvDiscoverySoap );
-
- free( (struct soap*)i_pProfile->m_pvDiscoverySoap );
- i_pProfile->m_pvDiscoverySoap = 0;
- }
- }
-
- i_pProfile->m_iEnrolled = FALSE;
-
- return true; /* always return true, maybe there are cases which return false in the future */
-}
-
-bool FIPScompatibleKMA(
- const char * const i_sKMAVersion) {
- return (strcmp(i_sKMAVersion,
- FIPS_COMPATIBLE_KMA_VERSION) >= 0);
-}
-
-#ifdef KMSUSERPKCS12
-extern "C"
-KMS_AGENT_STATUS
-KMSAgent_GetProfileStatus(
- char* i_pProfileName,
- KMSAGENT_PROFILE_FLAGS *flags)
-{
- /*
- * Determine how "initialized" the KMS token is by checking for
- * the profile config file and also the entity key container (pkcs#12).
- */
- if (ProfileExists(g_wsWorkingDirectory, i_pProfileName)) {
- *flags |= KMSAGENT_PROFILE_EXISTS_FLAG;
- if (ClientKeyP12Exists(i_pProfileName))
- *flags |= KMSAGENT_CLIENTKEY_EXISTS_FLAG;
- }
- return (KMS_AGENT_STATUS_OK);
-}
-#endif