xref: /onnv-gate/usr/src/lib/libkmsagent/common/KMSClientProfile.cpp (revision 12720:3db6e0082404)
1*12720SWyllys.Ingersoll@Sun.COM /*
2*12720SWyllys.Ingersoll@Sun.COM  * CDDL HEADER START
3*12720SWyllys.Ingersoll@Sun.COM  *
4*12720SWyllys.Ingersoll@Sun.COM  * The contents of this file are subject to the terms of the
5*12720SWyllys.Ingersoll@Sun.COM  * Common Development and Distribution License (the "License").
6*12720SWyllys.Ingersoll@Sun.COM  * You may not use this file except in compliance with the License.
7*12720SWyllys.Ingersoll@Sun.COM  *
8*12720SWyllys.Ingersoll@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12720SWyllys.Ingersoll@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*12720SWyllys.Ingersoll@Sun.COM  * See the License for the specific language governing permissions
11*12720SWyllys.Ingersoll@Sun.COM  * and limitations under the License.
12*12720SWyllys.Ingersoll@Sun.COM  *
13*12720SWyllys.Ingersoll@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*12720SWyllys.Ingersoll@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12720SWyllys.Ingersoll@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*12720SWyllys.Ingersoll@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*12720SWyllys.Ingersoll@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*12720SWyllys.Ingersoll@Sun.COM  *
19*12720SWyllys.Ingersoll@Sun.COM  * CDDL HEADER END
20*12720SWyllys.Ingersoll@Sun.COM  */
21*12720SWyllys.Ingersoll@Sun.COM 
22*12720SWyllys.Ingersoll@Sun.COM /*
23*12720SWyllys.Ingersoll@Sun.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*12720SWyllys.Ingersoll@Sun.COM  */
25*12720SWyllys.Ingersoll@Sun.COM 
26*12720SWyllys.Ingersoll@Sun.COM #include <stdio.h>
27*12720SWyllys.Ingersoll@Sun.COM #include <errno.h>
28*12720SWyllys.Ingersoll@Sun.COM 
29*12720SWyllys.Ingersoll@Sun.COM #if !defined(UNIX) && !defined(METAWARE)
30*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgent_direct.h"
31*12720SWyllys.Ingersoll@Sun.COM #endif
32*12720SWyllys.Ingersoll@Sun.COM 
33*12720SWyllys.Ingersoll@Sun.COM #include <string.h>
34*12720SWyllys.Ingersoll@Sun.COM 
35*12720SWyllys.Ingersoll@Sun.COM #include "KMSClientProfile.h"
36*12720SWyllys.Ingersoll@Sun.COM 
37*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgent.h"
38*12720SWyllys.Ingersoll@Sun.COM #include "KMS_CAStub.h"
39*12720SWyllys.Ingersoll@Sun.COM #include "KMS_CertificateStub.h"
40*12720SWyllys.Ingersoll@Sun.COM #include "KMS_DiscoveryStub.h"
41*12720SWyllys.Ingersoll@Sun.COM #include "KMSClientProfileImpl.h"
42*12720SWyllys.Ingersoll@Sun.COM #include "KMSAuditLogger.h"
43*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentSoapUtilities.h"
44*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentStringUtilities.h"
45*12720SWyllys.Ingersoll@Sun.COM 
46*12720SWyllys.Ingersoll@Sun.COM 
47*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentPKICommon.h" // must be before agentstorage
48*12720SWyllys.Ingersoll@Sun.COM 
49*12720SWyllys.Ingersoll@Sun.COM #include "stdsoap2.h"
50*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentStorage.h"   // uses KMSClientProfile
51*12720SWyllys.Ingersoll@Sun.COM 
52*12720SWyllys.Ingersoll@Sun.COM 
53*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentWebServiceNamespaces.h"
54*12720SWyllys.Ingersoll@Sun.COM #include "k_setupssl.h"
55*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentChallenge.h"
56*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentCryptoUtilities.h"
57*12720SWyllys.Ingersoll@Sun.COM #include "ApplianceParameters.h"
58*12720SWyllys.Ingersoll@Sun.COM #include "AutoMutex.h"
59*12720SWyllys.Ingersoll@Sun.COM 
60*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentLoadBalancer.h"
61*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentDataUnitCache.h"
62*12720SWyllys.Ingersoll@Sun.COM 
63*12720SWyllys.Ingersoll@Sun.COM #include "ClientSoapFaultCodes.h"
64*12720SWyllys.Ingersoll@Sun.COM #ifdef METAWARE
65*12720SWyllys.Ingersoll@Sun.COM #include "debug.h"
66*12720SWyllys.Ingersoll@Sun.COM #include "sizet.h"
67*12720SWyllys.Ingersoll@Sun.COM typedef unsigned char		uint8_t;
68*12720SWyllys.Ingersoll@Sun.COM typedef unsigned short		uint16_t;
69*12720SWyllys.Ingersoll@Sun.COM typedef unsigned int		uint32_t;
70*12720SWyllys.Ingersoll@Sun.COM typedef unsigned long long	uint64_t;
71*12720SWyllys.Ingersoll@Sun.COM #include "literals.h"
72*12720SWyllys.Ingersoll@Sun.COM #endif
73*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentAESKeyWrap.h"
74*12720SWyllys.Ingersoll@Sun.COM 
75*12720SWyllys.Ingersoll@Sun.COM #if defined(METAWARE) && defined(DEBUG)
76*12720SWyllys.Ingersoll@Sun.COM #include "debug.h"
77*12720SWyllys.Ingersoll@Sun.COM #endif
78*12720SWyllys.Ingersoll@Sun.COM #include "KMSAuditLogger.h"
79*12720SWyllys.Ingersoll@Sun.COM #include "KMSClientProfileImpl.h"
80*12720SWyllys.Ingersoll@Sun.COM 
81*12720SWyllys.Ingersoll@Sun.COM #ifdef METAWARE
82*12720SWyllys.Ingersoll@Sun.COM extern "C" void
83*12720SWyllys.Ingersoll@Sun.COM tnMsg( const char   *format,
84*12720SWyllys.Ingersoll@Sun.COM        ... );
85*12720SWyllys.Ingersoll@Sun.COM #endif
86*12720SWyllys.Ingersoll@Sun.COM 
87*12720SWyllys.Ingersoll@Sun.COM bool g_bUseFileLog = false;
88*12720SWyllys.Ingersoll@Sun.COM char g_wsWorkingDirectory[KMS_MAX_PATH_LENGTH+1] = "./";
89*12720SWyllys.Ingersoll@Sun.COM 
90*12720SWyllys.Ingersoll@Sun.COM 
InitializeLogging(const utf8cstr i_wsWorkingDirectory,int i_bUseFileLog)91*12720SWyllys.Ingersoll@Sun.COM static bool InitializeLogging(
92*12720SWyllys.Ingersoll@Sun.COM    const utf8cstr  i_wsWorkingDirectory,
93*12720SWyllys.Ingersoll@Sun.COM    int i_bUseFileLog )
94*12720SWyllys.Ingersoll@Sun.COM {
95*12720SWyllys.Ingersoll@Sun.COM    FATAL_ASSERT( !i_bUseFileLog || i_wsWorkingDirectory );
96*12720SWyllys.Ingersoll@Sun.COM 
97*12720SWyllys.Ingersoll@Sun.COM    bool bFileLogSuccess = true;
98*12720SWyllys.Ingersoll@Sun.COM 
99*12720SWyllys.Ingersoll@Sun.COM    g_bUseFileLog = ( i_bUseFileLog != 0 );
100*12720SWyllys.Ingersoll@Sun.COM 
101*12720SWyllys.Ingersoll@Sun.COM    // InitializeFileLogging must always be called,
102*12720SWyllys.Ingersoll@Sun.COM    // because the file is always used by FATALs.
103*12720SWyllys.Ingersoll@Sun.COM 
104*12720SWyllys.Ingersoll@Sun.COM    bFileLogSuccess = InitializeFileLogging( i_wsWorkingDirectory ) ? true:false;
105*12720SWyllys.Ingersoll@Sun.COM 
106*12720SWyllys.Ingersoll@Sun.COM    return bFileLogSuccess;
107*12720SWyllys.Ingersoll@Sun.COM }
108*12720SWyllys.Ingersoll@Sun.COM 
FinalizeLogging()109*12720SWyllys.Ingersoll@Sun.COM static void FinalizeLogging()
110*12720SWyllys.Ingersoll@Sun.COM {
111*12720SWyllys.Ingersoll@Sun.COM    // FinalizeFileLogging must always be called,
112*12720SWyllys.Ingersoll@Sun.COM    // because the file is always used by FATALs.
113*12720SWyllys.Ingersoll@Sun.COM    FinalizeFileLogging();
114*12720SWyllys.Ingersoll@Sun.COM 
115*12720SWyllys.Ingersoll@Sun.COM    return;
116*12720SWyllys.Ingersoll@Sun.COM }
117*12720SWyllys.Ingersoll@Sun.COM 
118*12720SWyllys.Ingersoll@Sun.COM 
119*12720SWyllys.Ingersoll@Sun.COM 
120*12720SWyllys.Ingersoll@Sun.COM 
121*12720SWyllys.Ingersoll@Sun.COM /*---------------------------------------------------------------------------
122*12720SWyllys.Ingersoll@Sun.COM  * Function: KMSClient_InitializeLibrary
123*12720SWyllys.Ingersoll@Sun.COM  *
124*12720SWyllys.Ingersoll@Sun.COM  *--------------------------------------------------------------------------*/
125*12720SWyllys.Ingersoll@Sun.COM 
KMSClient_InitializeLibrary(const utf8cstr i_wsWorkingDirectory,int i_bUseFileLog)126*12720SWyllys.Ingersoll@Sun.COM bool KMSClient_InitializeLibrary(
127*12720SWyllys.Ingersoll@Sun.COM    const utf8cstr  i_wsWorkingDirectory,
128*12720SWyllys.Ingersoll@Sun.COM    int i_bUseFileLog)
129*12720SWyllys.Ingersoll@Sun.COM {
130*12720SWyllys.Ingersoll@Sun.COM    bool bSuccess;
131*12720SWyllys.Ingersoll@Sun.COM 
132*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
133*12720SWyllys.Ingersoll@Sun.COM    log_printf("KMSClient_InitializeLibrary : ENTERING");
134*12720SWyllys.Ingersoll@Sun.COM #endif
135*12720SWyllys.Ingersoll@Sun.COM 
136*12720SWyllys.Ingersoll@Sun.COM    // setup SSL
137*12720SWyllys.Ingersoll@Sun.COM    bSuccess = K_SetupSSL() == 1;
138*12720SWyllys.Ingersoll@Sun.COM    if(!bSuccess)
139*12720SWyllys.Ingersoll@Sun.COM    {
140*12720SWyllys.Ingersoll@Sun.COM       return false;
141*12720SWyllys.Ingersoll@Sun.COM    }
142*12720SWyllys.Ingersoll@Sun.COM 
143*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
144*12720SWyllys.Ingersoll@Sun.COM    log_printf("KMSClient_InitializeLibrary : set current directory");
145*12720SWyllys.Ingersoll@Sun.COM #endif
146*12720SWyllys.Ingersoll@Sun.COM 
147*12720SWyllys.Ingersoll@Sun.COM    // if i_wsWorkingDirectory is null, caller means current directory
148*12720SWyllys.Ingersoll@Sun.COM    if ( i_wsWorkingDirectory != NULL )
149*12720SWyllys.Ingersoll@Sun.COM    {
150*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
151*12720SWyllys.Ingersoll@Sun.COM       log_printf("KMSClient_InitializeLibrary : check working directory");
152*12720SWyllys.Ingersoll@Sun.COM #endif
153*12720SWyllys.Ingersoll@Sun.COM 
154*12720SWyllys.Ingersoll@Sun.COM       // string is there but is empty or junk
155*12720SWyllys.Ingersoll@Sun.COM       if (strlen(i_wsWorkingDirectory) <= 0)
156*12720SWyllys.Ingersoll@Sun.COM       {
157*12720SWyllys.Ingersoll@Sun.COM          strcpy(i_wsWorkingDirectory, ".");
158*12720SWyllys.Ingersoll@Sun.COM       }
159*12720SWyllys.Ingersoll@Sun.COM 
160*12720SWyllys.Ingersoll@Sun.COM       if ( strlen(i_wsWorkingDirectory) >= KMS_MAX_PATH_LENGTH )
161*12720SWyllys.Ingersoll@Sun.COM       {
162*12720SWyllys.Ingersoll@Sun.COM          return false;
163*12720SWyllys.Ingersoll@Sun.COM       }
164*12720SWyllys.Ingersoll@Sun.COM 
165*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
166*12720SWyllys.Ingersoll@Sun.COM       log_printf("KMSClient_InitializeLibrary : set global working directory");
167*12720SWyllys.Ingersoll@Sun.COM #endif
168*12720SWyllys.Ingersoll@Sun.COM 
169*12720SWyllys.Ingersoll@Sun.COM       // set global working directory to input
170*12720SWyllys.Ingersoll@Sun.COM       strncpy(g_wsWorkingDirectory,
171*12720SWyllys.Ingersoll@Sun.COM               i_wsWorkingDirectory,
172*12720SWyllys.Ingersoll@Sun.COM               KMS_MAX_PATH_LENGTH);
173*12720SWyllys.Ingersoll@Sun.COM       g_wsWorkingDirectory[KMS_MAX_PATH_LENGTH] = 0;
174*12720SWyllys.Ingersoll@Sun.COM    }
175*12720SWyllys.Ingersoll@Sun.COM    else
176*12720SWyllys.Ingersoll@Sun.COM    {
177*12720SWyllys.Ingersoll@Sun.COM       strcpy(g_wsWorkingDirectory, ".");
178*12720SWyllys.Ingersoll@Sun.COM    }
179*12720SWyllys.Ingersoll@Sun.COM 
180*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
181*12720SWyllys.Ingersoll@Sun.COM    log_printf("KMSClient_InitializeLibrary : Initialize logging");
182*12720SWyllys.Ingersoll@Sun.COM #endif
183*12720SWyllys.Ingersoll@Sun.COM 
184*12720SWyllys.Ingersoll@Sun.COM    // initialize file logging
185*12720SWyllys.Ingersoll@Sun.COM    bSuccess = InitializeLogging( g_wsWorkingDirectory,
186*12720SWyllys.Ingersoll@Sun.COM                                  i_bUseFileLog);
187*12720SWyllys.Ingersoll@Sun.COM 
188*12720SWyllys.Ingersoll@Sun.COM    return bSuccess;
189*12720SWyllys.Ingersoll@Sun.COM }
190*12720SWyllys.Ingersoll@Sun.COM 
191*12720SWyllys.Ingersoll@Sun.COM 
192*12720SWyllys.Ingersoll@Sun.COM /*---------------------------------------------------------------------------
193*12720SWyllys.Ingersoll@Sun.COM  * Function: KMSClient_FinalizeLibrary
194*12720SWyllys.Ingersoll@Sun.COM  *--------------------------------------------------------------------------*/
KMSClient_FinalizeLibrary()195*12720SWyllys.Ingersoll@Sun.COM bool KMSClient_FinalizeLibrary()
196*12720SWyllys.Ingersoll@Sun.COM {
197*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
198*12720SWyllys.Ingersoll@Sun.COM    log_printf("KMSClient_FinalizeLibrary : ENTERING");
199*12720SWyllys.Ingersoll@Sun.COM #endif
200*12720SWyllys.Ingersoll@Sun.COM 
201*12720SWyllys.Ingersoll@Sun.COM    K_CleanupSSL();
202*12720SWyllys.Ingersoll@Sun.COM 
203*12720SWyllys.Ingersoll@Sun.COM    FinalizeLogging();
204*12720SWyllys.Ingersoll@Sun.COM 
205*12720SWyllys.Ingersoll@Sun.COM    return true; /* always */
206*12720SWyllys.Ingersoll@Sun.COM }
207*12720SWyllys.Ingersoll@Sun.COM 
208*12720SWyllys.Ingersoll@Sun.COM 
209*12720SWyllys.Ingersoll@Sun.COM int LogError_lastErrno;
210*12720SWyllys.Ingersoll@Sun.COM 
211*12720SWyllys.Ingersoll@Sun.COM 
212*12720SWyllys.Ingersoll@Sun.COM /**
213*12720SWyllys.Ingersoll@Sun.COM  * Construct a message for the KMSAuditLogger and store the message
214*12720SWyllys.Ingersoll@Sun.COM  *  in the profile as the last error message.
215*12720SWyllys.Ingersoll@Sun.COM  */
LogError_function(KMSClientProfile * i_pProfile,int i_iErrno,const char * i_sOperation,const char * i_sEntityID,const char * i_sNetworkAddress,const char * i_sMessage)216*12720SWyllys.Ingersoll@Sun.COM void LogError_function(KMSClientProfile *i_pProfile,
217*12720SWyllys.Ingersoll@Sun.COM                        int i_iErrno,
218*12720SWyllys.Ingersoll@Sun.COM                        const char* i_sOperation,
219*12720SWyllys.Ingersoll@Sun.COM                        const char* i_sEntityID,
220*12720SWyllys.Ingersoll@Sun.COM                        const char* i_sNetworkAddress,
221*12720SWyllys.Ingersoll@Sun.COM                        const char* i_sMessage )
222*12720SWyllys.Ingersoll@Sun.COM {
223*12720SWyllys.Ingersoll@Sun.COM    FATAL_ASSERT( i_pProfile && i_sOperation );
224*12720SWyllys.Ingersoll@Sun.COM 
225*12720SWyllys.Ingersoll@Sun.COM    // save for caller's use - this shouldn't be a global, but I don't
226*12720SWyllys.Ingersoll@Sun.COM    // want this as an item in the profile as I don't want it persisted
227*12720SWyllys.Ingersoll@Sun.COM    LogError_lastErrno = i_iErrno;
228*12720SWyllys.Ingersoll@Sun.COM 
229*12720SWyllys.Ingersoll@Sun.COM    // log the message to a data file (and internal logs)
230*12720SWyllys.Ingersoll@Sun.COM #ifndef METAWARE
231*12720SWyllys.Ingersoll@Sun.COM    if ( g_bUseFileLog )
232*12720SWyllys.Ingersoll@Sun.COM #endif
233*12720SWyllys.Ingersoll@Sun.COM    {
234*12720SWyllys.Ingersoll@Sun.COM       Log_function(i_iErrno,
235*12720SWyllys.Ingersoll@Sun.COM                    i_sOperation,
236*12720SWyllys.Ingersoll@Sun.COM                    i_sEntityID,
237*12720SWyllys.Ingersoll@Sun.COM                    i_sNetworkAddress,
238*12720SWyllys.Ingersoll@Sun.COM                    i_sMessage);
239*12720SWyllys.Ingersoll@Sun.COM    }
240*12720SWyllys.Ingersoll@Sun.COM 
241*12720SWyllys.Ingersoll@Sun.COM #ifdef METAWARE
242*12720SWyllys.Ingersoll@Sun.COM    /* print this to the T10000/9840 VOP */
243*12720SWyllys.Ingersoll@Sun.COM    /* NOTE the \n is important to VOP - leave it in */
244*12720SWyllys.Ingersoll@Sun.COM    tnMsg("`msg`KMS2.0:msg#=%i,op=%s\r\n",
245*12720SWyllys.Ingersoll@Sun.COM          i_iErrno,
246*12720SWyllys.Ingersoll@Sun.COM          i_sOperation);
247*12720SWyllys.Ingersoll@Sun.COM 
248*12720SWyllys.Ingersoll@Sun.COM    tnMsg("`msg`msg=%s,eid=%s,addr=%s\r\n",
249*12720SWyllys.Ingersoll@Sun.COM          i_sMessage,
250*12720SWyllys.Ingersoll@Sun.COM          i_sEntityID,
251*12720SWyllys.Ingersoll@Sun.COM          i_sNetworkAddress);
252*12720SWyllys.Ingersoll@Sun.COM 
253*12720SWyllys.Ingersoll@Sun.COM #endif
254*12720SWyllys.Ingersoll@Sun.COM 
255*12720SWyllys.Ingersoll@Sun.COM    // copy the error message into the profile (for later reference)
256*12720SWyllys.Ingersoll@Sun.COM    strncpy(i_pProfile->m_wsErrorString,
257*12720SWyllys.Ingersoll@Sun.COM            i_sOperation,
258*12720SWyllys.Ingersoll@Sun.COM            KMS_MAX_ERROR_STRING);
259*12720SWyllys.Ingersoll@Sun.COM 
260*12720SWyllys.Ingersoll@Sun.COM    // make sure to NUL out the end
261*12720SWyllys.Ingersoll@Sun.COM    i_pProfile->m_wsErrorString[KMS_MAX_ERROR_STRING] = 0;
262*12720SWyllys.Ingersoll@Sun.COM 
263*12720SWyllys.Ingersoll@Sun.COM    if ( i_sEntityID )
264*12720SWyllys.Ingersoll@Sun.COM    {
265*12720SWyllys.Ingersoll@Sun.COM       strncat(i_pProfile->m_wsErrorString,
266*12720SWyllys.Ingersoll@Sun.COM               i_sEntityID,
267*12720SWyllys.Ingersoll@Sun.COM               KMS_MAX_ERROR_STRING);
268*12720SWyllys.Ingersoll@Sun.COM    }
269*12720SWyllys.Ingersoll@Sun.COM 
270*12720SWyllys.Ingersoll@Sun.COM    if ( i_sNetworkAddress )
271*12720SWyllys.Ingersoll@Sun.COM    {
272*12720SWyllys.Ingersoll@Sun.COM       strncat(i_pProfile->m_wsErrorString,
273*12720SWyllys.Ingersoll@Sun.COM               ",Address=",
274*12720SWyllys.Ingersoll@Sun.COM               KMS_MAX_ERROR_STRING);
275*12720SWyllys.Ingersoll@Sun.COM       strncat(i_pProfile->m_wsErrorString,
276*12720SWyllys.Ingersoll@Sun.COM               i_sNetworkAddress,
277*12720SWyllys.Ingersoll@Sun.COM               KMS_MAX_ERROR_STRING);
278*12720SWyllys.Ingersoll@Sun.COM    }
279*12720SWyllys.Ingersoll@Sun.COM 
280*12720SWyllys.Ingersoll@Sun.COM    if ( i_sMessage )
281*12720SWyllys.Ingersoll@Sun.COM    {
282*12720SWyllys.Ingersoll@Sun.COM       strncat(i_pProfile->m_wsErrorString,
283*12720SWyllys.Ingersoll@Sun.COM               ",Msg=",
284*12720SWyllys.Ingersoll@Sun.COM               KMS_MAX_ERROR_STRING);
285*12720SWyllys.Ingersoll@Sun.COM       strncat(i_pProfile->m_wsErrorString,
286*12720SWyllys.Ingersoll@Sun.COM               i_sMessage,
287*12720SWyllys.Ingersoll@Sun.COM               KMS_MAX_ERROR_STRING);
288*12720SWyllys.Ingersoll@Sun.COM    }
289*12720SWyllys.Ingersoll@Sun.COM 
290*12720SWyllys.Ingersoll@Sun.COM    // make sure to NUL out the end
291*12720SWyllys.Ingersoll@Sun.COM    i_pProfile->m_wsErrorString[KMS_MAX_ERROR_STRING] = 0;
292*12720SWyllys.Ingersoll@Sun.COM 
293*12720SWyllys.Ingersoll@Sun.COM }
294*12720SWyllys.Ingersoll@Sun.COM 
295*12720SWyllys.Ingersoll@Sun.COM // see KMSClientProfileImpl.h
SSL_InvalidCertificate(const char * const i_sErrorString)296*12720SWyllys.Ingersoll@Sun.COM bool SSL_InvalidCertificate (const char * const i_sErrorString)
297*12720SWyllys.Ingersoll@Sun.COM {
298*12720SWyllys.Ingersoll@Sun.COM     if (
299*12720SWyllys.Ingersoll@Sun.COM         // OpenSSL generates this msg
300*12720SWyllys.Ingersoll@Sun.COM         strstr(i_sErrorString, "sslv3 alert certificate unknown"))
301*12720SWyllys.Ingersoll@Sun.COM     {
302*12720SWyllys.Ingersoll@Sun.COM         return true;
303*12720SWyllys.Ingersoll@Sun.COM     }
304*12720SWyllys.Ingersoll@Sun.COM     return false;
305*12720SWyllys.Ingersoll@Sun.COM 
306*12720SWyllys.Ingersoll@Sun.COM }
307*12720SWyllys.Ingersoll@Sun.COM 
308*12720SWyllys.Ingersoll@Sun.COM // see KMSClientProfileImpl.h
ServerError(const char * i_sErrorString,int i_iErrno)309*12720SWyllys.Ingersoll@Sun.COM bool ServerError (const char * i_sErrorString, int i_iErrno )
310*12720SWyllys.Ingersoll@Sun.COM {
311*12720SWyllys.Ingersoll@Sun.COM     // The Client Soap Fault Code returned by the KMA
312*12720SWyllys.Ingersoll@Sun.COM     // may be at the start of i_sErrorString or immediately
313*12720SWyllys.Ingersoll@Sun.COM     // follwing "SoapFaultString=" depending on the caller's
314*12720SWyllys.Ingersoll@Sun.COM     // string
315*12720SWyllys.Ingersoll@Sun.COM 
316*12720SWyllys.Ingersoll@Sun.COM     int iErrorCode;
317*12720SWyllys.Ingersoll@Sun.COM 
318*12720SWyllys.Ingersoll@Sun.COM     const char* sFaultstringStart  = strstr(i_sErrorString, "SoapFaultString=" );
319*12720SWyllys.Ingersoll@Sun.COM     if ( sFaultstringStart )
320*12720SWyllys.Ingersoll@Sun.COM     {
321*12720SWyllys.Ingersoll@Sun.COM         iErrorCode = GET_FAULT_CODE( sFaultstringStart + strlen("SoapFaultString=") );
322*12720SWyllys.Ingersoll@Sun.COM     }
323*12720SWyllys.Ingersoll@Sun.COM     else
324*12720SWyllys.Ingersoll@Sun.COM     {
325*12720SWyllys.Ingersoll@Sun.COM         // This may be zero if there is no error code at the start of the string.
326*12720SWyllys.Ingersoll@Sun.COM         iErrorCode = GET_FAULT_CODE( i_sErrorString );
327*12720SWyllys.Ingersoll@Sun.COM     }
328*12720SWyllys.Ingersoll@Sun.COM 
329*12720SWyllys.Ingersoll@Sun.COM     // the following is commented out so the former check can be observed.  This check is no longer
330*12720SWyllys.Ingersoll@Sun.COM     // made since invalid certificate failures may be due to a KMA that is behind on
331*12720SWyllys.Ingersoll@Sun.COM     // replication updates hence failover would succeed.
332*12720SWyllys.Ingersoll@Sun.COM //    if (
333*12720SWyllys.Ingersoll@Sun.COM //            // OpenSSL generates this msg
334*12720SWyllys.Ingersoll@Sun.COM //            SSL_InvalidCertificate(i_sErrorString))
335*12720SWyllys.Ingersoll@Sun.COM //    {
336*12720SWyllys.Ingersoll@Sun.COM //        return false;
337*12720SWyllys.Ingersoll@Sun.COM //    }
338*12720SWyllys.Ingersoll@Sun.COM 
339*12720SWyllys.Ingersoll@Sun.COM     if (
340*12720SWyllys.Ingersoll@Sun.COM        // when the KMA is locked
341*12720SWyllys.Ingersoll@Sun.COM        iErrorCode == CLIENT_ERROR_AGENT_APPLIANCE_LOCKED
342*12720SWyllys.Ingersoll@Sun.COM 
343*12720SWyllys.Ingersoll@Sun.COM        // KMS 2.2 change when the KMA is locked
344*12720SWyllys.Ingersoll@Sun.COM        || iErrorCode == CLIENT_ERROR_MANAGER_APPLIANCE_LOCKED
345*12720SWyllys.Ingersoll@Sun.COM 
346*12720SWyllys.Ingersoll@Sun.COM        // KMS 2.2 change for core security internal error
347*12720SWyllys.Ingersoll@Sun.COM        || iErrorCode == CLIENT_ERROR_MANAGER_INTERNAL
348*12720SWyllys.Ingersoll@Sun.COM 
349*12720SWyllys.Ingersoll@Sun.COM        // if the KMA's pre-gen'd key pool is depleted
350*12720SWyllys.Ingersoll@Sun.COM        || iErrorCode == CLIENT_ERROR_AGENT_NO_READY_KEYS
351*12720SWyllys.Ingersoll@Sun.COM 
352*12720SWyllys.Ingersoll@Sun.COM        // if the KMA's HSM is broke and the KMA is in FIPS mode
353*12720SWyllys.Ingersoll@Sun.COM        || iErrorCode == CLIENT_ERROR_SERVER_HSM_REQUIRED_BUT_MISSING
354*12720SWyllys.Ingersoll@Sun.COM 
355*12720SWyllys.Ingersoll@Sun.COM        // when the server is too slow
356*12720SWyllys.Ingersoll@Sun.COM        || NULL != strstr( i_sErrorString, "Timeout" )
357*12720SWyllys.Ingersoll@Sun.COM        || NULL != strstr( i_sErrorString, "Operation interrupted or timed out" )
358*12720SWyllys.Ingersoll@Sun.COM 
359*12720SWyllys.Ingersoll@Sun.COM        // The Appliance is powered down, or is not reachable
360*12720SWyllys.Ingersoll@Sun.COM        || NULL != strstr( i_sErrorString, "Connection refused" )
361*12720SWyllys.Ingersoll@Sun.COM 
362*12720SWyllys.Ingersoll@Sun.COM        || NULL != strstr( i_sErrorString, "Unknown error" )
363*12720SWyllys.Ingersoll@Sun.COM 
364*12720SWyllys.Ingersoll@Sun.COM        // SOAP EOF
365*12720SWyllys.Ingersoll@Sun.COM        || NULL != strstr( i_sErrorString, "End of file or no input:" )
366*12720SWyllys.Ingersoll@Sun.COM 
367*12720SWyllys.Ingersoll@Sun.COM        // Appliance server software is not running (while Appliance machine is OK)
368*12720SWyllys.Ingersoll@Sun.COM        || NULL != strstr( i_sErrorString, "connect failed in tcp_connect()" )
369*12720SWyllys.Ingersoll@Sun.COM 
370*12720SWyllys.Ingersoll@Sun.COM        // If the server has an internal error but still responds
371*12720SWyllys.Ingersoll@Sun.COM        || NULL != strstr( i_sErrorString, "Server Error" )
372*12720SWyllys.Ingersoll@Sun.COM 
373*12720SWyllys.Ingersoll@Sun.COM        // OpenSSL protocol errors (Note: the SSL_ERROR_SSL may be due
374*12720SWyllys.Ingersoll@Sun.COM        // to invalid client-side values, but for now it's used as a
375*12720SWyllys.Ingersoll@Sun.COM        // catch-all; a side-effect is that any actual invalid client-side
376*12720SWyllys.Ingersoll@Sun.COM        // value will cause one audit log entry to be created on each
377*12720SWyllys.Ingersoll@Sun.COM        // Appliance in the cluster).
378*12720SWyllys.Ingersoll@Sun.COM        || NULL != strstr( i_sErrorString,
379*12720SWyllys.Ingersoll@Sun.COM                        "Error observed by underlying BIO: No error" )
380*12720SWyllys.Ingersoll@Sun.COM        || NULL != strstr( i_sErrorString,
381*12720SWyllys.Ingersoll@Sun.COM                           "EOF was observed that violates the protocol" )
382*12720SWyllys.Ingersoll@Sun.COM        || NULL != strstr( i_sErrorString,
383*12720SWyllys.Ingersoll@Sun.COM                           "SSL_ERROR_SSL" ) )
384*12720SWyllys.Ingersoll@Sun.COM     {
385*12720SWyllys.Ingersoll@Sun.COM         return true;
386*12720SWyllys.Ingersoll@Sun.COM     }
387*12720SWyllys.Ingersoll@Sun.COM 
388*12720SWyllys.Ingersoll@Sun.COM #ifndef WIN32
389*12720SWyllys.Ingersoll@Sun.COM 	// check for errno values that imply connection problems to the server
390*12720SWyllys.Ingersoll@Sun.COM     switch (i_iErrno)
391*12720SWyllys.Ingersoll@Sun.COM     {
392*12720SWyllys.Ingersoll@Sun.COM         case ECONNABORTED : return true; // Connection aborted.
393*12720SWyllys.Ingersoll@Sun.COM         case ECONNREFUSED : return true; // Connection refused.
394*12720SWyllys.Ingersoll@Sun.COM         case ECONNRESET :   return true; // Connection reset.
395*12720SWyllys.Ingersoll@Sun.COM         case EHOSTUNREACH : return true; // Host is unreachable.
396*12720SWyllys.Ingersoll@Sun.COM         case ENETDOWN :     return true; // Network is down.
397*12720SWyllys.Ingersoll@Sun.COM         case ENETRESET :    return true; // Connection aborted by network.
398*12720SWyllys.Ingersoll@Sun.COM         case ENETUNREACH :  return true; // Network unreachable.
399*12720SWyllys.Ingersoll@Sun.COM         case ENOPROTOOPT :  return true; // Protocol not available.
400*12720SWyllys.Ingersoll@Sun.COM #ifndef METAWARE
401*12720SWyllys.Ingersoll@Sun.COM         case ETIME :        return true; // Stream ioctl() timeout.
402*12720SWyllys.Ingersoll@Sun.COM #endif
403*12720SWyllys.Ingersoll@Sun.COM         case ETIMEDOUT :    return true; // Connection timed out.
404*12720SWyllys.Ingersoll@Sun.COM     }
405*12720SWyllys.Ingersoll@Sun.COM #endif
406*12720SWyllys.Ingersoll@Sun.COM     // at this point we conclude its a client side issue
407*12720SWyllys.Ingersoll@Sun.COM     return false;
408*12720SWyllys.Ingersoll@Sun.COM }
409*12720SWyllys.Ingersoll@Sun.COM 
410*12720SWyllys.Ingersoll@Sun.COM /*---------------------------------------------------------------------------
411*12720SWyllys.Ingersoll@Sun.COM  * Function: KMSClient_GetLastErrorMessage
412*12720SWyllys.Ingersoll@Sun.COM  *
413*12720SWyllys.Ingersoll@Sun.COM  *--------------------------------------------------------------------------*/
414*12720SWyllys.Ingersoll@Sun.COM 
415*12720SWyllys.Ingersoll@Sun.COM // extern "C"
KMSClient_GetLastErrorMessage(KMSClientProfile * i_pProfile)416*12720SWyllys.Ingersoll@Sun.COM utf8char * KMSClient_GetLastErrorMessage(KMSClientProfile *i_pProfile)
417*12720SWyllys.Ingersoll@Sun.COM {
418*12720SWyllys.Ingersoll@Sun.COM    FATAL_ASSERT(i_pProfile);
419*12720SWyllys.Ingersoll@Sun.COM 
420*12720SWyllys.Ingersoll@Sun.COM    CAutoMutex oAutoMutex( 0 );
421*12720SWyllys.Ingersoll@Sun.COM    if ( i_pProfile->m_pLock )
422*12720SWyllys.Ingersoll@Sun.COM    {
423*12720SWyllys.Ingersoll@Sun.COM       oAutoMutex.Lock( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
424*12720SWyllys.Ingersoll@Sun.COM    }
425*12720SWyllys.Ingersoll@Sun.COM 
426*12720SWyllys.Ingersoll@Sun.COM    return i_pProfile->m_wsErrorString;
427*12720SWyllys.Ingersoll@Sun.COM }
428*12720SWyllys.Ingersoll@Sun.COM 
429*12720SWyllys.Ingersoll@Sun.COM 
430*12720SWyllys.Ingersoll@Sun.COM /*---------------------------------------------------------------------------
431*12720SWyllys.Ingersoll@Sun.COM  * Function: KMSClient_RetrieveEntityCertificate
432*12720SWyllys.Ingersoll@Sun.COM  * Get the Root CA Certificate and store it into the profile
433*12720SWyllys.Ingersoll@Sun.COM  *--------------------------------------------------------------------------*/
KMSClient_RetrieveEntityCertificate(KMSClientProfile * i_pProfile,utf8cstr i_wsEntityID,utf8cstr i_wsPassphrase,char * const o_sHexHashedPassphrase)434*12720SWyllys.Ingersoll@Sun.COM static bool KMSClient_RetrieveEntityCertificate(
435*12720SWyllys.Ingersoll@Sun.COM    KMSClientProfile* i_pProfile,
436*12720SWyllys.Ingersoll@Sun.COM    utf8cstr  i_wsEntityID,
437*12720SWyllys.Ingersoll@Sun.COM    utf8cstr  i_wsPassphrase,
438*12720SWyllys.Ingersoll@Sun.COM    char* const o_sHexHashedPassphrase )
439*12720SWyllys.Ingersoll@Sun.COM {
440*12720SWyllys.Ingersoll@Sun.COM    FATAL_ASSERT( i_pProfile && i_wsEntityID && i_wsPassphrase );
441*12720SWyllys.Ingersoll@Sun.COM 
442*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
443*12720SWyllys.Ingersoll@Sun.COM     log_printf("KMSClient_RetrieveEntityCertificate : entered");
444*12720SWyllys.Ingersoll@Sun.COM #endif
445*12720SWyllys.Ingersoll@Sun.COM 
446*12720SWyllys.Ingersoll@Sun.COM    CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
447*12720SWyllys.Ingersoll@Sun.COM    char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
448*12720SWyllys.Ingersoll@Sun.COM    char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
449*12720SWyllys.Ingersoll@Sun.COM 
450*12720SWyllys.Ingersoll@Sun.COM    strcpy(o_sHexHashedPassphrase, "");
451*12720SWyllys.Ingersoll@Sun.COM 
452*12720SWyllys.Ingersoll@Sun.COM    bool bSuccess = true;
453*12720SWyllys.Ingersoll@Sun.COM    bool bTryFailOver = false;
454*12720SWyllys.Ingersoll@Sun.COM 
455*12720SWyllys.Ingersoll@Sun.COM    struct soap *pstCASoap;
456*12720SWyllys.Ingersoll@Sun.COM    pstCASoap = (struct soap *) malloc( sizeof(struct soap) );
457*12720SWyllys.Ingersoll@Sun.COM    if(pstCASoap == NULL)
458*12720SWyllys.Ingersoll@Sun.COM    {
459*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
460*12720SWyllys.Ingersoll@Sun.COM       log_printf("Malloc %x pstCASoap returned null\n", sizeof(struct soap));
461*12720SWyllys.Ingersoll@Sun.COM #endif
462*12720SWyllys.Ingersoll@Sun.COM       LogError(i_pProfile,
463*12720SWyllys.Ingersoll@Sun.COM                LoadProfile_AUDIT_CLIENT_GET_ROOT_CA_CERTIFICATE_SOAP_ERROR,
464*12720SWyllys.Ingersoll@Sun.COM                NULL,
465*12720SWyllys.Ingersoll@Sun.COM                NULL,
466*12720SWyllys.Ingersoll@Sun.COM                "malloc failure for pstCASoap" );
467*12720SWyllys.Ingersoll@Sun.COM       return false;
468*12720SWyllys.Ingersoll@Sun.COM    }
469*12720SWyllys.Ingersoll@Sun.COM 
470*12720SWyllys.Ingersoll@Sun.COM    // initialize the SOAP connection that will get the RootCA
471*12720SWyllys.Ingersoll@Sun.COM    soap_init2( pstCASoap, (SOAP_XML_STRICT | SOAP_C_UTFSTRING), (SOAP_XML_STRICT | SOAP_C_UTFSTRING) );
472*12720SWyllys.Ingersoll@Sun.COM 
473*12720SWyllys.Ingersoll@Sun.COM #ifdef METAWARE
474*12720SWyllys.Ingersoll@Sun.COM    K_SetupCallbacks ( pstCASoap );
475*12720SWyllys.Ingersoll@Sun.COM #endif
476*12720SWyllys.Ingersoll@Sun.COM 
477*12720SWyllys.Ingersoll@Sun.COM    CCertificate* pRootCACertificate = 0;
478*12720SWyllys.Ingersoll@Sun.COM    CCertificate* pEntityCertificate = 0;
479*12720SWyllys.Ingersoll@Sun.COM    CPrivateKey*  pEntityPrivateKey = 0;
480*12720SWyllys.Ingersoll@Sun.COM 
481*12720SWyllys.Ingersoll@Sun.COM    soap_set_namespaces( pstCASoap, KMS_CA_namespaces );
482*12720SWyllys.Ingersoll@Sun.COM 
483*12720SWyllys.Ingersoll@Sun.COM    pstCASoap->connect_timeout = i_pProfile->m_iTransactionTimeout;
484*12720SWyllys.Ingersoll@Sun.COM    pstCASoap->send_timeout    = i_pProfile->m_iTransactionTimeout;
485*12720SWyllys.Ingersoll@Sun.COM    pstCASoap->recv_timeout    = i_pProfile->m_iTransactionTimeout;
486*12720SWyllys.Ingersoll@Sun.COM 
487*12720SWyllys.Ingersoll@Sun.COM    struct soap *pstCertificateSoap;
488*12720SWyllys.Ingersoll@Sun.COM 
489*12720SWyllys.Ingersoll@Sun.COM    pstCertificateSoap = (struct soap *) malloc( sizeof(struct soap) );
490*12720SWyllys.Ingersoll@Sun.COM 
491*12720SWyllys.Ingersoll@Sun.COM    if(pstCertificateSoap == NULL)
492*12720SWyllys.Ingersoll@Sun.COM    {
493*12720SWyllys.Ingersoll@Sun.COM #if defined(METAWARE)
494*12720SWyllys.Ingersoll@Sun.COM       log_printf("Malloc %x pstCertificateSoap returned null\n",
495*12720SWyllys.Ingersoll@Sun.COM                  sizeof(struct soap));
496*12720SWyllys.Ingersoll@Sun.COM #endif
497*12720SWyllys.Ingersoll@Sun.COM       soap_free( pstCASoap );
498*12720SWyllys.Ingersoll@Sun.COM       free(pstCASoap);
499*12720SWyllys.Ingersoll@Sun.COM       return false;
500*12720SWyllys.Ingersoll@Sun.COM    }
501*12720SWyllys.Ingersoll@Sun.COM 
502*12720SWyllys.Ingersoll@Sun.COM    // initialize the SOAP connection that will get the Certificate
503*12720SWyllys.Ingersoll@Sun.COM    soap_init2( pstCertificateSoap, (SOAP_XML_STRICT | SOAP_C_UTFSTRING), (SOAP_XML_STRICT | SOAP_C_UTFSTRING) );
504*12720SWyllys.Ingersoll@Sun.COM 
505*12720SWyllys.Ingersoll@Sun.COM #ifdef METAWARE
506*12720SWyllys.Ingersoll@Sun.COM    K_SetupCallbacks ( pstCertificateSoap );
507*12720SWyllys.Ingersoll@Sun.COM #endif
508*12720SWyllys.Ingersoll@Sun.COM 
509*12720SWyllys.Ingersoll@Sun.COM    soap_set_namespaces( pstCertificateSoap, KMS_Certificate_namespaces );
510*12720SWyllys.Ingersoll@Sun.COM 
511*12720SWyllys.Ingersoll@Sun.COM    pstCertificateSoap->connect_timeout = i_pProfile->m_iTransactionTimeout;
512*12720SWyllys.Ingersoll@Sun.COM    pstCertificateSoap->send_timeout = i_pProfile->m_iTransactionTimeout;
513*12720SWyllys.Ingersoll@Sun.COM    pstCertificateSoap->recv_timeout = i_pProfile->m_iTransactionTimeout;
514*12720SWyllys.Ingersoll@Sun.COM 
515*12720SWyllys.Ingersoll@Sun.COM    CAgentLoadBalancer oLoadBalancer(i_pProfile);
516*12720SWyllys.Ingersoll@Sun.COM    int iIndex = oLoadBalancer.Balance();
517*12720SWyllys.Ingersoll@Sun.COM 
518*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
519*12720SWyllys.Ingersoll@Sun.COM    log_printf("KMSClient_RetrieveEntityCertificate : call KMS_CA__RetrieveRootCACertificate");
520*12720SWyllys.Ingersoll@Sun.COM #endif
521*12720SWyllys.Ingersoll@Sun.COM 
522*12720SWyllys.Ingersoll@Sun.COM    // get the server's URL that will provide SOAP services
523*12720SWyllys.Ingersoll@Sun.COM    do
524*12720SWyllys.Ingersoll@Sun.COM    {
525*12720SWyllys.Ingersoll@Sun.COM       bSuccess = true;
526*12720SWyllys.Ingersoll@Sun.COM       bTryFailOver = false;
527*12720SWyllys.Ingersoll@Sun.COM       bool bFailedOnRetrieveRootCA = false;
528*12720SWyllys.Ingersoll@Sun.COM       const char* sURL = 0;
529*12720SWyllys.Ingersoll@Sun.COM 
530*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
531*12720SWyllys.Ingersoll@Sun.COM       {
532*12720SWyllys.Ingersoll@Sun.COM          sURL = oLoadBalancer.GetHTTPURL(iIndex,
533*12720SWyllys.Ingersoll@Sun.COM                                          i_pProfile->m_iPortForCAService);
534*12720SWyllys.Ingersoll@Sun.COM 
535*12720SWyllys.Ingersoll@Sun.COM          if ( !sURL )
536*12720SWyllys.Ingersoll@Sun.COM          {
537*12720SWyllys.Ingersoll@Sun.COM             bSuccess = false;
538*12720SWyllys.Ingersoll@Sun.COM          }
539*12720SWyllys.Ingersoll@Sun.COM       }
540*12720SWyllys.Ingersoll@Sun.COM 
541*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
542*12720SWyllys.Ingersoll@Sun.COM       {
543*12720SWyllys.Ingersoll@Sun.COM          strncpy(i_pProfile->m_sURL, sURL, KMS_MAX_URL);
544*12720SWyllys.Ingersoll@Sun.COM          i_pProfile->m_sURL[KMS_MAX_URL] = 0;
545*12720SWyllys.Ingersoll@Sun.COM       }
546*12720SWyllys.Ingersoll@Sun.COM 
547*12720SWyllys.Ingersoll@Sun.COM 
548*12720SWyllys.Ingersoll@Sun.COM       // SOAP CALL -  retrieve Root CA Certificate from the Server
549*12720SWyllys.Ingersoll@Sun.COM       struct KMS_CA::
550*12720SWyllys.Ingersoll@Sun.COM          KMS_CA__RetrieveRootCACertificateResponse stRootCACertificateResponse;
551*12720SWyllys.Ingersoll@Sun.COM 
552*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
553*12720SWyllys.Ingersoll@Sun.COM       {
554*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
555*12720SWyllys.Ingersoll@Sun.COM          log_printf("KMSClient_RetrieveCertificate : call KMS_CA__RetrieveRootCACertificate again");
556*12720SWyllys.Ingersoll@Sun.COM #endif
557*12720SWyllys.Ingersoll@Sun.COM          bSuccess =
558*12720SWyllys.Ingersoll@Sun.COM             KMS_CA::soap_call_KMS_CA__RetrieveRootCACertificate(
559*12720SWyllys.Ingersoll@Sun.COM                pstCASoap,
560*12720SWyllys.Ingersoll@Sun.COM                i_pProfile->m_sURL,
561*12720SWyllys.Ingersoll@Sun.COM                NULL,
562*12720SWyllys.Ingersoll@Sun.COM                i_wsEntityID,
563*12720SWyllys.Ingersoll@Sun.COM                stRootCACertificateResponse ) == SOAP_OK;
564*12720SWyllys.Ingersoll@Sun.COM 
565*12720SWyllys.Ingersoll@Sun.COM          if ( !bSuccess )
566*12720SWyllys.Ingersoll@Sun.COM          {
567*12720SWyllys.Ingersoll@Sun.COM             GetSoapFault(sSoapFaultMsg, (struct soap*)pstCASoap);
568*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCASoap);
569*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,
570*12720SWyllys.Ingersoll@Sun.COM                      LoadProfile_AUDIT_CLIENT_GET_ROOT_CA_CERTIFICATE_SOAP_ERROR,
571*12720SWyllys.Ingersoll@Sun.COM                      NULL,
572*12720SWyllys.Ingersoll@Sun.COM                      sKmaAddress,
573*12720SWyllys.Ingersoll@Sun.COM                      sSoapFaultMsg );
574*12720SWyllys.Ingersoll@Sun.COM 
575*12720SWyllys.Ingersoll@Sun.COM             bTryFailOver = ServerError(GET_SOAP_FAULTSTRING(pstCASoap), pstCASoap->errnum);
576*12720SWyllys.Ingersoll@Sun.COM             bFailedOnRetrieveRootCA = true;
577*12720SWyllys.Ingersoll@Sun.COM          }
578*12720SWyllys.Ingersoll@Sun.COM       }
579*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
580*12720SWyllys.Ingersoll@Sun.COM       else
581*12720SWyllys.Ingersoll@Sun.COM       {
582*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 1\n");
583*12720SWyllys.Ingersoll@Sun.COM       }
584*12720SWyllys.Ingersoll@Sun.COM #endif
585*12720SWyllys.Ingersoll@Sun.COM 
586*12720SWyllys.Ingersoll@Sun.COM 
587*12720SWyllys.Ingersoll@Sun.COM       // Validate the SOAP response
588*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
589*12720SWyllys.Ingersoll@Sun.COM       {
590*12720SWyllys.Ingersoll@Sun.COM          if ( stRootCACertificateResponse.RootCACertificate.__size < 1 ||
591*12720SWyllys.Ingersoll@Sun.COM               stRootCACertificateResponse.RootCACertificate.__ptr == NULL ||
592*12720SWyllys.Ingersoll@Sun.COM               stRootCACertificateResponse.AuthenticationHashIterationCount <
593*12720SWyllys.Ingersoll@Sun.COM               MIN_AUTHENTICATION_ITERATION_COUNT ||
594*12720SWyllys.Ingersoll@Sun.COM               stRootCACertificateResponse.AuthenticationHashIterationCount >
595*12720SWyllys.Ingersoll@Sun.COM                   MAX_AUTHENTICATION_ITERATION_COUNT ||
596*12720SWyllys.Ingersoll@Sun.COM               stRootCACertificateResponse.ClientAuthenticationChallenge.__size !=
597*12720SWyllys.Ingersoll@Sun.COM                   AUTHENTICATION_CHALLENGE_LENGTH ||
598*12720SWyllys.Ingersoll@Sun.COM               stRootCACertificateResponse.ClientAuthenticationChallenge.__ptr == NULL )
599*12720SWyllys.Ingersoll@Sun.COM          {
600*12720SWyllys.Ingersoll@Sun.COM             bSuccess = false;
601*12720SWyllys.Ingersoll@Sun.COM 
602*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCASoap);
603*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,
604*12720SWyllys.Ingersoll@Sun.COM                      AUDIT_CLIENT_GET_ROOT_CA_CERTIFICATE_INVALID_RESPONSE_FORMAT,
605*12720SWyllys.Ingersoll@Sun.COM                      NULL,
606*12720SWyllys.Ingersoll@Sun.COM                      sKmaAddress,
607*12720SWyllys.Ingersoll@Sun.COM                      NULL);
608*12720SWyllys.Ingersoll@Sun.COM          }
609*12720SWyllys.Ingersoll@Sun.COM          else
610*12720SWyllys.Ingersoll@Sun.COM          {
611*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCASoap);
612*12720SWyllys.Ingersoll@Sun.COM             Log(AUDIT_CLIENT_GET_ROOT_CA_CERTIFICATE_SUCCESS,
613*12720SWyllys.Ingersoll@Sun.COM                  NULL,
614*12720SWyllys.Ingersoll@Sun.COM                  sKmaAddress,
615*12720SWyllys.Ingersoll@Sun.COM                  NULL);
616*12720SWyllys.Ingersoll@Sun.COM          }
617*12720SWyllys.Ingersoll@Sun.COM 
618*12720SWyllys.Ingersoll@Sun.COM       }
619*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
620*12720SWyllys.Ingersoll@Sun.COM       else
621*12720SWyllys.Ingersoll@Sun.COM       {
622*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 2\n");
623*12720SWyllys.Ingersoll@Sun.COM       }
624*12720SWyllys.Ingersoll@Sun.COM #endif
625*12720SWyllys.Ingersoll@Sun.COM 
626*12720SWyllys.Ingersoll@Sun.COM       // build our RootCACertificate object
627*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
628*12720SWyllys.Ingersoll@Sun.COM       {
629*12720SWyllys.Ingersoll@Sun.COM          pRootCACertificate = new CCertificate;
630*12720SWyllys.Ingersoll@Sun.COM 
631*12720SWyllys.Ingersoll@Sun.COM          // make sure the new was successful
632*12720SWyllys.Ingersoll@Sun.COM          bSuccess = ( pRootCACertificate != 0 );
633*12720SWyllys.Ingersoll@Sun.COM       }
634*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
635*12720SWyllys.Ingersoll@Sun.COM       else
636*12720SWyllys.Ingersoll@Sun.COM       {
637*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 3\n");
638*12720SWyllys.Ingersoll@Sun.COM       }
639*12720SWyllys.Ingersoll@Sun.COM #endif
640*12720SWyllys.Ingersoll@Sun.COM 
641*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
642*12720SWyllys.Ingersoll@Sun.COM       {
643*12720SWyllys.Ingersoll@Sun.COM          // OVERLOADED Load method - 3 parameters means
644*12720SWyllys.Ingersoll@Sun.COM          // recall from BUFFER
645*12720SWyllys.Ingersoll@Sun.COM          bSuccess =
646*12720SWyllys.Ingersoll@Sun.COM             pRootCACertificate->Load(
647*12720SWyllys.Ingersoll@Sun.COM                stRootCACertificateResponse.RootCACertificate.__ptr,  // to here
648*12720SWyllys.Ingersoll@Sun.COM                stRootCACertificateResponse.RootCACertificate.__size, // size
649*12720SWyllys.Ingersoll@Sun.COM                PKI_FORMAT );                                         // ignored
650*12720SWyllys.Ingersoll@Sun.COM 
651*12720SWyllys.Ingersoll@Sun.COM          if( !bSuccess )
652*12720SWyllys.Ingersoll@Sun.COM          {
653*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCASoap);
654*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,
655*12720SWyllys.Ingersoll@Sun.COM                      AUDIT_CLIENT_GET_ROOT_CA_CERTIFICATE_INVALID_CA_CERTIFICATE_FORMAT,
656*12720SWyllys.Ingersoll@Sun.COM                      NULL,
657*12720SWyllys.Ingersoll@Sun.COM                      sKmaAddress,
658*12720SWyllys.Ingersoll@Sun.COM                      NULL);
659*12720SWyllys.Ingersoll@Sun.COM          }
660*12720SWyllys.Ingersoll@Sun.COM 
661*12720SWyllys.Ingersoll@Sun.COM       }
662*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
663*12720SWyllys.Ingersoll@Sun.COM       else
664*12720SWyllys.Ingersoll@Sun.COM       {
665*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 4\n");
666*12720SWyllys.Ingersoll@Sun.COM       }
667*12720SWyllys.Ingersoll@Sun.COM #endif
668*12720SWyllys.Ingersoll@Sun.COM 
669*12720SWyllys.Ingersoll@Sun.COM 
670*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
671*12720SWyllys.Ingersoll@Sun.COM       {
672*12720SWyllys.Ingersoll@Sun.COM          // save the built CACertificate object to a FILE (i_pProfile gets the
673*12720SWyllys.Ingersoll@Sun.COM          // persistent handle to that file)
674*12720SWyllys.Ingersoll@Sun.COM          bSuccess = StoreCACertificate( i_pProfile, pRootCACertificate );
675*12720SWyllys.Ingersoll@Sun.COM 
676*12720SWyllys.Ingersoll@Sun.COM          if ( !bSuccess )
677*12720SWyllys.Ingersoll@Sun.COM          {
678*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_SAVE_CA_CERTIFICATE_FAILED,
679*12720SWyllys.Ingersoll@Sun.COM                      NULL,
680*12720SWyllys.Ingersoll@Sun.COM                      NULL,
681*12720SWyllys.Ingersoll@Sun.COM                      NULL);
682*12720SWyllys.Ingersoll@Sun.COM          }
683*12720SWyllys.Ingersoll@Sun.COM       }
684*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
685*12720SWyllys.Ingersoll@Sun.COM       else
686*12720SWyllys.Ingersoll@Sun.COM       {
687*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 5\n");
688*12720SWyllys.Ingersoll@Sun.COM       }
689*12720SWyllys.Ingersoll@Sun.COM #endif
690*12720SWyllys.Ingersoll@Sun.COM 
691*12720SWyllys.Ingersoll@Sun.COM       //-------------------------------
692*12720SWyllys.Ingersoll@Sun.COM       // Initialize SSL - use SERVER AUTH
693*12720SWyllys.Ingersoll@Sun.COM       //-------------------------------
694*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
695*12720SWyllys.Ingersoll@Sun.COM       {
696*12720SWyllys.Ingersoll@Sun.COM          // SERVER_AUTHENTICATION needs just the pstCertificateSoap
697*12720SWyllys.Ingersoll@Sun.COM          bSuccess =
698*12720SWyllys.Ingersoll@Sun.COM             K_soap_ssl_client_context(
699*12720SWyllys.Ingersoll@Sun.COM                i_pProfile,                            // in ->m_wsProfileName,->m_sHexHashedPassphrase
700*12720SWyllys.Ingersoll@Sun.COM                pstCertificateSoap,                    // in - soap structure
701*12720SWyllys.Ingersoll@Sun.COM                SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION // in - flags
702*12720SWyllys.Ingersoll@Sun.COM                ) == SOAP_OK;
703*12720SWyllys.Ingersoll@Sun.COM 
704*12720SWyllys.Ingersoll@Sun.COM          if ( !bSuccess )
705*12720SWyllys.Ingersoll@Sun.COM          {
706*12720SWyllys.Ingersoll@Sun.COM             GetSoapFault(sSoapFaultMsg, (struct soap*)pstCertificateSoap);
707*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
708*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_SOAP_ERROR,
709*12720SWyllys.Ingersoll@Sun.COM                      NULL,
710*12720SWyllys.Ingersoll@Sun.COM                      sKmaAddress,
711*12720SWyllys.Ingersoll@Sun.COM                      sSoapFaultMsg );
712*12720SWyllys.Ingersoll@Sun.COM          }
713*12720SWyllys.Ingersoll@Sun.COM       }
714*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
715*12720SWyllys.Ingersoll@Sun.COM       else
716*12720SWyllys.Ingersoll@Sun.COM       {
717*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 6\n");
718*12720SWyllys.Ingersoll@Sun.COM       }
719*12720SWyllys.Ingersoll@Sun.COM #endif
720*12720SWyllys.Ingersoll@Sun.COM 
721*12720SWyllys.Ingersoll@Sun.COM       // hash the passphrase passed in
722*12720SWyllys.Ingersoll@Sun.COM       char sHexAuthenticationSecret[2*HASH_LENGTH+1];
723*12720SWyllys.Ingersoll@Sun.COM 
724*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
725*12720SWyllys.Ingersoll@Sun.COM       {
726*12720SWyllys.Ingersoll@Sun.COM          bSuccess = ComputeFixedEntityHashedPassphraseAndAuthenticationSecret(
727*12720SWyllys.Ingersoll@Sun.COM             i_wsPassphrase,
728*12720SWyllys.Ingersoll@Sun.COM             o_sHexHashedPassphrase,
729*12720SWyllys.Ingersoll@Sun.COM             stRootCACertificateResponse.AuthenticationHashIterationCount,
730*12720SWyllys.Ingersoll@Sun.COM             sHexAuthenticationSecret );
731*12720SWyllys.Ingersoll@Sun.COM 
732*12720SWyllys.Ingersoll@Sun.COM          if ( !bSuccess )
733*12720SWyllys.Ingersoll@Sun.COM          {
734*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,AUDIT_CLIENT_COMPUTE_FIXED_FAILED,
735*12720SWyllys.Ingersoll@Sun.COM                      NULL,
736*12720SWyllys.Ingersoll@Sun.COM                      NULL,
737*12720SWyllys.Ingersoll@Sun.COM                      NULL);
738*12720SWyllys.Ingersoll@Sun.COM          }
739*12720SWyllys.Ingersoll@Sun.COM       }
740*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
741*12720SWyllys.Ingersoll@Sun.COM       else
742*12720SWyllys.Ingersoll@Sun.COM       {
743*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 7\n");
744*12720SWyllys.Ingersoll@Sun.COM       }
745*12720SWyllys.Ingersoll@Sun.COM #endif
746*12720SWyllys.Ingersoll@Sun.COM 
747*12720SWyllys.Ingersoll@Sun.COM       // copy received Root CA into buffer for input
748*12720SWyllys.Ingersoll@Sun.COM       // into challenge-response computation
749*12720SWyllys.Ingersoll@Sun.COM       unsigned char aRootCACertificate[MAX_CERT_SIZE];
750*12720SWyllys.Ingersoll@Sun.COM       int iRootCACertificateLength;
751*12720SWyllys.Ingersoll@Sun.COM 
752*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
753*12720SWyllys.Ingersoll@Sun.COM       {
754*12720SWyllys.Ingersoll@Sun.COM          // OVERLOADED save method - save iRootCACertificateLength to aRootCACertificate
755*12720SWyllys.Ingersoll@Sun.COM          // buffer
756*12720SWyllys.Ingersoll@Sun.COM          bSuccess = pRootCACertificate->Save(
757*12720SWyllys.Ingersoll@Sun.COM             aRootCACertificate,
758*12720SWyllys.Ingersoll@Sun.COM             MAX_CERT_SIZE,
759*12720SWyllys.Ingersoll@Sun.COM             &iRootCACertificateLength,
760*12720SWyllys.Ingersoll@Sun.COM             PKI_FORMAT );
761*12720SWyllys.Ingersoll@Sun.COM 
762*12720SWyllys.Ingersoll@Sun.COM          if ( !bSuccess )
763*12720SWyllys.Ingersoll@Sun.COM          {
764*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,AUDIT_CLIENT_SAVE_ROOTCA_FAILED,
765*12720SWyllys.Ingersoll@Sun.COM                      NULL,
766*12720SWyllys.Ingersoll@Sun.COM                      NULL,
767*12720SWyllys.Ingersoll@Sun.COM                      NULL);
768*12720SWyllys.Ingersoll@Sun.COM          }
769*12720SWyllys.Ingersoll@Sun.COM       }
770*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
771*12720SWyllys.Ingersoll@Sun.COM       else
772*12720SWyllys.Ingersoll@Sun.COM       {
773*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 8\n");
774*12720SWyllys.Ingersoll@Sun.COM       }
775*12720SWyllys.Ingersoll@Sun.COM #endif
776*12720SWyllys.Ingersoll@Sun.COM 
777*12720SWyllys.Ingersoll@Sun.COM       // respond to server's challenge
778*12720SWyllys.Ingersoll@Sun.COM       unsigned char aAuthenticationSecret[AUTHENTICATION_SECRET_LENGTH];
779*12720SWyllys.Ingersoll@Sun.COM       unsigned char
780*12720SWyllys.Ingersoll@Sun.COM          aClientAuthenticationChallengeResponse[AUTHENTICATION_RESPONSE_LENGTH];
781*12720SWyllys.Ingersoll@Sun.COM 
782*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
783*12720SWyllys.Ingersoll@Sun.COM       {
784*12720SWyllys.Ingersoll@Sun.COM          FATAL_ASSERT( AUTHENTICATION_SECRET_LENGTH ==
785*12720SWyllys.Ingersoll@Sun.COM                        ConvertUTF8HexStringToBinary(
786*12720SWyllys.Ingersoll@Sun.COM                           sHexAuthenticationSecret, NULL ) );
787*12720SWyllys.Ingersoll@Sun.COM 
788*12720SWyllys.Ingersoll@Sun.COM          ConvertUTF8HexStringToBinary(
789*12720SWyllys.Ingersoll@Sun.COM             sHexAuthenticationSecret, aAuthenticationSecret );
790*12720SWyllys.Ingersoll@Sun.COM 
791*12720SWyllys.Ingersoll@Sun.COM          // client authentication response
792*12720SWyllys.Ingersoll@Sun.COM          bSuccess = ComputeChallengeResponse(
793*12720SWyllys.Ingersoll@Sun.COM             aAuthenticationSecret,
794*12720SWyllys.Ingersoll@Sun.COM             AUTHENTICATION_SECRET_LENGTH,
795*12720SWyllys.Ingersoll@Sun.COM             aRootCACertificate,
796*12720SWyllys.Ingersoll@Sun.COM             iRootCACertificateLength,
797*12720SWyllys.Ingersoll@Sun.COM             stRootCACertificateResponse.ClientAuthenticationChallenge.__ptr,
798*12720SWyllys.Ingersoll@Sun.COM             AUTHENTICATION_CHALLENGE_LENGTH,
799*12720SWyllys.Ingersoll@Sun.COM             aClientAuthenticationChallengeResponse,
800*12720SWyllys.Ingersoll@Sun.COM             AUTHENTICATION_RESPONSE_LENGTH );
801*12720SWyllys.Ingersoll@Sun.COM 
802*12720SWyllys.Ingersoll@Sun.COM          if ( !bSuccess )
803*12720SWyllys.Ingersoll@Sun.COM          {
804*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,AUDIT_CLIENT_COMPUTE_CHALLENGE_RESPONSE_FAILED,
805*12720SWyllys.Ingersoll@Sun.COM                      NULL,
806*12720SWyllys.Ingersoll@Sun.COM                      NULL,
807*12720SWyllys.Ingersoll@Sun.COM                      NULL);
808*12720SWyllys.Ingersoll@Sun.COM          }
809*12720SWyllys.Ingersoll@Sun.COM       }
810*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
811*12720SWyllys.Ingersoll@Sun.COM       else
812*12720SWyllys.Ingersoll@Sun.COM       {
813*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 9\n");
814*12720SWyllys.Ingersoll@Sun.COM       }
815*12720SWyllys.Ingersoll@Sun.COM #endif
816*12720SWyllys.Ingersoll@Sun.COM 
817*12720SWyllys.Ingersoll@Sun.COM       struct KMS_Certificate::xsd__hexBinary stClientAuthenticationResponse;
818*12720SWyllys.Ingersoll@Sun.COM 
819*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
820*12720SWyllys.Ingersoll@Sun.COM       {
821*12720SWyllys.Ingersoll@Sun.COM          stClientAuthenticationResponse.__size =
822*12720SWyllys.Ingersoll@Sun.COM             AUTHENTICATION_RESPONSE_LENGTH;
823*12720SWyllys.Ingersoll@Sun.COM          stClientAuthenticationResponse.__ptr =
824*12720SWyllys.Ingersoll@Sun.COM             (unsigned char*)soap_malloc(
825*12720SWyllys.Ingersoll@Sun.COM                pstCertificateSoap, AUTHENTICATION_RESPONSE_LENGTH );
826*12720SWyllys.Ingersoll@Sun.COM 
827*12720SWyllys.Ingersoll@Sun.COM          if ( stClientAuthenticationResponse.__ptr != NULL )
828*12720SWyllys.Ingersoll@Sun.COM          {
829*12720SWyllys.Ingersoll@Sun.COM             memcpy( stClientAuthenticationResponse.__ptr,
830*12720SWyllys.Ingersoll@Sun.COM                     aClientAuthenticationChallengeResponse,
831*12720SWyllys.Ingersoll@Sun.COM                     AUTHENTICATION_RESPONSE_LENGTH );
832*12720SWyllys.Ingersoll@Sun.COM          }
833*12720SWyllys.Ingersoll@Sun.COM          else
834*12720SWyllys.Ingersoll@Sun.COM          {
835*12720SWyllys.Ingersoll@Sun.COM             bSuccess = false;
836*12720SWyllys.Ingersoll@Sun.COM          }
837*12720SWyllys.Ingersoll@Sun.COM       }
838*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
839*12720SWyllys.Ingersoll@Sun.COM       else
840*12720SWyllys.Ingersoll@Sun.COM       {
841*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 10\n");
842*12720SWyllys.Ingersoll@Sun.COM       }
843*12720SWyllys.Ingersoll@Sun.COM #endif
844*12720SWyllys.Ingersoll@Sun.COM 
845*12720SWyllys.Ingersoll@Sun.COM       // generate challenge nonce
846*12720SWyllys.Ingersoll@Sun.COM       struct KMS_Certificate::xsd__hexBinary stServerAuthenticationChallenge;
847*12720SWyllys.Ingersoll@Sun.COM 
848*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
849*12720SWyllys.Ingersoll@Sun.COM       {
850*12720SWyllys.Ingersoll@Sun.COM          stServerAuthenticationChallenge.__size =
851*12720SWyllys.Ingersoll@Sun.COM             AUTHENTICATION_CHALLENGE_LENGTH;
852*12720SWyllys.Ingersoll@Sun.COM          stServerAuthenticationChallenge.__ptr =
853*12720SWyllys.Ingersoll@Sun.COM             (unsigned char*)soap_malloc( pstCertificateSoap,
854*12720SWyllys.Ingersoll@Sun.COM                                          AUTHENTICATION_CHALLENGE_LENGTH );
855*12720SWyllys.Ingersoll@Sun.COM 
856*12720SWyllys.Ingersoll@Sun.COM          bSuccess = ( stServerAuthenticationChallenge.__ptr != NULL );
857*12720SWyllys.Ingersoll@Sun.COM       }
858*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
859*12720SWyllys.Ingersoll@Sun.COM       else
860*12720SWyllys.Ingersoll@Sun.COM       {
861*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 11\n");
862*12720SWyllys.Ingersoll@Sun.COM       }
863*12720SWyllys.Ingersoll@Sun.COM #endif
864*12720SWyllys.Ingersoll@Sun.COM 
865*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
866*12720SWyllys.Ingersoll@Sun.COM       {
867*12720SWyllys.Ingersoll@Sun.COM          bSuccess = GetPseudorandomBytes(
868*12720SWyllys.Ingersoll@Sun.COM             AUTHENTICATION_CHALLENGE_LENGTH,
869*12720SWyllys.Ingersoll@Sun.COM             stServerAuthenticationChallenge.__ptr );
870*12720SWyllys.Ingersoll@Sun.COM       }
871*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
872*12720SWyllys.Ingersoll@Sun.COM       else
873*12720SWyllys.Ingersoll@Sun.COM       {
874*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 12\n");
875*12720SWyllys.Ingersoll@Sun.COM       }
876*12720SWyllys.Ingersoll@Sun.COM #endif
877*12720SWyllys.Ingersoll@Sun.COM 
878*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
879*12720SWyllys.Ingersoll@Sun.COM       {
880*12720SWyllys.Ingersoll@Sun.COM          sURL = oLoadBalancer.GetHTTPSURL(iIndex,
881*12720SWyllys.Ingersoll@Sun.COM                                           i_pProfile->
882*12720SWyllys.Ingersoll@Sun.COM                                           m_iPortForCertificateService);
883*12720SWyllys.Ingersoll@Sun.COM 
884*12720SWyllys.Ingersoll@Sun.COM          if ( !sURL )
885*12720SWyllys.Ingersoll@Sun.COM          {
886*12720SWyllys.Ingersoll@Sun.COM             bSuccess = false;
887*12720SWyllys.Ingersoll@Sun.COM          }
888*12720SWyllys.Ingersoll@Sun.COM       }
889*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
890*12720SWyllys.Ingersoll@Sun.COM       else
891*12720SWyllys.Ingersoll@Sun.COM       {
892*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 13\n");
893*12720SWyllys.Ingersoll@Sun.COM       }
894*12720SWyllys.Ingersoll@Sun.COM #endif
895*12720SWyllys.Ingersoll@Sun.COM 
896*12720SWyllys.Ingersoll@Sun.COM       // Verify that the same URL is used for Root CA Certificate
897*12720SWyllys.Ingersoll@Sun.COM       // retrieval as for Entity Certificate retrieval
898*12720SWyllys.Ingersoll@Sun.COM 
899*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
900*12720SWyllys.Ingersoll@Sun.COM       {
901*12720SWyllys.Ingersoll@Sun.COM          char sTempCAURL[KMS_MAX_URL + 1];
902*12720SWyllys.Ingersoll@Sun.COM          strncpy( sTempCAURL, i_pProfile->m_sURL, KMS_MAX_URL );
903*12720SWyllys.Ingersoll@Sun.COM          sTempCAURL[KMS_MAX_URL] = 0;
904*12720SWyllys.Ingersoll@Sun.COM 
905*12720SWyllys.Ingersoll@Sun.COM          char * sRetrieveRootCACertificateURL = strtok( sTempCAURL, ":" );
906*12720SWyllys.Ingersoll@Sun.COM 
907*12720SWyllys.Ingersoll@Sun.COM          sRetrieveRootCACertificateURL = strtok(NULL, ":");
908*12720SWyllys.Ingersoll@Sun.COM 
909*12720SWyllys.Ingersoll@Sun.COM          char sTempAgentURL[KMS_MAX_URL + 1];
910*12720SWyllys.Ingersoll@Sun.COM          strncpy( sTempAgentURL, sURL, KMS_MAX_URL );
911*12720SWyllys.Ingersoll@Sun.COM          sTempAgentURL[KMS_MAX_URL] = 0;
912*12720SWyllys.Ingersoll@Sun.COM          char * sRetrieveAgentCertificateURL = strtok( sTempAgentURL, ":" );
913*12720SWyllys.Ingersoll@Sun.COM          sRetrieveAgentCertificateURL = strtok(NULL, ":");
914*12720SWyllys.Ingersoll@Sun.COM 
915*12720SWyllys.Ingersoll@Sun.COM          FATAL_ASSERT( strcmp( sRetrieveRootCACertificateURL,
916*12720SWyllys.Ingersoll@Sun.COM                                sRetrieveAgentCertificateURL ) == 0 );
917*12720SWyllys.Ingersoll@Sun.COM 
918*12720SWyllys.Ingersoll@Sun.COM          strncpy(i_pProfile->m_sURL, sURL, KMS_MAX_URL);
919*12720SWyllys.Ingersoll@Sun.COM          i_pProfile->m_sURL[KMS_MAX_URL] = 0;
920*12720SWyllys.Ingersoll@Sun.COM       }
921*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
922*12720SWyllys.Ingersoll@Sun.COM       else
923*12720SWyllys.Ingersoll@Sun.COM       {
924*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 14\n");
925*12720SWyllys.Ingersoll@Sun.COM       }
926*12720SWyllys.Ingersoll@Sun.COM #endif
927*12720SWyllys.Ingersoll@Sun.COM 
928*12720SWyllys.Ingersoll@Sun.COM       KMS_Certificate::KMS_Certificate__RetrieveEntityCertificateResponse
929*12720SWyllys.Ingersoll@Sun.COM          stRetrieveEntityCertificateResponse;
930*12720SWyllys.Ingersoll@Sun.COM 
931*12720SWyllys.Ingersoll@Sun.COM       // SOAP - retrieve ENTITY Certificate, passing the challenge response,
932*12720SWyllys.Ingersoll@Sun.COM       // a challenge to the server and get back the server's response
933*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
934*12720SWyllys.Ingersoll@Sun.COM       {
935*12720SWyllys.Ingersoll@Sun.COM          bSuccess =
936*12720SWyllys.Ingersoll@Sun.COM             KMS_Certificate::soap_call_KMS_Certificate__RetrieveEntityCertificate(
937*12720SWyllys.Ingersoll@Sun.COM                pstCertificateSoap,
938*12720SWyllys.Ingersoll@Sun.COM                sURL,
939*12720SWyllys.Ingersoll@Sun.COM                NULL,
940*12720SWyllys.Ingersoll@Sun.COM                (utf8cstr )i_wsEntityID,
941*12720SWyllys.Ingersoll@Sun.COM                stClientAuthenticationResponse,
942*12720SWyllys.Ingersoll@Sun.COM                stServerAuthenticationChallenge,
943*12720SWyllys.Ingersoll@Sun.COM                stRetrieveEntityCertificateResponse ) == SOAP_OK;
944*12720SWyllys.Ingersoll@Sun.COM 
945*12720SWyllys.Ingersoll@Sun.COM          if( !bSuccess )
946*12720SWyllys.Ingersoll@Sun.COM          {
947*12720SWyllys.Ingersoll@Sun.COM             GetSoapFault(sSoapFaultMsg, (struct soap*)pstCertificateSoap);
948*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
949*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_SOAP_ERROR,
950*12720SWyllys.Ingersoll@Sun.COM                      NULL,
951*12720SWyllys.Ingersoll@Sun.COM                      sKmaAddress,
952*12720SWyllys.Ingersoll@Sun.COM                      sSoapFaultMsg );
953*12720SWyllys.Ingersoll@Sun.COM 
954*12720SWyllys.Ingersoll@Sun.COM             bTryFailOver = ServerError(GET_SOAP_FAULTSTRING(pstCertificateSoap),
955*12720SWyllys.Ingersoll@Sun.COM                                         pstCertificateSoap->errnum);
956*12720SWyllys.Ingersoll@Sun.COM          }
957*12720SWyllys.Ingersoll@Sun.COM       }
958*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
959*12720SWyllys.Ingersoll@Sun.COM       else
960*12720SWyllys.Ingersoll@Sun.COM       {
961*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 15\n");
962*12720SWyllys.Ingersoll@Sun.COM       }
963*12720SWyllys.Ingersoll@Sun.COM #endif
964*12720SWyllys.Ingersoll@Sun.COM 
965*12720SWyllys.Ingersoll@Sun.COM       // Validate the response structure
966*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
967*12720SWyllys.Ingersoll@Sun.COM       {
968*12720SWyllys.Ingersoll@Sun.COM          if ( stRetrieveEntityCertificateResponse.
969*12720SWyllys.Ingersoll@Sun.COM               ServerAuthenticationResponse.__ptr == NULL
970*12720SWyllys.Ingersoll@Sun.COM 
971*12720SWyllys.Ingersoll@Sun.COM               || stRetrieveEntityCertificateResponse.
972*12720SWyllys.Ingersoll@Sun.COM               ServerAuthenticationResponse.__size !=
973*12720SWyllys.Ingersoll@Sun.COM               AUTHENTICATION_RESPONSE_LENGTH
974*12720SWyllys.Ingersoll@Sun.COM 
975*12720SWyllys.Ingersoll@Sun.COM               || stRetrieveEntityCertificateResponse.Certificate.__size < 1
976*12720SWyllys.Ingersoll@Sun.COM 
977*12720SWyllys.Ingersoll@Sun.COM               || stRetrieveEntityCertificateResponse.Certificate.__ptr == 0
978*12720SWyllys.Ingersoll@Sun.COM 
979*12720SWyllys.Ingersoll@Sun.COM               || stRetrieveEntityCertificateResponse.
980*12720SWyllys.Ingersoll@Sun.COM               WrappedPrivateKeyMaterial.__size < 1
981*12720SWyllys.Ingersoll@Sun.COM 
982*12720SWyllys.Ingersoll@Sun.COM               || stRetrieveEntityCertificateResponse.
983*12720SWyllys.Ingersoll@Sun.COM               WrappedPrivateKeyMaterial.__ptr == 0 )
984*12720SWyllys.Ingersoll@Sun.COM          {
985*12720SWyllys.Ingersoll@Sun.COM             bSuccess = false;
986*12720SWyllys.Ingersoll@Sun.COM 
987*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
988*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_INVALID_RESPONSE_FORMAT,
989*12720SWyllys.Ingersoll@Sun.COM                      NULL,
990*12720SWyllys.Ingersoll@Sun.COM                      sKmaAddress,
991*12720SWyllys.Ingersoll@Sun.COM                      NULL );
992*12720SWyllys.Ingersoll@Sun.COM          }
993*12720SWyllys.Ingersoll@Sun.COM          else
994*12720SWyllys.Ingersoll@Sun.COM          {
995*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
996*12720SWyllys.Ingersoll@Sun.COM             Log(AUDIT_CLIENT_GET_CERTIFICATE_SUCCESS,
997*12720SWyllys.Ingersoll@Sun.COM                  NULL,
998*12720SWyllys.Ingersoll@Sun.COM                  sKmaAddress,
999*12720SWyllys.Ingersoll@Sun.COM                  NULL );
1000*12720SWyllys.Ingersoll@Sun.COM          }
1001*12720SWyllys.Ingersoll@Sun.COM      }
1002*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1003*12720SWyllys.Ingersoll@Sun.COM       else
1004*12720SWyllys.Ingersoll@Sun.COM       {
1005*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 16\n");
1006*12720SWyllys.Ingersoll@Sun.COM       }
1007*12720SWyllys.Ingersoll@Sun.COM #endif
1008*12720SWyllys.Ingersoll@Sun.COM 
1009*12720SWyllys.Ingersoll@Sun.COM       // if valid, calculate the correct challenge-response
1010*12720SWyllys.Ingersoll@Sun.COM       unsigned char
1011*12720SWyllys.Ingersoll@Sun.COM          aServerAuthenticationChallengeResponse[AUTHENTICATION_RESPONSE_LENGTH];
1012*12720SWyllys.Ingersoll@Sun.COM 
1013*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
1014*12720SWyllys.Ingersoll@Sun.COM       {
1015*12720SWyllys.Ingersoll@Sun.COM          bSuccess = ComputeChallengeResponse(
1016*12720SWyllys.Ingersoll@Sun.COM             aAuthenticationSecret,
1017*12720SWyllys.Ingersoll@Sun.COM             AUTHENTICATION_SECRET_LENGTH,
1018*12720SWyllys.Ingersoll@Sun.COM             aRootCACertificate,
1019*12720SWyllys.Ingersoll@Sun.COM             iRootCACertificateLength,
1020*12720SWyllys.Ingersoll@Sun.COM             stServerAuthenticationChallenge.__ptr,
1021*12720SWyllys.Ingersoll@Sun.COM             AUTHENTICATION_CHALLENGE_LENGTH,
1022*12720SWyllys.Ingersoll@Sun.COM             aServerAuthenticationChallengeResponse,
1023*12720SWyllys.Ingersoll@Sun.COM             AUTHENTICATION_RESPONSE_LENGTH );
1024*12720SWyllys.Ingersoll@Sun.COM       }
1025*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1026*12720SWyllys.Ingersoll@Sun.COM       else
1027*12720SWyllys.Ingersoll@Sun.COM       {
1028*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 17\n");
1029*12720SWyllys.Ingersoll@Sun.COM       }
1030*12720SWyllys.Ingersoll@Sun.COM #endif
1031*12720SWyllys.Ingersoll@Sun.COM 
1032*12720SWyllys.Ingersoll@Sun.COM       // if successful, check if the server provided the correct challenge-response
1033*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
1034*12720SWyllys.Ingersoll@Sun.COM       {
1035*12720SWyllys.Ingersoll@Sun.COM          if ( 0 != memcmp(
1036*12720SWyllys.Ingersoll@Sun.COM             aServerAuthenticationChallengeResponse,
1037*12720SWyllys.Ingersoll@Sun.COM             stRetrieveEntityCertificateResponse.ServerAuthenticationResponse.__ptr,
1038*12720SWyllys.Ingersoll@Sun.COM             AUTHENTICATION_RESPONSE_LENGTH )  )
1039*12720SWyllys.Ingersoll@Sun.COM          {
1040*12720SWyllys.Ingersoll@Sun.COM             bSuccess = false;
1041*12720SWyllys.Ingersoll@Sun.COM 
1042*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
1043*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_INVALID_CHALLENGE_RESPONSE,
1044*12720SWyllys.Ingersoll@Sun.COM                      NULL,
1045*12720SWyllys.Ingersoll@Sun.COM                      sKmaAddress,
1046*12720SWyllys.Ingersoll@Sun.COM                      NULL );
1047*12720SWyllys.Ingersoll@Sun.COM          }
1048*12720SWyllys.Ingersoll@Sun.COM       }
1049*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1050*12720SWyllys.Ingersoll@Sun.COM       else
1051*12720SWyllys.Ingersoll@Sun.COM       {
1052*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 18\n");
1053*12720SWyllys.Ingersoll@Sun.COM       }
1054*12720SWyllys.Ingersoll@Sun.COM #endif
1055*12720SWyllys.Ingersoll@Sun.COM 
1056*12720SWyllys.Ingersoll@Sun.COM 
1057*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
1058*12720SWyllys.Ingersoll@Sun.COM       {
1059*12720SWyllys.Ingersoll@Sun.COM          pEntityCertificate = new CCertificate;
1060*12720SWyllys.Ingersoll@Sun.COM          // if certificate was obtained
1061*12720SWyllys.Ingersoll@Sun.COM          bSuccess = ( pEntityCertificate != 0 );
1062*12720SWyllys.Ingersoll@Sun.COM       }
1063*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1064*12720SWyllys.Ingersoll@Sun.COM       else
1065*12720SWyllys.Ingersoll@Sun.COM       {
1066*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 19\n");
1067*12720SWyllys.Ingersoll@Sun.COM       }
1068*12720SWyllys.Ingersoll@Sun.COM #endif
1069*12720SWyllys.Ingersoll@Sun.COM 
1070*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
1071*12720SWyllys.Ingersoll@Sun.COM       {
1072*12720SWyllys.Ingersoll@Sun.COM          // Load(recall) the signed certificate using OVERLOADED load method
1073*12720SWyllys.Ingersoll@Sun.COM          // 3 parameters means load from a buffer
1074*12720SWyllys.Ingersoll@Sun.COM          bSuccess = pEntityCertificate->Load(
1075*12720SWyllys.Ingersoll@Sun.COM             stRetrieveEntityCertificateResponse.Certificate.__ptr,  // load into
1076*12720SWyllys.Ingersoll@Sun.COM             stRetrieveEntityCertificateResponse.Certificate.__size,
1077*12720SWyllys.Ingersoll@Sun.COM             PKI_FORMAT );
1078*12720SWyllys.Ingersoll@Sun.COM 
1079*12720SWyllys.Ingersoll@Sun.COM          if ( !bSuccess )
1080*12720SWyllys.Ingersoll@Sun.COM          {
1081*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
1082*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_INVALID_CERTIFICATE_FORMAT,
1083*12720SWyllys.Ingersoll@Sun.COM                      NULL,
1084*12720SWyllys.Ingersoll@Sun.COM                      sKmaAddress,
1085*12720SWyllys.Ingersoll@Sun.COM                      NULL );
1086*12720SWyllys.Ingersoll@Sun.COM          }
1087*12720SWyllys.Ingersoll@Sun.COM       }
1088*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1089*12720SWyllys.Ingersoll@Sun.COM       else
1090*12720SWyllys.Ingersoll@Sun.COM       {
1091*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 20\n");
1092*12720SWyllys.Ingersoll@Sun.COM       }
1093*12720SWyllys.Ingersoll@Sun.COM #endif
1094*12720SWyllys.Ingersoll@Sun.COM 
1095*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
1096*12720SWyllys.Ingersoll@Sun.COM       {
1097*12720SWyllys.Ingersoll@Sun.COM          pEntityPrivateKey = new CPrivateKey;
1098*12720SWyllys.Ingersoll@Sun.COM          bSuccess = ( pEntityPrivateKey != 0 );
1099*12720SWyllys.Ingersoll@Sun.COM       }
1100*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1101*12720SWyllys.Ingersoll@Sun.COM       else
1102*12720SWyllys.Ingersoll@Sun.COM       {
1103*12720SWyllys.Ingersoll@Sun.COM          log_printf("!bSuccess 21\n");
1104*12720SWyllys.Ingersoll@Sun.COM       }
1105*12720SWyllys.Ingersoll@Sun.COM #endif
1106*12720SWyllys.Ingersoll@Sun.COM 
1107*12720SWyllys.Ingersoll@Sun.COM 
1108*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
1109*12720SWyllys.Ingersoll@Sun.COM       {
1110*12720SWyllys.Ingersoll@Sun.COM          // Load the Private Key using OVERLOADED Load method - 3 parameters
1111*12720SWyllys.Ingersoll@Sun.COM          // means load from a buffer
1112*12720SWyllys.Ingersoll@Sun.COM 
1113*12720SWyllys.Ingersoll@Sun.COM          // TODO: change this when certificate service supports requesting unwrapped private keys
1114*12720SWyllys.Ingersoll@Sun.COM          bSuccess = pEntityPrivateKey->Load(
1115*12720SWyllys.Ingersoll@Sun.COM             stRetrieveEntityCertificateResponse.WrappedPrivateKeyMaterial.__ptr, // load into
1116*12720SWyllys.Ingersoll@Sun.COM             stRetrieveEntityCertificateResponse.WrappedPrivateKeyMaterial.__size,
1117*12720SWyllys.Ingersoll@Sun.COM             NULL,
1118*12720SWyllys.Ingersoll@Sun.COM             PKI_FORMAT );
1119*12720SWyllys.Ingersoll@Sun.COM 
1120*12720SWyllys.Ingersoll@Sun.COM          if (!bSuccess )
1121*12720SWyllys.Ingersoll@Sun.COM          {
1122*12720SWyllys.Ingersoll@Sun.COM 
1123*12720SWyllys.Ingersoll@Sun.COM             GetPeerNetworkAddress(sKmaAddress, pstCertificateSoap);
1124*12720SWyllys.Ingersoll@Sun.COM             LogError(i_pProfile,AUDIT_CLIENT_GET_CERTIFICATE_INVALID_KEY_FORMAT,
1125*12720SWyllys.Ingersoll@Sun.COM                      NULL,
1126*12720SWyllys.Ingersoll@Sun.COM                      sKmaAddress,
1127*12720SWyllys.Ingersoll@Sun.COM                      NULL );
1128*12720SWyllys.Ingersoll@Sun.COM          }
1129*12720SWyllys.Ingersoll@Sun.COM       }
1130*12720SWyllys.Ingersoll@Sun.COM 
1131*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess )
1132*12720SWyllys.Ingersoll@Sun.COM       {
1133*12720SWyllys.Ingersoll@Sun.COM             strncpy(i_pProfile->m_wsEntityID,
1134*12720SWyllys.Ingersoll@Sun.COM                 i_wsEntityID,
1135*12720SWyllys.Ingersoll@Sun.COM                 KMS_MAX_ENTITY_ID );
1136*12720SWyllys.Ingersoll@Sun.COM             i_pProfile->m_wsEntityID[KMS_MAX_ENTITY_ID] = 0;
1137*12720SWyllys.Ingersoll@Sun.COM 
1138*12720SWyllys.Ingersoll@Sun.COM             // store PKI certificates and unwrapped private key
1139*12720SWyllys.Ingersoll@Sun.COM             bSuccess = StorePKIcerts( i_pProfile,
1140*12720SWyllys.Ingersoll@Sun.COM                             pRootCACertificate,
1141*12720SWyllys.Ingersoll@Sun.COM                             pEntityCertificate,
1142*12720SWyllys.Ingersoll@Sun.COM                             pEntityPrivateKey,
1143*12720SWyllys.Ingersoll@Sun.COM #ifdef KMSUSERPKCS12
1144*12720SWyllys.Ingersoll@Sun.COM 			    i_wsPassphrase
1145*12720SWyllys.Ingersoll@Sun.COM #else
1146*12720SWyllys.Ingersoll@Sun.COM                             NULL
1147*12720SWyllys.Ingersoll@Sun.COM #endif
1148*12720SWyllys.Ingersoll@Sun.COM 			    );
1149*12720SWyllys.Ingersoll@Sun.COM #ifdef KMSUSERPKCS12
1150*12720SWyllys.Ingersoll@Sun.COM 		if (bSuccess) {
1151*12720SWyllys.Ingersoll@Sun.COM 			/*
1152*12720SWyllys.Ingersoll@Sun.COM 			 * Write out the cert and key individually so GetPKIcerts
1153*12720SWyllys.Ingersoll@Sun.COM 			 * can use them.
1154*12720SWyllys.Ingersoll@Sun.COM 			 */
1155*12720SWyllys.Ingersoll@Sun.COM 			bSuccess = StoreTempAgentPKI(i_pProfile,
1156*12720SWyllys.Ingersoll@Sun.COM 			    pEntityCertificate, pEntityPrivateKey);
1157*12720SWyllys.Ingersoll@Sun.COM 		}
1158*12720SWyllys.Ingersoll@Sun.COM 
1159*12720SWyllys.Ingersoll@Sun.COM #endif
1160*12720SWyllys.Ingersoll@Sun.COM 	}
1161*12720SWyllys.Ingersoll@Sun.COM 
1162*12720SWyllys.Ingersoll@Sun.COM       if ( !bSuccess )
1163*12720SWyllys.Ingersoll@Sun.COM       {
1164*12720SWyllys.Ingersoll@Sun.COM          if (pRootCACertificate)
1165*12720SWyllys.Ingersoll@Sun.COM          {
1166*12720SWyllys.Ingersoll@Sun.COM              delete pRootCACertificate;
1167*12720SWyllys.Ingersoll@Sun.COM          }
1168*12720SWyllys.Ingersoll@Sun.COM          if (pEntityCertificate)
1169*12720SWyllys.Ingersoll@Sun.COM          {
1170*12720SWyllys.Ingersoll@Sun.COM              delete pEntityCertificate;
1171*12720SWyllys.Ingersoll@Sun.COM          }
1172*12720SWyllys.Ingersoll@Sun.COM          if (pEntityPrivateKey)
1173*12720SWyllys.Ingersoll@Sun.COM          {
1174*12720SWyllys.Ingersoll@Sun.COM              delete pEntityPrivateKey;
1175*12720SWyllys.Ingersoll@Sun.COM          }
1176*12720SWyllys.Ingersoll@Sun.COM 
1177*12720SWyllys.Ingersoll@Sun.COM          i_pProfile->m_iEnrolled = FALSE;
1178*12720SWyllys.Ingersoll@Sun.COM 
1179*12720SWyllys.Ingersoll@Sun.COM          if ( bTryFailOver )
1180*12720SWyllys.Ingersoll@Sun.COM          {
1181*12720SWyllys.Ingersoll@Sun.COM             iIndex = oLoadBalancer.FailOver(iIndex, bFailedOnRetrieveRootCA ? pstCASoap : pstCertificateSoap);
1182*12720SWyllys.Ingersoll@Sun.COM          }
1183*12720SWyllys.Ingersoll@Sun.COM       }
1184*12720SWyllys.Ingersoll@Sun.COM    }
1185*12720SWyllys.Ingersoll@Sun.COM    while ( bTryFailOver && (iIndex >= 0) && !bSuccess );
1186*12720SWyllys.Ingersoll@Sun.COM 
1187*12720SWyllys.Ingersoll@Sun.COM    // certs are now persisted so free up space
1188*12720SWyllys.Ingersoll@Sun.COM    if ( bSuccess )
1189*12720SWyllys.Ingersoll@Sun.COM    {
1190*12720SWyllys.Ingersoll@Sun.COM         delete pRootCACertificate;
1191*12720SWyllys.Ingersoll@Sun.COM         delete pEntityCertificate;
1192*12720SWyllys.Ingersoll@Sun.COM         delete pEntityPrivateKey;
1193*12720SWyllys.Ingersoll@Sun.COM    }
1194*12720SWyllys.Ingersoll@Sun.COM 
1195*12720SWyllys.Ingersoll@Sun.COM    // Clean up SOAP resources for pstCASoap
1196*12720SWyllys.Ingersoll@Sun.COM    soap_destroy( pstCASoap );
1197*12720SWyllys.Ingersoll@Sun.COM    soap_end( pstCASoap );
1198*12720SWyllys.Ingersoll@Sun.COM    soap_done( pstCASoap );
1199*12720SWyllys.Ingersoll@Sun.COM 
1200*12720SWyllys.Ingersoll@Sun.COM    // Clean up SOAP resources for pstCertificateSoap
1201*12720SWyllys.Ingersoll@Sun.COM    soap_destroy( pstCertificateSoap );
1202*12720SWyllys.Ingersoll@Sun.COM    soap_end( pstCertificateSoap );
1203*12720SWyllys.Ingersoll@Sun.COM    soap_done( pstCertificateSoap );
1204*12720SWyllys.Ingersoll@Sun.COM 
1205*12720SWyllys.Ingersoll@Sun.COM    free(pstCASoap);
1206*12720SWyllys.Ingersoll@Sun.COM    free(pstCertificateSoap);
1207*12720SWyllys.Ingersoll@Sun.COM 
1208*12720SWyllys.Ingersoll@Sun.COM    return bSuccess;
1209*12720SWyllys.Ingersoll@Sun.COM }
1210*12720SWyllys.Ingersoll@Sun.COM 
1211*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------
1212*12720SWyllys.Ingersoll@Sun.COM  * LoadClusterInformation
1213*12720SWyllys.Ingersoll@Sun.COM  *  calls GetCluster - that's it.
1214*12720SWyllys.Ingersoll@Sun.COM  *    If there is no cluster file, this function will return true,
1215*12720SWyllys.Ingersoll@Sun.COM  *    but o_bClusterInformationFound will be false.
1216*12720SWyllys.Ingersoll@Sun.COM  *-------------------------------------------------------------------------*/
LoadClusterInformation(KMSClientProfile * i_pProfile,int & o_bClusterInformationFound)1217*12720SWyllys.Ingersoll@Sun.COM static bool LoadClusterInformation( KMSClientProfile* i_pProfile,
1218*12720SWyllys.Ingersoll@Sun.COM                                     int& o_bClusterInformationFound )
1219*12720SWyllys.Ingersoll@Sun.COM {
1220*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT( i_pProfile );
1221*12720SWyllys.Ingersoll@Sun.COM 
1222*12720SWyllys.Ingersoll@Sun.COM     o_bClusterInformationFound = false;
1223*12720SWyllys.Ingersoll@Sun.COM 
1224*12720SWyllys.Ingersoll@Sun.COM     CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
1225*12720SWyllys.Ingersoll@Sun.COM 
1226*12720SWyllys.Ingersoll@Sun.COM     return GetCluster( i_pProfile, o_bClusterInformationFound ) ;
1227*12720SWyllys.Ingersoll@Sun.COM 
1228*12720SWyllys.Ingersoll@Sun.COM }
1229*12720SWyllys.Ingersoll@Sun.COM 
1230*12720SWyllys.Ingersoll@Sun.COM 
1231*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------
1232*12720SWyllys.Ingersoll@Sun.COM  * EnrollAgent
1233*12720SWyllys.Ingersoll@Sun.COM  *  calls functions to perform enrollment and save PKI info to persistent storage
1234*12720SWyllys.Ingersoll@Sun.COM  *  stores configuration in persistent storage
1235*12720SWyllys.Ingersoll@Sun.COM  *-------------------------------------------------------------------------*/
1236*12720SWyllys.Ingersoll@Sun.COM 
EnrollAgent(KMSClientProfile * io_pProfile,utf8cstr i_wsEntityID,utf8cstr i_wsPassphrase)1237*12720SWyllys.Ingersoll@Sun.COM static bool EnrollAgent( KMSClientProfile * io_pProfile,
1238*12720SWyllys.Ingersoll@Sun.COM                          utf8cstr           i_wsEntityID,
1239*12720SWyllys.Ingersoll@Sun.COM                          utf8cstr           i_wsPassphrase )
1240*12720SWyllys.Ingersoll@Sun.COM {
1241*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT( io_pProfile && i_wsEntityID && i_wsPassphrase );
1242*12720SWyllys.Ingersoll@Sun.COM 
1243*12720SWyllys.Ingersoll@Sun.COM     bool bSuccess = true;
1244*12720SWyllys.Ingersoll@Sun.COM 
1245*12720SWyllys.Ingersoll@Sun.COM     // see KMSAgentCryptoUtilities for HASH_LENGTH, aka KMS_MAX_HASH_SIZE
1246*12720SWyllys.Ingersoll@Sun.COM     char sHexHashedPassphrase[2*KMS_MAX_HASH_SIZE+1];
1247*12720SWyllys.Ingersoll@Sun.COM 
1248*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess )
1249*12720SWyllys.Ingersoll@Sun.COM     {
1250*12720SWyllys.Ingersoll@Sun.COM         // performs enrollment and saves PKI info to persistent storage
1251*12720SWyllys.Ingersoll@Sun.COM         bSuccess = KMSClient_RetrieveEntityCertificate(
1252*12720SWyllys.Ingersoll@Sun.COM                                     io_pProfile,
1253*12720SWyllys.Ingersoll@Sun.COM                                     i_wsEntityID,
1254*12720SWyllys.Ingersoll@Sun.COM                                     i_wsPassphrase,
1255*12720SWyllys.Ingersoll@Sun.COM                                     sHexHashedPassphrase );
1256*12720SWyllys.Ingersoll@Sun.COM 
1257*12720SWyllys.Ingersoll@Sun.COM         // KMSClient_RetrieveCertificate logs errors
1258*12720SWyllys.Ingersoll@Sun.COM     }
1259*12720SWyllys.Ingersoll@Sun.COM 
1260*12720SWyllys.Ingersoll@Sun.COM     if (bSuccess)
1261*12720SWyllys.Ingersoll@Sun.COM     {
1262*12720SWyllys.Ingersoll@Sun.COM         strncpy(io_pProfile->m_sHexHashedPassphrase,
1263*12720SWyllys.Ingersoll@Sun.COM             sHexHashedPassphrase,
1264*12720SWyllys.Ingersoll@Sun.COM             2*KMS_MAX_HASH_SIZE );
1265*12720SWyllys.Ingersoll@Sun.COM         io_pProfile->m_sHexHashedPassphrase[2*KMS_MAX_HASH_SIZE] = 0;
1266*12720SWyllys.Ingersoll@Sun.COM 
1267*12720SWyllys.Ingersoll@Sun.COM         // persist the profile now updated with the hashed passphrase
1268*12720SWyllys.Ingersoll@Sun.COM         bSuccess = StoreConfig( io_pProfile );
1269*12720SWyllys.Ingersoll@Sun.COM 
1270*12720SWyllys.Ingersoll@Sun.COM         if (!bSuccess)
1271*12720SWyllys.Ingersoll@Sun.COM         {
1272*12720SWyllys.Ingersoll@Sun.COM               Log(AUDIT_CLIENT_LOAD_PROFILE,
1273*12720SWyllys.Ingersoll@Sun.COM                   i_wsEntityID,
1274*12720SWyllys.Ingersoll@Sun.COM                   NULL,
1275*12720SWyllys.Ingersoll@Sun.COM                   "store config failed following enrollment" );
1276*12720SWyllys.Ingersoll@Sun.COM         }
1277*12720SWyllys.Ingersoll@Sun.COM     }
1278*12720SWyllys.Ingersoll@Sun.COM 
1279*12720SWyllys.Ingersoll@Sun.COM     return bSuccess;
1280*12720SWyllys.Ingersoll@Sun.COM }
1281*12720SWyllys.Ingersoll@Sun.COM 
1282*12720SWyllys.Ingersoll@Sun.COM /*---------------------------------------------------------------------------
1283*12720SWyllys.Ingersoll@Sun.COM  * Function: KMSClient_LoadProfile
1284*12720SWyllys.Ingersoll@Sun.COM  *
1285*12720SWyllys.Ingersoll@Sun.COM  *--------------------------------------------------------------------------*/
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)1286*12720SWyllys.Ingersoll@Sun.COM bool KMSClient_LoadProfile(
1287*12720SWyllys.Ingersoll@Sun.COM                 KMSClientProfile *io_pProfile,
1288*12720SWyllys.Ingersoll@Sun.COM                 utf8char *i_wsProfileName,
1289*12720SWyllys.Ingersoll@Sun.COM                 utf8char *i_wsEntityID,
1290*12720SWyllys.Ingersoll@Sun.COM                 utf8char *i_wsPassphrase,
1291*12720SWyllys.Ingersoll@Sun.COM                 utf8char *i_wsApplianceAddress,
1292*12720SWyllys.Ingersoll@Sun.COM                 int      i_iTransactionTimeout,
1293*12720SWyllys.Ingersoll@Sun.COM                 int      i_iFailOverLimit,
1294*12720SWyllys.Ingersoll@Sun.COM                 int      i_iClusterDiscoveryFrequency,
1295*12720SWyllys.Ingersoll@Sun.COM                 int       i_eKMSmode)
1296*12720SWyllys.Ingersoll@Sun.COM {
1297*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT(io_pProfile);
1298*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT(i_wsProfileName);
1299*12720SWyllys.Ingersoll@Sun.COM 
1300*12720SWyllys.Ingersoll@Sun.COM     bool bSuccess = true;
1301*12720SWyllys.Ingersoll@Sun.COM 
1302*12720SWyllys.Ingersoll@Sun.COM     char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
1303*12720SWyllys.Ingersoll@Sun.COM     char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
1304*12720SWyllys.Ingersoll@Sun.COM 
1305*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1306*12720SWyllys.Ingersoll@Sun.COM     log_printf("KMSClient_LoadProfile : entered");
1307*12720SWyllys.Ingersoll@Sun.COM #endif
1308*12720SWyllys.Ingersoll@Sun.COM 
1309*12720SWyllys.Ingersoll@Sun.COM     memset( io_pProfile, 0, sizeof(KMSClientProfile) );
1310*12720SWyllys.Ingersoll@Sun.COM 
1311*12720SWyllys.Ingersoll@Sun.COM     // create lock
1312*12720SWyllys.Ingersoll@Sun.COM 
1313*12720SWyllys.Ingersoll@Sun.COM     if (bSuccess)
1314*12720SWyllys.Ingersoll@Sun.COM     {
1315*12720SWyllys.Ingersoll@Sun.COM         bSuccess =
1316*12720SWyllys.Ingersoll@Sun.COM            ( K_CreateMutex((K_MUTEX_HANDLE *)&io_pProfile->m_pLock) ==
1317*12720SWyllys.Ingersoll@Sun.COM              K_SYS_OK );
1318*12720SWyllys.Ingersoll@Sun.COM     }
1319*12720SWyllys.Ingersoll@Sun.COM 
1320*12720SWyllys.Ingersoll@Sun.COM     // initialize profile with parameters
1321*12720SWyllys.Ingersoll@Sun.COM 
1322*12720SWyllys.Ingersoll@Sun.COM     strncpy(io_pProfile->m_wsProfileName,
1323*12720SWyllys.Ingersoll@Sun.COM             i_wsProfileName,
1324*12720SWyllys.Ingersoll@Sun.COM             KMS_MAX_ENTITY_ID);
1325*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_wsProfileName[KMS_MAX_ENTITY_ID] = 0;
1326*12720SWyllys.Ingersoll@Sun.COM 
1327*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_iPortForCAService =
1328*12720SWyllys.Ingersoll@Sun.COM        DEFAULT_CA_SERVICE_PORT_NUMBER;
1329*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_iPortForCertificateService =
1330*12720SWyllys.Ingersoll@Sun.COM        DEFAULT_CERTIFICATE_SERVICE_PORT_NUMBER;
1331*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_iPortForDiscoveryService =
1332*12720SWyllys.Ingersoll@Sun.COM        DEFAULT_DISCOVERY_SERVICE_PORT_NUMBER;
1333*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_iPortForAgentService =
1334*12720SWyllys.Ingersoll@Sun.COM        DEFAULT_AGENT_SERVICE_PORT_NUMBER;
1335*12720SWyllys.Ingersoll@Sun.COM     strncpy(io_pProfile->m_wsApplianceAddress,
1336*12720SWyllys.Ingersoll@Sun.COM             i_wsApplianceAddress,
1337*12720SWyllys.Ingersoll@Sun.COM             KMS_MAX_NETWORK_ADDRESS);
1338*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_wsApplianceAddress[KMS_MAX_NETWORK_ADDRESS] = 0;
1339*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_iClusterDiscoveryFrequency = i_iClusterDiscoveryFrequency;
1340*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_iTransactionTimeout = i_iTransactionTimeout;
1341*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_iFailoverLimit = i_iFailOverLimit;
1342*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_eKMSmode = i_eKMSmode;
1343*12720SWyllys.Ingersoll@Sun.COM 
1344*12720SWyllys.Ingersoll@Sun.COM     // if the file isn't found, create a new one
1345*12720SWyllys.Ingersoll@Sun.COM     bool bProfileExists = ProfileExists( g_wsWorkingDirectory,  /* pass in default */
1346*12720SWyllys.Ingersoll@Sun.COM                                          io_pProfile->m_wsProfileName );
1347*12720SWyllys.Ingersoll@Sun.COM 
1348*12720SWyllys.Ingersoll@Sun.COM #ifdef KMSUSERPKCS12
1349*12720SWyllys.Ingersoll@Sun.COM 	/*
1350*12720SWyllys.Ingersoll@Sun.COM 	 * Fix logic for determining if this request is for enrollment.
1351*12720SWyllys.Ingersoll@Sun.COM 	 * Look to see if the server cert and clientkey.p12 file exist.
1352*12720SWyllys.Ingersoll@Sun.COM 	 * We always expect a password for Solaris which is used to
1353*12720SWyllys.Ingersoll@Sun.COM 	 * validate that the user has access to the clientkey data by
1354*12720SWyllys.Ingersoll@Sun.COM 	 * attempting to use it to open the PKCS12 file.
1355*12720SWyllys.Ingersoll@Sun.COM 	 */
1356*12720SWyllys.Ingersoll@Sun.COM 	 bool bEnrolling = !ClientKeyP12Exists(io_pProfile->m_wsProfileName);
1357*12720SWyllys.Ingersoll@Sun.COM #else
1358*12720SWyllys.Ingersoll@Sun.COM     bool bEnrolling = i_wsEntityID && i_wsPassphrase;
1359*12720SWyllys.Ingersoll@Sun.COM #endif
1360*12720SWyllys.Ingersoll@Sun.COM 
1361*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess && !bEnrolling && !bProfileExists )
1362*12720SWyllys.Ingersoll@Sun.COM     {
1363*12720SWyllys.Ingersoll@Sun.COM        // when not enrolling a profile must exist
1364*12720SWyllys.Ingersoll@Sun.COM        bSuccess = false;
1365*12720SWyllys.Ingersoll@Sun.COM        Log(AUDIT_CLIENT_LOAD_PROFILE,
1366*12720SWyllys.Ingersoll@Sun.COM            i_wsProfileName,
1367*12720SWyllys.Ingersoll@Sun.COM            NULL,
1368*12720SWyllys.Ingersoll@Sun.COM            "Enrollment attempted but profile could not be found" );
1369*12720SWyllys.Ingersoll@Sun.COM     }
1370*12720SWyllys.Ingersoll@Sun.COM 
1371*12720SWyllys.Ingersoll@Sun.COM     // if the file isn't found, create a new one
1372*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess && !bProfileExists )
1373*12720SWyllys.Ingersoll@Sun.COM     {
1374*12720SWyllys.Ingersoll@Sun.COM        strncpy(io_pProfile->m_wsEntityID,
1375*12720SWyllys.Ingersoll@Sun.COM                i_wsEntityID,
1376*12720SWyllys.Ingersoll@Sun.COM                KMS_MAX_ENTITY_ID );
1377*12720SWyllys.Ingersoll@Sun.COM        io_pProfile->m_wsEntityID[KMS_MAX_ENTITY_ID] = 0;
1378*12720SWyllys.Ingersoll@Sun.COM        bSuccess = CreateProfile( io_pProfile,
1379*12720SWyllys.Ingersoll@Sun.COM                                  g_wsWorkingDirectory,
1380*12720SWyllys.Ingersoll@Sun.COM                                  io_pProfile->m_wsProfileName );
1381*12720SWyllys.Ingersoll@Sun.COM     }
1382*12720SWyllys.Ingersoll@Sun.COM 
1383*12720SWyllys.Ingersoll@Sun.COM     // load profile.cfg file
1384*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess )
1385*12720SWyllys.Ingersoll@Sun.COM     {
1386*12720SWyllys.Ingersoll@Sun.COM         bSuccess = GetConfig( io_pProfile );
1387*12720SWyllys.Ingersoll@Sun.COM 
1388*12720SWyllys.Ingersoll@Sun.COM     }
1389*12720SWyllys.Ingersoll@Sun.COM 
1390*12720SWyllys.Ingersoll@Sun.COM     // if profile settings changed then update the profile storage
1391*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess &&
1392*12720SWyllys.Ingersoll@Sun.COM          ( strncmp(io_pProfile->m_wsApplianceAddress,
1393*12720SWyllys.Ingersoll@Sun.COM                    i_wsApplianceAddress, KMS_MAX_NETWORK_ADDRESS ) != 0 ||
1394*12720SWyllys.Ingersoll@Sun.COM            io_pProfile->m_iClusterDiscoveryFrequency != i_iClusterDiscoveryFrequency ||
1395*12720SWyllys.Ingersoll@Sun.COM            io_pProfile->m_iTransactionTimeout != i_iTransactionTimeout ||
1396*12720SWyllys.Ingersoll@Sun.COM            io_pProfile->m_iFailoverLimit != i_iFailOverLimit
1397*12720SWyllys.Ingersoll@Sun.COM          ))
1398*12720SWyllys.Ingersoll@Sun.COM     {
1399*12720SWyllys.Ingersoll@Sun.COM         strncpy(io_pProfile->m_wsApplianceAddress,
1400*12720SWyllys.Ingersoll@Sun.COM                 i_wsApplianceAddress,
1401*12720SWyllys.Ingersoll@Sun.COM                 KMS_MAX_NETWORK_ADDRESS);
1402*12720SWyllys.Ingersoll@Sun.COM         io_pProfile->m_wsApplianceAddress[KMS_MAX_NETWORK_ADDRESS] = 0;
1403*12720SWyllys.Ingersoll@Sun.COM         io_pProfile->m_iClusterDiscoveryFrequency = i_iClusterDiscoveryFrequency;
1404*12720SWyllys.Ingersoll@Sun.COM         io_pProfile->m_iTransactionTimeout = i_iTransactionTimeout;
1405*12720SWyllys.Ingersoll@Sun.COM         io_pProfile->m_iFailoverLimit = i_iFailOverLimit;
1406*12720SWyllys.Ingersoll@Sun.COM 
1407*12720SWyllys.Ingersoll@Sun.COM         bSuccess = StoreConfig( io_pProfile );
1408*12720SWyllys.Ingersoll@Sun.COM     }
1409*12720SWyllys.Ingersoll@Sun.COM 
1410*12720SWyllys.Ingersoll@Sun.COM     // get PKI info from prior enrollment
1411*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess && !bEnrolling )
1412*12720SWyllys.Ingersoll@Sun.COM     {
1413*12720SWyllys.Ingersoll@Sun.COM #ifdef KMSUSERPKCS12
1414*12720SWyllys.Ingersoll@Sun.COM 	/*
1415*12720SWyllys.Ingersoll@Sun.COM 	 * Decrypt the PKCS12 file with the client cert and key using
1416*12720SWyllys.Ingersoll@Sun.COM 	 * the given password.  If it fails, then return an auth failure
1417*12720SWyllys.Ingersoll@Sun.COM 	 * status.  If success, write the client cert and key to the client file
1418*12720SWyllys.Ingersoll@Sun.COM 	 * so it can be used later by the SOAP SSL functions.
1419*12720SWyllys.Ingersoll@Sun.COM 	 */
1420*12720SWyllys.Ingersoll@Sun.COM 	CCertificate* pEntityCertificate = new CCertificate;;
1421*12720SWyllys.Ingersoll@Sun.COM 	CPrivateKey*  pEntityPrivateKey = new CPrivateKey;
1422*12720SWyllys.Ingersoll@Sun.COM 	bSuccess = GetPKCS12CertAndKey(io_pProfile,
1423*12720SWyllys.Ingersoll@Sun.COM 	    i_wsPassphrase,
1424*12720SWyllys.Ingersoll@Sun.COM 	    pEntityCertificate,
1425*12720SWyllys.Ingersoll@Sun.COM 	    pEntityPrivateKey);
1426*12720SWyllys.Ingersoll@Sun.COM 	if (!bSuccess) {
1427*12720SWyllys.Ingersoll@Sun.COM 		Log(AUDIT_CLIENT_LOAD_PROFILE,
1428*12720SWyllys.Ingersoll@Sun.COM 			i_wsProfileName,
1429*12720SWyllys.Ingersoll@Sun.COM 			NULL,
1430*12720SWyllys.Ingersoll@Sun.COM 			"Enrollment Certificate and Private Key "\
1431*12720SWyllys.Ingersoll@Sun.COM 			"were not loaded from PKCS12" );
1432*12720SWyllys.Ingersoll@Sun.COM 	} else {
1433*12720SWyllys.Ingersoll@Sun.COM 		/*
1434*12720SWyllys.Ingersoll@Sun.COM 		 * Write out the cert and key individually so GetPKIcerts
1435*12720SWyllys.Ingersoll@Sun.COM 		 * can use them.
1436*12720SWyllys.Ingersoll@Sun.COM 		 */
1437*12720SWyllys.Ingersoll@Sun.COM 		 bSuccess = StoreTempAgentPKI(io_pProfile,
1438*12720SWyllys.Ingersoll@Sun.COM 		    pEntityCertificate, pEntityPrivateKey);
1439*12720SWyllys.Ingersoll@Sun.COM 		 if (!bSuccess) {
1440*12720SWyllys.Ingersoll@Sun.COM 			Log(AUDIT_CLIENT_LOAD_PROFILE,
1441*12720SWyllys.Ingersoll@Sun.COM 				i_wsProfileName,
1442*12720SWyllys.Ingersoll@Sun.COM 				NULL,
1443*12720SWyllys.Ingersoll@Sun.COM 				"Enrollment Certificate and Private Key "\
1444*12720SWyllys.Ingersoll@Sun.COM 				"were not stored to file." );
1445*12720SWyllys.Ingersoll@Sun.COM 		 }
1446*12720SWyllys.Ingersoll@Sun.COM 	}
1447*12720SWyllys.Ingersoll@Sun.COM 	delete pEntityCertificate;
1448*12720SWyllys.Ingersoll@Sun.COM 	delete pEntityPrivateKey;
1449*12720SWyllys.Ingersoll@Sun.COM 
1450*12720SWyllys.Ingersoll@Sun.COM #endif
1451*12720SWyllys.Ingersoll@Sun.COM 	if (bSuccess)
1452*12720SWyllys.Ingersoll@Sun.COM         	bSuccess = GetPKIcerts( io_pProfile );
1453*12720SWyllys.Ingersoll@Sun.COM     }
1454*12720SWyllys.Ingersoll@Sun.COM 
1455*12720SWyllys.Ingersoll@Sun.COM     // if not enrolling then previously enrolled PKI info should now be initialized
1456*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess && !bEnrolling &&
1457*12720SWyllys.Ingersoll@Sun.COM         (!io_pProfile->m_sHexHashedPassphrase ||
1458*12720SWyllys.Ingersoll@Sun.COM         !io_pProfile->m_iEnrolled  ))
1459*12720SWyllys.Ingersoll@Sun.COM     {
1460*12720SWyllys.Ingersoll@Sun.COM         bSuccess = false;
1461*12720SWyllys.Ingersoll@Sun.COM         Log(AUDIT_CLIENT_LOAD_PROFILE,
1462*12720SWyllys.Ingersoll@Sun.COM           i_wsProfileName,
1463*12720SWyllys.Ingersoll@Sun.COM           NULL,
1464*12720SWyllys.Ingersoll@Sun.COM           "Enrollment Certificates and Private Key were not loaded from profile" );
1465*12720SWyllys.Ingersoll@Sun.COM     }
1466*12720SWyllys.Ingersoll@Sun.COM 
1467*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_bIsClusterDiscoveryCalled = false;
1468*12720SWyllys.Ingersoll@Sun.COM 
1469*12720SWyllys.Ingersoll@Sun.COM     // allocate main soap struct
1470*12720SWyllys.Ingersoll@Sun.COM     struct soap* pstSoap = 0;
1471*12720SWyllys.Ingersoll@Sun.COM 
1472*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess )
1473*12720SWyllys.Ingersoll@Sun.COM     {
1474*12720SWyllys.Ingersoll@Sun.COM         pstSoap = (struct soap*)malloc( sizeof(struct soap) );
1475*12720SWyllys.Ingersoll@Sun.COM 
1476*12720SWyllys.Ingersoll@Sun.COM         io_pProfile->m_pvSoap = pstSoap;
1477*12720SWyllys.Ingersoll@Sun.COM 
1478*12720SWyllys.Ingersoll@Sun.COM         bSuccess = ( pstSoap != NULL );
1479*12720SWyllys.Ingersoll@Sun.COM 
1480*12720SWyllys.Ingersoll@Sun.COM         if ( bSuccess )
1481*12720SWyllys.Ingersoll@Sun.COM         {
1482*12720SWyllys.Ingersoll@Sun.COM             soap_init2( pstSoap,
1483*12720SWyllys.Ingersoll@Sun.COM                     (SOAP_XML_STRICT | SOAP_C_UTFSTRING ),
1484*12720SWyllys.Ingersoll@Sun.COM                     (SOAP_XML_STRICT | SOAP_C_UTFSTRING) );
1485*12720SWyllys.Ingersoll@Sun.COM 
1486*12720SWyllys.Ingersoll@Sun.COM #ifdef METAWARE
1487*12720SWyllys.Ingersoll@Sun.COM             K_SetupCallbacks ( pstSoap );
1488*12720SWyllys.Ingersoll@Sun.COM #endif
1489*12720SWyllys.Ingersoll@Sun.COM 
1490*12720SWyllys.Ingersoll@Sun.COM             soap_set_namespaces( pstSoap, KMS_Agent_namespaces );
1491*12720SWyllys.Ingersoll@Sun.COM 
1492*12720SWyllys.Ingersoll@Sun.COM             pstSoap->connect_timeout = io_pProfile->m_iTransactionTimeout;
1493*12720SWyllys.Ingersoll@Sun.COM             pstSoap->send_timeout = io_pProfile->m_iTransactionTimeout;
1494*12720SWyllys.Ingersoll@Sun.COM             pstSoap->recv_timeout = io_pProfile->m_iTransactionTimeout;
1495*12720SWyllys.Ingersoll@Sun.COM         }
1496*12720SWyllys.Ingersoll@Sun.COM         else
1497*12720SWyllys.Ingersoll@Sun.COM         {
1498*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1499*12720SWyllys.Ingersoll@Sun.COM            log_printf("Malloc %x pstSoap returned null\n",
1500*12720SWyllys.Ingersoll@Sun.COM                       sizeof(struct soap));
1501*12720SWyllys.Ingersoll@Sun.COM #endif
1502*12720SWyllys.Ingersoll@Sun.COM 
1503*12720SWyllys.Ingersoll@Sun.COM         }
1504*12720SWyllys.Ingersoll@Sun.COM     }
1505*12720SWyllys.Ingersoll@Sun.COM 
1506*12720SWyllys.Ingersoll@Sun.COM     // delete the existing cluster config if the input IP address
1507*12720SWyllys.Ingersoll@Sun.COM     // does not match one already known to the cluster config
1508*12720SWyllys.Ingersoll@Sun.COM 
1509*12720SWyllys.Ingersoll@Sun.COM     // Note that KMSClientProfile may be too large to fit on the stack, so we're
1510*12720SWyllys.Ingersoll@Sun.COM     // going to put it on the heap.
1511*12720SWyllys.Ingersoll@Sun.COM 
1512*12720SWyllys.Ingersoll@Sun.COM     KMSClientProfile* pstTempProfile = 0;
1513*12720SWyllys.Ingersoll@Sun.COM     bool bFound = false;
1514*12720SWyllys.Ingersoll@Sun.COM     int i;
1515*12720SWyllys.Ingersoll@Sun.COM 
1516*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess )
1517*12720SWyllys.Ingersoll@Sun.COM     {
1518*12720SWyllys.Ingersoll@Sun.COM         pstTempProfile = (KMSClientProfile*)malloc( sizeof(KMSClientProfile) );
1519*12720SWyllys.Ingersoll@Sun.COM         bSuccess = (pstTempProfile != 0);
1520*12720SWyllys.Ingersoll@Sun.COM #if defined(METAWARE)
1521*12720SWyllys.Ingersoll@Sun.COM         if (!bSuccess)
1522*12720SWyllys.Ingersoll@Sun.COM            log_printf("Malloc %x pstTempProfile returned null\n",
1523*12720SWyllys.Ingersoll@Sun.COM                       sizeof(KMSClientProfile));
1524*12720SWyllys.Ingersoll@Sun.COM #endif
1525*12720SWyllys.Ingersoll@Sun.COM 
1526*12720SWyllys.Ingersoll@Sun.COM     }
1527*12720SWyllys.Ingersoll@Sun.COM 
1528*12720SWyllys.Ingersoll@Sun.COM     int bClusterInformationFound = false;
1529*12720SWyllys.Ingersoll@Sun.COM 
1530*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess )
1531*12720SWyllys.Ingersoll@Sun.COM     {
1532*12720SWyllys.Ingersoll@Sun.COM         memcpy( pstTempProfile, io_pProfile, sizeof(KMSClientProfile) );
1533*12720SWyllys.Ingersoll@Sun.COM 
1534*12720SWyllys.Ingersoll@Sun.COM         bSuccess = LoadClusterInformation( pstTempProfile, bClusterInformationFound );
1535*12720SWyllys.Ingersoll@Sun.COM     }
1536*12720SWyllys.Ingersoll@Sun.COM 
1537*12720SWyllys.Ingersoll@Sun.COM     // got cluster info from persistent storage
1538*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess && bClusterInformationFound )
1539*12720SWyllys.Ingersoll@Sun.COM     {
1540*12720SWyllys.Ingersoll@Sun.COM        // see if address is a member of the remembered cluster or is a
1541*12720SWyllys.Ingersoll@Sun.COM        // new kma, meaning this KMA joins the cluster as the
1542*12720SWyllys.Ingersoll@Sun.COM        // discovery KMA.
1543*12720SWyllys.Ingersoll@Sun.COM         for ( i = 0; i < pstTempProfile->m_iClusterNum; i++ )
1544*12720SWyllys.Ingersoll@Sun.COM         {
1545*12720SWyllys.Ingersoll@Sun.COM             bFound = (strncmp( pstTempProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
1546*12720SWyllys.Ingersoll@Sun.COM                               io_pProfile->m_wsApplianceAddress,
1547*12720SWyllys.Ingersoll@Sun.COM                               KMS_MAX_NETWORK_ADDRESS) == 0);
1548*12720SWyllys.Ingersoll@Sun.COM 
1549*12720SWyllys.Ingersoll@Sun.COM             if ( bFound )
1550*12720SWyllys.Ingersoll@Sun.COM             {
1551*12720SWyllys.Ingersoll@Sun.COM                 break;
1552*12720SWyllys.Ingersoll@Sun.COM             }
1553*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1554*12720SWyllys.Ingersoll@Sun.COM             else
1555*12720SWyllys.Ingersoll@Sun.COM                log_printf ("KMSClient_LoadProfile : Appliance Address doesn't match");
1556*12720SWyllys.Ingersoll@Sun.COM #endif
1557*12720SWyllys.Ingersoll@Sun.COM         }
1558*12720SWyllys.Ingersoll@Sun.COM 
1559*12720SWyllys.Ingersoll@Sun.COM         if ( !bFound )
1560*12720SWyllys.Ingersoll@Sun.COM         {
1561*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1562*12720SWyllys.Ingersoll@Sun.COM            log_printf ("KMSClient_LoadProfile : delete cluster");
1563*12720SWyllys.Ingersoll@Sun.COM #endif
1564*12720SWyllys.Ingersoll@Sun.COM            DeleteCluster( pstTempProfile );
1565*12720SWyllys.Ingersoll@Sun.COM            char msg[256];
1566*12720SWyllys.Ingersoll@Sun.COM            K_snprintf(msg, 256,
1567*12720SWyllys.Ingersoll@Sun.COM                "KMSClientProfile.LoadProfile(): deleting previous cluster config, %s not found\n",
1568*12720SWyllys.Ingersoll@Sun.COM                 io_pProfile->m_wsApplianceAddress);
1569*12720SWyllys.Ingersoll@Sun.COM            Log(AUDIT_CLIENT_LOAD_PROFILE,
1570*12720SWyllys.Ingersoll@Sun.COM               i_wsProfileName,
1571*12720SWyllys.Ingersoll@Sun.COM               NULL,
1572*12720SWyllys.Ingersoll@Sun.COM               msg );
1573*12720SWyllys.Ingersoll@Sun.COM            DeleteCluster( pstTempProfile );
1574*12720SWyllys.Ingersoll@Sun.COM         }
1575*12720SWyllys.Ingersoll@Sun.COM         else
1576*12720SWyllys.Ingersoll@Sun.COM         {
1577*12720SWyllys.Ingersoll@Sun.COM             // since address is a member of the persisted cluster copy the persisted cluster info to the profile
1578*12720SWyllys.Ingersoll@Sun.COM             io_pProfile->m_iClusterNum = pstTempProfile->m_iClusterNum;
1579*12720SWyllys.Ingersoll@Sun.COM             memcpy(io_pProfile->m_aCluster,
1580*12720SWyllys.Ingersoll@Sun.COM                    pstTempProfile->m_aCluster,
1581*12720SWyllys.Ingersoll@Sun.COM                     sizeof(KMSClusterEntry)*io_pProfile->m_iClusterNum);
1582*12720SWyllys.Ingersoll@Sun.COM         }
1583*12720SWyllys.Ingersoll@Sun.COM     }
1584*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1585*12720SWyllys.Ingersoll@Sun.COM     else
1586*12720SWyllys.Ingersoll@Sun.COM        log_printf ("KMSClient_LoadProfile : no persisted cluster information");
1587*12720SWyllys.Ingersoll@Sun.COM #endif
1588*12720SWyllys.Ingersoll@Sun.COM 
1589*12720SWyllys.Ingersoll@Sun.COM     if ( pstTempProfile )
1590*12720SWyllys.Ingersoll@Sun.COM     {
1591*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1592*12720SWyllys.Ingersoll@Sun.COM        log_printf ("KMSClient_LoadProfile : free the temporary profile");
1593*12720SWyllys.Ingersoll@Sun.COM #endif
1594*12720SWyllys.Ingersoll@Sun.COM         free( pstTempProfile );
1595*12720SWyllys.Ingersoll@Sun.COM         pstTempProfile = 0;
1596*12720SWyllys.Ingersoll@Sun.COM     }
1597*12720SWyllys.Ingersoll@Sun.COM 
1598*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess && !io_pProfile->m_iEnrolled )
1599*12720SWyllys.Ingersoll@Sun.COM     {
1600*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1601*12720SWyllys.Ingersoll@Sun.COM        log_printf ("KMSClient_LoadProfile : call EnrollAgent");
1602*12720SWyllys.Ingersoll@Sun.COM #endif
1603*12720SWyllys.Ingersoll@Sun.COM         // enroll the agent
1604*12720SWyllys.Ingersoll@Sun.COM         bSuccess = EnrollAgent( io_pProfile,
1605*12720SWyllys.Ingersoll@Sun.COM                                 i_wsEntityID,
1606*12720SWyllys.Ingersoll@Sun.COM                                 i_wsPassphrase );
1607*12720SWyllys.Ingersoll@Sun.COM     }
1608*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1609*12720SWyllys.Ingersoll@Sun.COM     else if (io_pProfile->m_iEnrolled)
1610*12720SWyllys.Ingersoll@Sun.COM        log_printf ("KMSClient_LoadProfile : Already Enrolled");
1611*12720SWyllys.Ingersoll@Sun.COM #endif
1612*12720SWyllys.Ingersoll@Sun.COM 
1613*12720SWyllys.Ingersoll@Sun.COM 
1614*12720SWyllys.Ingersoll@Sun.COM 
1615*12720SWyllys.Ingersoll@Sun.COM     if (bSuccess)
1616*12720SWyllys.Ingersoll@Sun.COM     {
1617*12720SWyllys.Ingersoll@Sun.COM        // Initialize SSL - use CLIENT AUTH
1618*12720SWyllys.Ingersoll@Sun.COM        // CLIENT_AUTHENTICATION needs the pstSoap, and expects
1619*12720SWyllys.Ingersoll@Sun.COM        // the profile io_pProfile to be full (have the other certificates
1620*12720SWyllys.Ingersoll@Sun.COM        // and keypair)
1621*12720SWyllys.Ingersoll@Sun.COM 
1622*12720SWyllys.Ingersoll@Sun.COM         if ( bSuccess )
1623*12720SWyllys.Ingersoll@Sun.COM         {
1624*12720SWyllys.Ingersoll@Sun.COM             bSuccess =
1625*12720SWyllys.Ingersoll@Sun.COM                 K_soap_ssl_client_context(
1626*12720SWyllys.Ingersoll@Sun.COM                    io_pProfile,                            // in/out
1627*12720SWyllys.Ingersoll@Sun.COM                    pstSoap,                                // out
1628*12720SWyllys.Ingersoll@Sun.COM                    SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION  // in - flags
1629*12720SWyllys.Ingersoll@Sun.COM                     ) == SOAP_OK;
1630*12720SWyllys.Ingersoll@Sun.COM 
1631*12720SWyllys.Ingersoll@Sun.COM             if ( !bSuccess )
1632*12720SWyllys.Ingersoll@Sun.COM             {
1633*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1634*12720SWyllys.Ingersoll@Sun.COM                 if (!bSuccess)
1635*12720SWyllys.Ingersoll@Sun.COM                   log_printf ("KMSClient_LoadProfile : K_soap_ssl_client_context failed");
1636*12720SWyllys.Ingersoll@Sun.COM #endif
1637*12720SWyllys.Ingersoll@Sun.COM                 GetSoapFault(sSoapFaultMsg, (struct soap*)pstSoap);
1638*12720SWyllys.Ingersoll@Sun.COM                 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1639*12720SWyllys.Ingersoll@Sun.COM 
1640*12720SWyllys.Ingersoll@Sun.COM                 LogError(io_pProfile,
1641*12720SWyllys.Ingersoll@Sun.COM                     AUDIT_CLIENT_LOAD_PROFILE_SOAP_ERROR,
1642*12720SWyllys.Ingersoll@Sun.COM                     NULL,
1643*12720SWyllys.Ingersoll@Sun.COM                     sKmaAddress,
1644*12720SWyllys.Ingersoll@Sun.COM                     sSoapFaultMsg );
1645*12720SWyllys.Ingersoll@Sun.COM             }
1646*12720SWyllys.Ingersoll@Sun.COM         }
1647*12720SWyllys.Ingersoll@Sun.COM 
1648*12720SWyllys.Ingersoll@Sun.COM         // discover the cluster
1649*12720SWyllys.Ingersoll@Sun.COM 
1650*12720SWyllys.Ingersoll@Sun.COM         if ( bSuccess &&
1651*12720SWyllys.Ingersoll@Sun.COM             io_pProfile->m_iClusterDiscoveryFrequency > 0 )
1652*12720SWyllys.Ingersoll@Sun.COM          {
1653*12720SWyllys.Ingersoll@Sun.COM               bSuccess = ( KMSClient_GetClusterInformation(
1654*12720SWyllys.Ingersoll@Sun.COM                                             io_pProfile,
1655*12720SWyllys.Ingersoll@Sun.COM                                             io_pProfile->m_wsEntitySiteID,
1656*12720SWyllys.Ingersoll@Sun.COM                                             sizeof(io_pProfile->m_wsEntitySiteID),
1657*12720SWyllys.Ingersoll@Sun.COM                                             &(io_pProfile->m_iClusterNum),
1658*12720SWyllys.Ingersoll@Sun.COM                                             io_pProfile->m_aCluster,
1659*12720SWyllys.Ingersoll@Sun.COM                                             KMS_MAX_CLUSTER_NUM) != 0 );
1660*12720SWyllys.Ingersoll@Sun.COM               // KMSClient_GetClusterInformation logs errors
1661*12720SWyllys.Ingersoll@Sun.COM 
1662*12720SWyllys.Ingersoll@Sun.COM               if (bSuccess && i_eKMSmode == FIPS_MODE)
1663*12720SWyllys.Ingersoll@Sun.COM               {
1664*12720SWyllys.Ingersoll@Sun.COM                     bSuccess = !KMSClient_NoFIPSCompatibleKMAs(io_pProfile);
1665*12720SWyllys.Ingersoll@Sun.COM                     if (!bSuccess)
1666*12720SWyllys.Ingersoll@Sun.COM                     {
1667*12720SWyllys.Ingersoll@Sun.COM                         LogError(io_pProfile,
1668*12720SWyllys.Ingersoll@Sun.COM                             AUDIT_CLIENT_AGENT_LOAD_PROFILE_NO_FIPS_COMPATIBLE_KMAS_AVAILABLE,
1669*12720SWyllys.Ingersoll@Sun.COM                             NULL,
1670*12720SWyllys.Ingersoll@Sun.COM                             NULL,
1671*12720SWyllys.Ingersoll@Sun.COM                             NULL );
1672*12720SWyllys.Ingersoll@Sun.COM                     }
1673*12720SWyllys.Ingersoll@Sun.COM               }
1674*12720SWyllys.Ingersoll@Sun.COM          }
1675*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1676*12720SWyllys.Ingersoll@Sun.COM         if (!bSuccess)
1677*12720SWyllys.Ingersoll@Sun.COM            log_printf ("KMSClient_LoadProfile : getClusterInformation failed");
1678*12720SWyllys.Ingersoll@Sun.COM #endif
1679*12720SWyllys.Ingersoll@Sun.COM 
1680*12720SWyllys.Ingersoll@Sun.COM #ifdef KMSUSERPKCS12
1681*12720SWyllys.Ingersoll@Sun.COM 	/*
1682*12720SWyllys.Ingersoll@Sun.COM 	 * Once the SSL context is established, delete the
1683*12720SWyllys.Ingersoll@Sun.COM 	 * private key file.
1684*12720SWyllys.Ingersoll@Sun.COM 	 */
1685*12720SWyllys.Ingersoll@Sun.COM 	 (void) CleanupPrivateKeyFile(io_pProfile);
1686*12720SWyllys.Ingersoll@Sun.COM #endif
1687*12720SWyllys.Ingersoll@Sun.COM     }
1688*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1689*12720SWyllys.Ingersoll@Sun.COM     else if (!bSuccess)
1690*12720SWyllys.Ingersoll@Sun.COM        log_printf ("KMSClient_LoadProfile : EnrollAgent failed");
1691*12720SWyllys.Ingersoll@Sun.COM #endif
1692*12720SWyllys.Ingersoll@Sun.COM 
1693*12720SWyllys.Ingersoll@Sun.COM     CAgentLoadBalancer *pAgentLoadBalancer = new CAgentLoadBalancer(io_pProfile);
1694*12720SWyllys.Ingersoll@Sun.COM     if(pAgentLoadBalancer == NULL)
1695*12720SWyllys.Ingersoll@Sun.COM     {
1696*12720SWyllys.Ingersoll@Sun.COM         bSuccess = false;
1697*12720SWyllys.Ingersoll@Sun.COM     }
1698*12720SWyllys.Ingersoll@Sun.COM 
1699*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1700*12720SWyllys.Ingersoll@Sun.COM     if (!bSuccess)
1701*12720SWyllys.Ingersoll@Sun.COM        log_printf ("KMSClient_LoadProfile : new CAgentLoadBalancer failed");
1702*12720SWyllys.Ingersoll@Sun.COM #endif
1703*12720SWyllys.Ingersoll@Sun.COM 
1704*12720SWyllys.Ingersoll@Sun.COM     io_pProfile->m_pAgentLoadBalancer = pAgentLoadBalancer;
1705*12720SWyllys.Ingersoll@Sun.COM 
1706*12720SWyllys.Ingersoll@Sun.COM     // create a data unit server affinity cache for Agents
1707*12720SWyllys.Ingersoll@Sun.COM 
1708*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess )
1709*12720SWyllys.Ingersoll@Sun.COM     {
1710*12720SWyllys.Ingersoll@Sun.COM         io_pProfile->m_pDataUnitCache = new CDataUnitCache();
1711*12720SWyllys.Ingersoll@Sun.COM 
1712*12720SWyllys.Ingersoll@Sun.COM         bSuccess = ( io_pProfile->m_pDataUnitCache != NULL );
1713*12720SWyllys.Ingersoll@Sun.COM     }
1714*12720SWyllys.Ingersoll@Sun.COM 
1715*12720SWyllys.Ingersoll@Sun.COM     if ( bSuccess )
1716*12720SWyllys.Ingersoll@Sun.COM     {
1717*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1718*12720SWyllys.Ingersoll@Sun.COM        log_printf ("KMSClient_LoadProfile : set version to KMS_AGENT_VERSION = %x",
1719*12720SWyllys.Ingersoll@Sun.COM                    KMS_AGENT_VERSION);
1720*12720SWyllys.Ingersoll@Sun.COM        log_printf ("KMSClient_LoadProfile : profile is: %x\n", io_pProfile);
1721*12720SWyllys.Ingersoll@Sun.COM #endif
1722*12720SWyllys.Ingersoll@Sun.COM        // this is checked later by ProfileLoaded and is taken
1723*12720SWyllys.Ingersoll@Sun.COM        // to indicate that the profile was correctly loaded
1724*12720SWyllys.Ingersoll@Sun.COM 	   io_pProfile->m_iVersion = KMS_AGENT_VERSION;
1725*12720SWyllys.Ingersoll@Sun.COM     }
1726*12720SWyllys.Ingersoll@Sun.COM 
1727*12720SWyllys.Ingersoll@Sun.COM     if( !bSuccess )
1728*12720SWyllys.Ingersoll@Sun.COM     {
1729*12720SWyllys.Ingersoll@Sun.COM         K_DestroyMutex((K_MUTEX_HANDLE)io_pProfile->m_pLock);
1730*12720SWyllys.Ingersoll@Sun.COM         io_pProfile->m_pLock = 0;
1731*12720SWyllys.Ingersoll@Sun.COM 
1732*12720SWyllys.Ingersoll@Sun.COM         if ( io_pProfile->m_pvSoap )
1733*12720SWyllys.Ingersoll@Sun.COM         {
1734*12720SWyllys.Ingersoll@Sun.COM             soap_destroy( (struct soap*)io_pProfile->m_pvSoap );
1735*12720SWyllys.Ingersoll@Sun.COM             soap_end( (struct soap*)io_pProfile->m_pvSoap );
1736*12720SWyllys.Ingersoll@Sun.COM             soap_done( (struct soap*)io_pProfile->m_pvSoap );
1737*12720SWyllys.Ingersoll@Sun.COM 
1738*12720SWyllys.Ingersoll@Sun.COM             free( (struct soap*)io_pProfile->m_pvSoap );
1739*12720SWyllys.Ingersoll@Sun.COM             io_pProfile->m_pvSoap = 0;
1740*12720SWyllys.Ingersoll@Sun.COM 
1741*12720SWyllys.Ingersoll@Sun.COM             if( io_pProfile->m_pAgentLoadBalancer != NULL)
1742*12720SWyllys.Ingersoll@Sun.COM             {
1743*12720SWyllys.Ingersoll@Sun.COM                 delete(reinterpret_cast <CAgentLoadBalancer *>(io_pProfile->m_pAgentLoadBalancer));
1744*12720SWyllys.Ingersoll@Sun.COM             }
1745*12720SWyllys.Ingersoll@Sun.COM 
1746*12720SWyllys.Ingersoll@Sun.COM             if( io_pProfile->m_pDataUnitCache != NULL)
1747*12720SWyllys.Ingersoll@Sun.COM             {
1748*12720SWyllys.Ingersoll@Sun.COM                 delete(reinterpret_cast <CDataUnitCache *>(io_pProfile->m_pDataUnitCache));
1749*12720SWyllys.Ingersoll@Sun.COM             }
1750*12720SWyllys.Ingersoll@Sun.COM 
1751*12720SWyllys.Ingersoll@Sun.COM         }
1752*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
1753*12720SWyllys.Ingersoll@Sun.COM         log_printf ("KMSClient_LoadProfile : failed - returning");
1754*12720SWyllys.Ingersoll@Sun.COM #endif
1755*12720SWyllys.Ingersoll@Sun.COM     }
1756*12720SWyllys.Ingersoll@Sun.COM 
1757*12720SWyllys.Ingersoll@Sun.COM     return bSuccess;
1758*12720SWyllys.Ingersoll@Sun.COM }
1759*12720SWyllys.Ingersoll@Sun.COM 
1760*12720SWyllys.Ingersoll@Sun.COM /**
1761*12720SWyllys.Ingersoll@Sun.COM  *  compare cluster entries having equivalent KMA names (aka Appliance alias) and
1762*12720SWyllys.Ingersoll@Sun.COM  *  return true if equal.  Note:  KMANetworkAddress comparison is handled separately
1763*12720SWyllys.Ingersoll@Sun.COM  *  due to IPv4/IPv6
1764*12720SWyllys.Ingersoll@Sun.COM  */
EqualClusterEntry(struct KMS_Discovery::KMS_Discovery_ClusterMember const * i_pLeft,KMSClusterEntry const * i_pRight)1765*12720SWyllys.Ingersoll@Sun.COM static bool EqualClusterEntry(
1766*12720SWyllys.Ingersoll@Sun.COM                        struct KMS_Discovery::KMS_Discovery_ClusterMember const *i_pLeft,
1767*12720SWyllys.Ingersoll@Sun.COM                        KMSClusterEntry                                   const *i_pRight)
1768*12720SWyllys.Ingersoll@Sun.COM {
1769*12720SWyllys.Ingersoll@Sun.COM     bool bEnabled = i_pRight->m_iEnabled ? true : false;
1770*12720SWyllys.Ingersoll@Sun.COM     if ( i_pLeft->Enabled != bEnabled )
1771*12720SWyllys.Ingersoll@Sun.COM     {
1772*12720SWyllys.Ingersoll@Sun.COM         return false;
1773*12720SWyllys.Ingersoll@Sun.COM     }
1774*12720SWyllys.Ingersoll@Sun.COM     if ( i_pLeft->KMAID != i_pRight->m_lApplianceID )
1775*12720SWyllys.Ingersoll@Sun.COM     {
1776*12720SWyllys.Ingersoll@Sun.COM         return false;
1777*12720SWyllys.Ingersoll@Sun.COM     }
1778*12720SWyllys.Ingersoll@Sun.COM     if ( strncmp(i_pLeft->KMASiteID,
1779*12720SWyllys.Ingersoll@Sun.COM             i_pRight->m_wsApplianceSiteID,
1780*12720SWyllys.Ingersoll@Sun.COM             KMS_MAX_ENTITY_SITE_ID) != 0 )
1781*12720SWyllys.Ingersoll@Sun.COM     {
1782*12720SWyllys.Ingersoll@Sun.COM         return false;
1783*12720SWyllys.Ingersoll@Sun.COM     }
1784*12720SWyllys.Ingersoll@Sun.COM     //    Note: we now minimize persistence of cluster changes by not saving
1785*12720SWyllys.Ingersoll@Sun.COM     //      whenever m_iResponding changes
1786*12720SWyllys.Ingersoll@Sun.COM 
1787*12720SWyllys.Ingersoll@Sun.COM     return true;
1788*12720SWyllys.Ingersoll@Sun.COM }
1789*12720SWyllys.Ingersoll@Sun.COM /**
1790*12720SWyllys.Ingersoll@Sun.COM  *  @return true if the current address matches the provided IPv6Address
1791*12720SWyllys.Ingersoll@Sun.COM  *  when the i_bUseIPv6 arg is true, otherwise compare the current address
1792*12720SWyllys.Ingersoll@Sun.COM  *  with the IPv4Address.  If i_bUseIPv6 then i_pCurrentAddress must be
1793*12720SWyllys.Ingersoll@Sun.COM  *  enclosed in brackets, i.e. as in RFC 2396.
1794*12720SWyllys.Ingersoll@Sun.COM  */
EqualKMANetworkAddress(bool i_bUseIPv6,const char * const i_pIPv6Address,const char * const i_pIPv4Address,const char * const i_pCurrentAddress)1795*12720SWyllys.Ingersoll@Sun.COM static bool EqualKMANetworkAddress (
1796*12720SWyllys.Ingersoll@Sun.COM                                     bool i_bUseIPv6,
1797*12720SWyllys.Ingersoll@Sun.COM                                     const char * const i_pIPv6Address,
1798*12720SWyllys.Ingersoll@Sun.COM                                     const char * const i_pIPv4Address,
1799*12720SWyllys.Ingersoll@Sun.COM                                     const char * const i_pCurrentAddress
1800*12720SWyllys.Ingersoll@Sun.COM                                     )
1801*12720SWyllys.Ingersoll@Sun.COM {
1802*12720SWyllys.Ingersoll@Sun.COM     bool bEqualAddress = true;
1803*12720SWyllys.Ingersoll@Sun.COM 
1804*12720SWyllys.Ingersoll@Sun.COM     if ( i_pCurrentAddress == NULL )
1805*12720SWyllys.Ingersoll@Sun.COM     {
1806*12720SWyllys.Ingersoll@Sun.COM         return false;
1807*12720SWyllys.Ingersoll@Sun.COM     }
1808*12720SWyllys.Ingersoll@Sun.COM 
1809*12720SWyllys.Ingersoll@Sun.COM     if (i_bUseIPv6)
1810*12720SWyllys.Ingersoll@Sun.COM     {
1811*12720SWyllys.Ingersoll@Sun.COM         if ( i_pIPv6Address == NULL )
1812*12720SWyllys.Ingersoll@Sun.COM         {
1813*12720SWyllys.Ingersoll@Sun.COM             return false;
1814*12720SWyllys.Ingersoll@Sun.COM         }
1815*12720SWyllys.Ingersoll@Sun.COM         char sIPv6Address[KMS_MAX_NETWORK_ADDRESS] = "[";
1816*12720SWyllys.Ingersoll@Sun.COM 
1817*12720SWyllys.Ingersoll@Sun.COM         strcat(sIPv6Address, i_pIPv6Address);
1818*12720SWyllys.Ingersoll@Sun.COM 
1819*12720SWyllys.Ingersoll@Sun.COM         char * pLoc = strchr(sIPv6Address, '/');
1820*12720SWyllys.Ingersoll@Sun.COM 
1821*12720SWyllys.Ingersoll@Sun.COM         if ( pLoc != NULL )
1822*12720SWyllys.Ingersoll@Sun.COM         {
1823*12720SWyllys.Ingersoll@Sun.COM             // remove prefix from address
1824*12720SWyllys.Ingersoll@Sun.COM             *pLoc = '\0';
1825*12720SWyllys.Ingersoll@Sun.COM         }
1826*12720SWyllys.Ingersoll@Sun.COM         strcat(sIPv6Address, "]");
1827*12720SWyllys.Ingersoll@Sun.COM         bEqualAddress = strncmp(sIPv6Address, i_pCurrentAddress, KMS_MAX_NETWORK_ADDRESS) == 0;
1828*12720SWyllys.Ingersoll@Sun.COM     }
1829*12720SWyllys.Ingersoll@Sun.COM     else
1830*12720SWyllys.Ingersoll@Sun.COM     {
1831*12720SWyllys.Ingersoll@Sun.COM         if ( i_pIPv4Address == NULL )
1832*12720SWyllys.Ingersoll@Sun.COM         {
1833*12720SWyllys.Ingersoll@Sun.COM             return false;
1834*12720SWyllys.Ingersoll@Sun.COM         }
1835*12720SWyllys.Ingersoll@Sun.COM         bEqualAddress = strncmp(i_pIPv4Address, i_pCurrentAddress, KMS_MAX_NETWORK_ADDRESS) == 0;
1836*12720SWyllys.Ingersoll@Sun.COM     }
1837*12720SWyllys.Ingersoll@Sun.COM 
1838*12720SWyllys.Ingersoll@Sun.COM     return bEqualAddress;
1839*12720SWyllys.Ingersoll@Sun.COM }
1840*12720SWyllys.Ingersoll@Sun.COM 
1841*12720SWyllys.Ingersoll@Sun.COM /**
1842*12720SWyllys.Ingersoll@Sun.COM  *  compares the profile's current cluster state with the filtered discover
1843*12720SWyllys.Ingersoll@Sun.COM  *  cluster response and returns true if the repsonse
1844*12720SWyllys.Ingersoll@Sun.COM  *  differs from i_pProfile->m_aCluster.  A cluster has changed if the state of any
1845*12720SWyllys.Ingersoll@Sun.COM  *  cluster node has changed or if the set of cluster nodes has changed.
1846*12720SWyllys.Ingersoll@Sun.COM  *  The order of nodes is immaterial.
1847*12720SWyllys.Ingersoll@Sun.COM  */
ClusterConfigChanged(KMSClientProfile const * i_pProfile,char * const i_sResponseEntitySiteID,struct KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers const * i_pFilteredCluster)1848*12720SWyllys.Ingersoll@Sun.COM static bool ClusterConfigChanged (
1849*12720SWyllys.Ingersoll@Sun.COM                                   KMSClientProfile const *i_pProfile,
1850*12720SWyllys.Ingersoll@Sun.COM                                   char * const i_sResponseEntitySiteID,
1851*12720SWyllys.Ingersoll@Sun.COM                                   struct KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers const *i_pFilteredCluster)
1852*12720SWyllys.Ingersoll@Sun.COM {
1853*12720SWyllys.Ingersoll@Sun.COM     int i, j;
1854*12720SWyllys.Ingersoll@Sun.COM 
1855*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT(i_pProfile);
1856*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT(i_pFilteredCluster);
1857*12720SWyllys.Ingersoll@Sun.COM 
1858*12720SWyllys.Ingersoll@Sun.COM     // cardinality check
1859*12720SWyllys.Ingersoll@Sun.COM     if (i_pProfile->m_iClusterNum !=
1860*12720SWyllys.Ingersoll@Sun.COM         i_pFilteredCluster->__size)
1861*12720SWyllys.Ingersoll@Sun.COM     {
1862*12720SWyllys.Ingersoll@Sun.COM         return true;
1863*12720SWyllys.Ingersoll@Sun.COM     }
1864*12720SWyllys.Ingersoll@Sun.COM 
1865*12720SWyllys.Ingersoll@Sun.COM     // check if the agent's site ID changed
1866*12720SWyllys.Ingersoll@Sun.COM     if (strncmp(i_pProfile->m_wsEntitySiteID,
1867*12720SWyllys.Ingersoll@Sun.COM         i_sResponseEntitySiteID, KMS_MAX_ENTITY_SITE_ID) != 0)
1868*12720SWyllys.Ingersoll@Sun.COM     {
1869*12720SWyllys.Ingersoll@Sun.COM         return true;
1870*12720SWyllys.Ingersoll@Sun.COM     }
1871*12720SWyllys.Ingersoll@Sun.COM 
1872*12720SWyllys.Ingersoll@Sun.COM     // for all KMAs in filtered response check if they exist unchanged in the profile
1873*12720SWyllys.Ingersoll@Sun.COM     for (i = 0; i < i_pFilteredCluster->__size; i++)
1874*12720SWyllys.Ingersoll@Sun.COM     {
1875*12720SWyllys.Ingersoll@Sun.COM         bool bFound = false;
1876*12720SWyllys.Ingersoll@Sun.COM         for (j = 0; j < i_pProfile->m_iClusterNum; j++)
1877*12720SWyllys.Ingersoll@Sun.COM         {
1878*12720SWyllys.Ingersoll@Sun.COM             if (strncmp(i_pFilteredCluster->__ptr[i].KMAName,
1879*12720SWyllys.Ingersoll@Sun.COM                     i_pProfile->m_aCluster[j].m_wsApplianceAlias,
1880*12720SWyllys.Ingersoll@Sun.COM                     KMS_MAX_ENTITY_ID) == 0)
1881*12720SWyllys.Ingersoll@Sun.COM             {
1882*12720SWyllys.Ingersoll@Sun.COM                 bFound = true;
1883*12720SWyllys.Ingersoll@Sun.COM                 if (
1884*12720SWyllys.Ingersoll@Sun.COM                 !EqualKMANetworkAddress(
1885*12720SWyllys.Ingersoll@Sun.COM                     strchr(i_pProfile->m_wsApplianceAddress, ':') ? true : false,
1886*12720SWyllys.Ingersoll@Sun.COM                     i_pFilteredCluster->__ptr[i].KMANetworkAddressIPv6,
1887*12720SWyllys.Ingersoll@Sun.COM                     i_pFilteredCluster->__ptr[i].KMANetworkAddress,
1888*12720SWyllys.Ingersoll@Sun.COM                     i_pProfile->m_aCluster[j].m_wsApplianceNetworkAddress) ||
1889*12720SWyllys.Ingersoll@Sun.COM                 !EqualClusterEntry((i_pFilteredCluster->__ptr + i),
1890*12720SWyllys.Ingersoll@Sun.COM                     &i_pProfile->m_aCluster[j]))
1891*12720SWyllys.Ingersoll@Sun.COM 
1892*12720SWyllys.Ingersoll@Sun.COM                 {
1893*12720SWyllys.Ingersoll@Sun.COM                     return true;
1894*12720SWyllys.Ingersoll@Sun.COM                 }
1895*12720SWyllys.Ingersoll@Sun.COM             }
1896*12720SWyllys.Ingersoll@Sun.COM         }
1897*12720SWyllys.Ingersoll@Sun.COM         if ( !bFound )
1898*12720SWyllys.Ingersoll@Sun.COM         {
1899*12720SWyllys.Ingersoll@Sun.COM             return true;
1900*12720SWyllys.Ingersoll@Sun.COM         }
1901*12720SWyllys.Ingersoll@Sun.COM     }
1902*12720SWyllys.Ingersoll@Sun.COM     return false;
1903*12720SWyllys.Ingersoll@Sun.COM }
1904*12720SWyllys.Ingersoll@Sun.COM 
1905*12720SWyllys.Ingersoll@Sun.COM /**
1906*12720SWyllys.Ingersoll@Sun.COM  *  returns true if the string is a valid IPv6 address syntactically
1907*12720SWyllys.Ingersoll@Sun.COM  */
ValidIPv6KMAaddress(const char * const i_pIPAddress)1908*12720SWyllys.Ingersoll@Sun.COM static bool ValidIPv6KMAaddress( const char * const i_pIPAddress )
1909*12720SWyllys.Ingersoll@Sun.COM {
1910*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT( i_pIPAddress );
1911*12720SWyllys.Ingersoll@Sun.COM 
1912*12720SWyllys.Ingersoll@Sun.COM     if ( strlen(i_pIPAddress) <= 0 )
1913*12720SWyllys.Ingersoll@Sun.COM     {
1914*12720SWyllys.Ingersoll@Sun.COM         return false;
1915*12720SWyllys.Ingersoll@Sun.COM     }
1916*12720SWyllys.Ingersoll@Sun.COM 
1917*12720SWyllys.Ingersoll@Sun.COM     // simple check
1918*12720SWyllys.Ingersoll@Sun.COM     if ( strchr( i_pIPAddress, ':'))
1919*12720SWyllys.Ingersoll@Sun.COM     {
1920*12720SWyllys.Ingersoll@Sun.COM         return true;
1921*12720SWyllys.Ingersoll@Sun.COM     }
1922*12720SWyllys.Ingersoll@Sun.COM 
1923*12720SWyllys.Ingersoll@Sun.COM     return false;
1924*12720SWyllys.Ingersoll@Sun.COM }
1925*12720SWyllys.Ingersoll@Sun.COM /**
1926*12720SWyllys.Ingersoll@Sun.COM  *
1927*12720SWyllys.Ingersoll@Sun.COM  */
FreeFilteredCluster(struct KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers * const io_stFilteredCluster,int iLimit)1928*12720SWyllys.Ingersoll@Sun.COM static void FreeFilteredCluster (
1929*12720SWyllys.Ingersoll@Sun.COM                                   struct KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers * const io_stFilteredCluster,
1930*12720SWyllys.Ingersoll@Sun.COM                                   int iLimit )
1931*12720SWyllys.Ingersoll@Sun.COM {
1932*12720SWyllys.Ingersoll@Sun.COM     int j = 0;
1933*12720SWyllys.Ingersoll@Sun.COM     for (; j < iLimit; j++ )
1934*12720SWyllys.Ingersoll@Sun.COM     {
1935*12720SWyllys.Ingersoll@Sun.COM         free( io_stFilteredCluster->__ptr[j].KMAName );
1936*12720SWyllys.Ingersoll@Sun.COM         free( io_stFilteredCluster->__ptr[j].KMASiteID );
1937*12720SWyllys.Ingersoll@Sun.COM         free( io_stFilteredCluster->__ptr[j].KMAHostName );
1938*12720SWyllys.Ingersoll@Sun.COM         free( io_stFilteredCluster->__ptr[j].KMANetworkAddress );
1939*12720SWyllys.Ingersoll@Sun.COM         free( io_stFilteredCluster->__ptr[j].KMAVersion );
1940*12720SWyllys.Ingersoll@Sun.COM         free( io_stFilteredCluster->__ptr[j].KMAHostNameIPv6 );
1941*12720SWyllys.Ingersoll@Sun.COM         free( io_stFilteredCluster->__ptr[j].KMANetworkAddressIPv6 );
1942*12720SWyllys.Ingersoll@Sun.COM     }
1943*12720SWyllys.Ingersoll@Sun.COM 
1944*12720SWyllys.Ingersoll@Sun.COM     free( io_stFilteredCluster->__ptr );
1945*12720SWyllys.Ingersoll@Sun.COM }
1946*12720SWyllys.Ingersoll@Sun.COM 
1947*12720SWyllys.Ingersoll@Sun.COM /**
1948*12720SWyllys.Ingersoll@Sun.COM  *  filters the discover cluster response to be less than or equal to KMS_MAX_CLUSTER_NUM KMAs.  The heuristic used to filter
1949*12720SWyllys.Ingersoll@Sun.COM  *  the response is the same as used by CAgentLoadBalancer::KMSClient_SortClusterArray(), FIPS compatibility, then within site,
1950*12720SWyllys.Ingersoll@Sun.COM  *  then responding and enabled KMAs.
1951*12720SWyllys.Ingersoll@Sun.COM  *  @param i_stResponse pointer to gsoap discover cluster service response
1952*12720SWyllys.Ingersoll@Sun.COM  *  @param io_stFilteredCluster pointer to gsoap discover cluster array to be populated with the filtered list of KMAs
1953*12720SWyllys.Ingersoll@Sun.COM  *  @return true on success and io_stFilteredCluster->__size less than or equal to KMS_MAX_CLUSTER_NUM,
1954*12720SWyllys.Ingersoll@Sun.COM  *  otherwise io_stFilteredCluster is undefined. io_stFilteredCluster->__ptr is populated with the array of elements
1955*12720SWyllys.Ingersoll@Sun.COM  *  malloc'd.
1956*12720SWyllys.Ingersoll@Sun.COM  */
FilterCluster(struct KMS_Discovery::KMS_Discovery__DiscoverClusterResponse * const i_stResponse,bool i_bFIPS,struct KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers * const io_stFilteredCluster)1957*12720SWyllys.Ingersoll@Sun.COM static bool FilterCluster (struct KMS_Discovery::KMS_Discovery__DiscoverClusterResponse * const i_stResponse,
1958*12720SWyllys.Ingersoll@Sun.COM                            bool i_bFIPS,
1959*12720SWyllys.Ingersoll@Sun.COM                            struct KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers * const io_stFilteredCluster)
1960*12720SWyllys.Ingersoll@Sun.COM {
1961*12720SWyllys.Ingersoll@Sun.COM     /*
1962*12720SWyllys.Ingersoll@Sun.COM      *  do something like KMSAgentLoadBalancer:SortClusterArray() to the stResponse array
1963*12720SWyllys.Ingersoll@Sun.COM      *  return 1st KMS_MAX_CLUSTER_NUM entries and free the rest.
1964*12720SWyllys.Ingersoll@Sun.COM     */
1965*12720SWyllys.Ingersoll@Sun.COM 
1966*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT(i_stResponse);
1967*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT(io_stFilteredCluster);
1968*12720SWyllys.Ingersoll@Sun.COM 
1969*12720SWyllys.Ingersoll@Sun.COM     io_stFilteredCluster->__size = i_stResponse->ArrayOfClusterMembers.__size;
1970*12720SWyllys.Ingersoll@Sun.COM     io_stFilteredCluster->__ptr = reinterpret_cast < struct KMS_Discovery::KMS_Discovery_ClusterMember * >
1971*12720SWyllys.Ingersoll@Sun.COM             ( calloc( io_stFilteredCluster->__size,
1972*12720SWyllys.Ingersoll@Sun.COM                       sizeof (struct KMS_Discovery::KMS_Discovery_ClusterMember ) ) );
1973*12720SWyllys.Ingersoll@Sun.COM 
1974*12720SWyllys.Ingersoll@Sun.COM     if (io_stFilteredCluster->__ptr == NULL)
1975*12720SWyllys.Ingersoll@Sun.COM     {
1976*12720SWyllys.Ingersoll@Sun.COM         Log(AUDIT_CLIENT_FILTER_CLUSTER_FAILED,
1977*12720SWyllys.Ingersoll@Sun.COM                 NULL,
1978*12720SWyllys.Ingersoll@Sun.COM                 NULL,
1979*12720SWyllys.Ingersoll@Sun.COM                 "calloc failed");
1980*12720SWyllys.Ingersoll@Sun.COM         return false;
1981*12720SWyllys.Ingersoll@Sun.COM     }
1982*12720SWyllys.Ingersoll@Sun.COM 
1983*12720SWyllys.Ingersoll@Sun.COM     if (io_stFilteredCluster->__size <= 0)
1984*12720SWyllys.Ingersoll@Sun.COM     {
1985*12720SWyllys.Ingersoll@Sun.COM         Log(AUDIT_CLIENT_FILTER_CLUSTER_FAILED,
1986*12720SWyllys.Ingersoll@Sun.COM                 NULL,
1987*12720SWyllys.Ingersoll@Sun.COM                 NULL,
1988*12720SWyllys.Ingersoll@Sun.COM                 "returned cluster size is not positive");
1989*12720SWyllys.Ingersoll@Sun.COM         return false;
1990*12720SWyllys.Ingersoll@Sun.COM     }
1991*12720SWyllys.Ingersoll@Sun.COM 
1992*12720SWyllys.Ingersoll@Sun.COM     // copy response cluster members
1993*12720SWyllys.Ingersoll@Sun.COM     for (int i = 0; i < io_stFilteredCluster->__size; i++)
1994*12720SWyllys.Ingersoll@Sun.COM     {
1995*12720SWyllys.Ingersoll@Sun.COM         bool bSuccess = true;
1996*12720SWyllys.Ingersoll@Sun.COM 
1997*12720SWyllys.Ingersoll@Sun.COM         size_t iKMANameSize = 0, iKMASiteIDSize = 0, iKMAHostNameSize = 0,
1998*12720SWyllys.Ingersoll@Sun.COM                 iKMANetworkAddressSize = 0, iKMAVersionSize = 0, iKMAHostNameIPv6Size = 0,
1999*12720SWyllys.Ingersoll@Sun.COM                 iKMANetworkAddressIPv6Size = 0;
2000*12720SWyllys.Ingersoll@Sun.COM 
2001*12720SWyllys.Ingersoll@Sun.COM         // allocate storage for the various struct member's arrays
2002*12720SWyllys.Ingersoll@Sun.COM         iKMANameSize = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAName)+1;
2003*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].KMAName = reinterpret_cast <char *> (malloc(iKMANameSize));
2004*12720SWyllys.Ingersoll@Sun.COM 
2005*12720SWyllys.Ingersoll@Sun.COM         iKMASiteIDSize = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMASiteID)+1;
2006*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].KMASiteID = reinterpret_cast <char *> (malloc(iKMASiteIDSize));
2007*12720SWyllys.Ingersoll@Sun.COM 
2008*12720SWyllys.Ingersoll@Sun.COM         iKMAHostNameSize = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAHostName)+1;
2009*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].KMAHostName = reinterpret_cast <char *> (malloc(iKMAHostNameSize));
2010*12720SWyllys.Ingersoll@Sun.COM 
2011*12720SWyllys.Ingersoll@Sun.COM         iKMANetworkAddressSize = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMANetworkAddress)+1;
2012*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].KMANetworkAddress = reinterpret_cast <char *> (malloc(iKMANetworkAddressSize));
2013*12720SWyllys.Ingersoll@Sun.COM 
2014*12720SWyllys.Ingersoll@Sun.COM         // KMAVersion is an optional field derived from an xml attribute in the soap interface that will not be present in 2.0 KMAs
2015*12720SWyllys.Ingersoll@Sun.COM         if (i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAVersion)
2016*12720SWyllys.Ingersoll@Sun.COM         {
2017*12720SWyllys.Ingersoll@Sun.COM             iKMAVersionSize = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAVersion)+1;
2018*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].KMAVersion = reinterpret_cast <char *> (malloc(iKMAVersionSize));
2019*12720SWyllys.Ingersoll@Sun.COM             if (io_stFilteredCluster->__ptr[i].KMAVersion == NULL)
2020*12720SWyllys.Ingersoll@Sun.COM             {
2021*12720SWyllys.Ingersoll@Sun.COM                 bSuccess = false;
2022*12720SWyllys.Ingersoll@Sun.COM             }
2023*12720SWyllys.Ingersoll@Sun.COM         }
2024*12720SWyllys.Ingersoll@Sun.COM         else
2025*12720SWyllys.Ingersoll@Sun.COM         {
2026*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].KMAVersion = NULL;
2027*12720SWyllys.Ingersoll@Sun.COM         }
2028*12720SWyllys.Ingersoll@Sun.COM 
2029*12720SWyllys.Ingersoll@Sun.COM         // KMAHostNameIPv6 is an optional field derived from an xml attribute in the soap interface that will not be present in 2.0 KMAs
2030*12720SWyllys.Ingersoll@Sun.COM         if (i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAHostNameIPv6)
2031*12720SWyllys.Ingersoll@Sun.COM         {
2032*12720SWyllys.Ingersoll@Sun.COM             iKMAHostNameIPv6Size = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAHostNameIPv6)+1;
2033*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].KMAHostNameIPv6 = reinterpret_cast <char *> (malloc(iKMAHostNameIPv6Size));
2034*12720SWyllys.Ingersoll@Sun.COM             if ( io_stFilteredCluster->__ptr[i].KMAHostNameIPv6 == NULL )
2035*12720SWyllys.Ingersoll@Sun.COM             {
2036*12720SWyllys.Ingersoll@Sun.COM                 bSuccess = false;
2037*12720SWyllys.Ingersoll@Sun.COM             }
2038*12720SWyllys.Ingersoll@Sun.COM         }
2039*12720SWyllys.Ingersoll@Sun.COM         else
2040*12720SWyllys.Ingersoll@Sun.COM         {
2041*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].KMAHostNameIPv6 = NULL;
2042*12720SWyllys.Ingersoll@Sun.COM         }
2043*12720SWyllys.Ingersoll@Sun.COM 
2044*12720SWyllys.Ingersoll@Sun.COM         // KMANetworkAddressIPv6 is an optional field derived from an xml attribute in the soap interface that will not be present in 2.0 KMAs
2045*12720SWyllys.Ingersoll@Sun.COM         if (i_stResponse->ArrayOfClusterMembers.__ptr[i].KMANetworkAddressIPv6)
2046*12720SWyllys.Ingersoll@Sun.COM         {
2047*12720SWyllys.Ingersoll@Sun.COM             iKMANetworkAddressIPv6Size = strlen(i_stResponse->ArrayOfClusterMembers.__ptr[i].KMANetworkAddressIPv6)+1;
2048*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6 = reinterpret_cast <char *> (malloc(iKMANetworkAddressIPv6Size));
2049*12720SWyllys.Ingersoll@Sun.COM             if ( io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6 == NULL )
2050*12720SWyllys.Ingersoll@Sun.COM             {
2051*12720SWyllys.Ingersoll@Sun.COM                 bSuccess = false;
2052*12720SWyllys.Ingersoll@Sun.COM             }
2053*12720SWyllys.Ingersoll@Sun.COM             }
2054*12720SWyllys.Ingersoll@Sun.COM         else
2055*12720SWyllys.Ingersoll@Sun.COM         {
2056*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6 = NULL;
2057*12720SWyllys.Ingersoll@Sun.COM         }
2058*12720SWyllys.Ingersoll@Sun.COM 
2059*12720SWyllys.Ingersoll@Sun.COM         if ( io_stFilteredCluster->__ptr[i].KMAName == NULL ||
2060*12720SWyllys.Ingersoll@Sun.COM              io_stFilteredCluster->__ptr[i].KMASiteID == NULL ||
2061*12720SWyllys.Ingersoll@Sun.COM              io_stFilteredCluster->__ptr[i].KMAHostName == NULL ||
2062*12720SWyllys.Ingersoll@Sun.COM              io_stFilteredCluster->__ptr[i].KMANetworkAddress == NULL ||
2063*12720SWyllys.Ingersoll@Sun.COM              !bSuccess )
2064*12720SWyllys.Ingersoll@Sun.COM         {
2065*12720SWyllys.Ingersoll@Sun.COM             // cleanup and return
2066*12720SWyllys.Ingersoll@Sun.COM             FreeFilteredCluster( io_stFilteredCluster, i+1 );
2067*12720SWyllys.Ingersoll@Sun.COM             Log( AUDIT_CLIENT_FILTER_CLUSTER_FAILED,
2068*12720SWyllys.Ingersoll@Sun.COM                     NULL,
2069*12720SWyllys.Ingersoll@Sun.COM                     NULL,
2070*12720SWyllys.Ingersoll@Sun.COM                     "malloc failed" );
2071*12720SWyllys.Ingersoll@Sun.COM             return false;
2072*12720SWyllys.Ingersoll@Sun.COM         }
2073*12720SWyllys.Ingersoll@Sun.COM 
2074*12720SWyllys.Ingersoll@Sun.COM         strncpy(io_stFilteredCluster->__ptr[i].KMAName,
2075*12720SWyllys.Ingersoll@Sun.COM                 i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAName,
2076*12720SWyllys.Ingersoll@Sun.COM                 iKMANameSize);
2077*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].KMAName[iKMANameSize-1] = '\0';
2078*12720SWyllys.Ingersoll@Sun.COM 
2079*12720SWyllys.Ingersoll@Sun.COM         strncpy(io_stFilteredCluster->__ptr[i].KMASiteID,
2080*12720SWyllys.Ingersoll@Sun.COM                 i_stResponse->ArrayOfClusterMembers.__ptr[i].KMASiteID,
2081*12720SWyllys.Ingersoll@Sun.COM                 iKMASiteIDSize);
2082*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].KMASiteID[iKMASiteIDSize-1] = '\0';
2083*12720SWyllys.Ingersoll@Sun.COM 
2084*12720SWyllys.Ingersoll@Sun.COM         strncpy(io_stFilteredCluster->__ptr[i].KMAHostName,
2085*12720SWyllys.Ingersoll@Sun.COM                 i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAHostName,
2086*12720SWyllys.Ingersoll@Sun.COM                 iKMAHostNameSize);
2087*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].KMAHostName[iKMAHostNameSize-1] = '\0';
2088*12720SWyllys.Ingersoll@Sun.COM 
2089*12720SWyllys.Ingersoll@Sun.COM         strncpy(io_stFilteredCluster->__ptr[i].KMANetworkAddress,
2090*12720SWyllys.Ingersoll@Sun.COM                 i_stResponse->ArrayOfClusterMembers.__ptr[i].KMANetworkAddress,
2091*12720SWyllys.Ingersoll@Sun.COM                 iKMANetworkAddressSize);
2092*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].KMANetworkAddress[iKMANetworkAddressSize-1] = '\0';
2093*12720SWyllys.Ingersoll@Sun.COM 
2094*12720SWyllys.Ingersoll@Sun.COM         if ( io_stFilteredCluster->__ptr[i].KMAVersion )
2095*12720SWyllys.Ingersoll@Sun.COM         {
2096*12720SWyllys.Ingersoll@Sun.COM             strncpy( io_stFilteredCluster->__ptr[i].KMAVersion,
2097*12720SWyllys.Ingersoll@Sun.COM                     i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAVersion,
2098*12720SWyllys.Ingersoll@Sun.COM                     iKMAVersionSize );
2099*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].KMAVersion[iKMAVersionSize-1] = '\0';
2100*12720SWyllys.Ingersoll@Sun.COM         }
2101*12720SWyllys.Ingersoll@Sun.COM 
2102*12720SWyllys.Ingersoll@Sun.COM         if (io_stFilteredCluster->__ptr[i].KMAHostNameIPv6)
2103*12720SWyllys.Ingersoll@Sun.COM         {
2104*12720SWyllys.Ingersoll@Sun.COM             strncpy(io_stFilteredCluster->__ptr[i].KMAHostNameIPv6,
2105*12720SWyllys.Ingersoll@Sun.COM                     i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAHostNameIPv6,
2106*12720SWyllys.Ingersoll@Sun.COM                     iKMAHostNameIPv6Size);
2107*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].KMAHostNameIPv6[iKMAHostNameIPv6Size-1] = '\0';
2108*12720SWyllys.Ingersoll@Sun.COM         }
2109*12720SWyllys.Ingersoll@Sun.COM 
2110*12720SWyllys.Ingersoll@Sun.COM         if ( io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6 )
2111*12720SWyllys.Ingersoll@Sun.COM         {
2112*12720SWyllys.Ingersoll@Sun.COM             strncpy( io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6,
2113*12720SWyllys.Ingersoll@Sun.COM                     i_stResponse->ArrayOfClusterMembers.__ptr[i].KMANetworkAddressIPv6,
2114*12720SWyllys.Ingersoll@Sun.COM                     iKMANetworkAddressIPv6Size );
2115*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6[iKMANetworkAddressIPv6Size-1] = '\0';
2116*12720SWyllys.Ingersoll@Sun.COM         }
2117*12720SWyllys.Ingersoll@Sun.COM 
2118*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].KMAID = i_stResponse->ArrayOfClusterMembers.__ptr[i].KMAID;
2119*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].Enabled = i_stResponse->ArrayOfClusterMembers.__ptr[i].Enabled;
2120*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].KMS_Discovery__Locked = i_stResponse->ArrayOfClusterMembers.__ptr[i].KMS_Discovery__Locked;
2121*12720SWyllys.Ingersoll@Sun.COM 
2122*12720SWyllys.Ingersoll@Sun.COM         // set load to zero, KMA with version <= Build600 don't initialize
2123*12720SWyllys.Ingersoll@Sun.COM         // the load field from the service network
2124*12720SWyllys.Ingersoll@Sun.COM         if ( ( io_stFilteredCluster->__ptr[i].KMAVersion &&
2125*12720SWyllys.Ingersoll@Sun.COM              strcmp( io_stFilteredCluster->__ptr[i].KMAVersion, "Build600" ) <= 0 ) ||
2126*12720SWyllys.Ingersoll@Sun.COM              io_stFilteredCluster->__ptr[i].KMAVersion == NULL )
2127*12720SWyllys.Ingersoll@Sun.COM         {
2128*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].Load = 0;
2129*12720SWyllys.Ingersoll@Sun.COM         }
2130*12720SWyllys.Ingersoll@Sun.COM         else
2131*12720SWyllys.Ingersoll@Sun.COM         {
2132*12720SWyllys.Ingersoll@Sun.COM             io_stFilteredCluster->__ptr[i].Load = i_stResponse->ArrayOfClusterMembers.__ptr[i].Load;
2133*12720SWyllys.Ingersoll@Sun.COM         }
2134*12720SWyllys.Ingersoll@Sun.COM 
2135*12720SWyllys.Ingersoll@Sun.COM         io_stFilteredCluster->__ptr[i].Responding = i_stResponse->ArrayOfClusterMembers.__ptr[i].Responding;
2136*12720SWyllys.Ingersoll@Sun.COM 
2137*12720SWyllys.Ingersoll@Sun.COM         if (!bSuccess)
2138*12720SWyllys.Ingersoll@Sun.COM         {
2139*12720SWyllys.Ingersoll@Sun.COM             FreeFilteredCluster( io_stFilteredCluster, i );
2140*12720SWyllys.Ingersoll@Sun.COM             Log(AUDIT_CLIENT_FILTER_CLUSTER_FAILED,
2141*12720SWyllys.Ingersoll@Sun.COM                     NULL,
2142*12720SWyllys.Ingersoll@Sun.COM                     NULL,
2143*12720SWyllys.Ingersoll@Sun.COM                     "cluster member copy failed");
2144*12720SWyllys.Ingersoll@Sun.COM             return false;
2145*12720SWyllys.Ingersoll@Sun.COM         }
2146*12720SWyllys.Ingersoll@Sun.COM     }
2147*12720SWyllys.Ingersoll@Sun.COM 
2148*12720SWyllys.Ingersoll@Sun.COM     // is filtering necessary?
2149*12720SWyllys.Ingersoll@Sun.COM     if (io_stFilteredCluster->__size <= KMS_MAX_CLUSTER_NUM)
2150*12720SWyllys.Ingersoll@Sun.COM     {
2151*12720SWyllys.Ingersoll@Sun.COM         // no filtering required
2152*12720SWyllys.Ingersoll@Sun.COM         return true;
2153*12720SWyllys.Ingersoll@Sun.COM     }
2154*12720SWyllys.Ingersoll@Sun.COM     else
2155*12720SWyllys.Ingersoll@Sun.COM     {
2156*12720SWyllys.Ingersoll@Sun.COM         char sMesg[100];
2157*12720SWyllys.Ingersoll@Sun.COM         K_snprintf(sMesg, sizeof (sMesg), "DiscoverCluster returned %d KMAs, filtering to %d ...", io_stFilteredCluster->__size, KMS_MAX_CLUSTER_NUM);
2158*12720SWyllys.Ingersoll@Sun.COM         Log(AUDIT_CLIENT_FILTER_CLUSTER,
2159*12720SWyllys.Ingersoll@Sun.COM                     NULL,
2160*12720SWyllys.Ingersoll@Sun.COM                     NULL,
2161*12720SWyllys.Ingersoll@Sun.COM                     sMesg);
2162*12720SWyllys.Ingersoll@Sun.COM 
2163*12720SWyllys.Ingersoll@Sun.COM     }
2164*12720SWyllys.Ingersoll@Sun.COM 
2165*12720SWyllys.Ingersoll@Sun.COM     // adjust loads according to availability, site and FIPS compatibility
2166*12720SWyllys.Ingersoll@Sun.COM     {
2167*12720SWyllys.Ingersoll@Sun.COM         int i = 0;
2168*12720SWyllys.Ingersoll@Sun.COM         for (; i < io_stFilteredCluster->__size; i++)
2169*12720SWyllys.Ingersoll@Sun.COM         {
2170*12720SWyllys.Ingersoll@Sun.COM             if (io_stFilteredCluster->__ptr[i].Enabled == false
2171*12720SWyllys.Ingersoll@Sun.COM                 || io_stFilteredCluster->__ptr[i].Responding == false
2172*12720SWyllys.Ingersoll@Sun.COM                 || io_stFilteredCluster->__ptr[i].KMS_Discovery__Locked == true)
2173*12720SWyllys.Ingersoll@Sun.COM             {
2174*12720SWyllys.Ingersoll@Sun.COM                 io_stFilteredCluster->__ptr[i].Load += 0x40;
2175*12720SWyllys.Ingersoll@Sun.COM             }
2176*12720SWyllys.Ingersoll@Sun.COM 
2177*12720SWyllys.Ingersoll@Sun.COM             if (strcmp(io_stFilteredCluster->__ptr[i].KMASiteID,
2178*12720SWyllys.Ingersoll@Sun.COM                 i_stResponse->EntitySiteID) != 0)
2179*12720SWyllys.Ingersoll@Sun.COM             {
2180*12720SWyllys.Ingersoll@Sun.COM                 io_stFilteredCluster->__ptr[i].Load += 0x20;
2181*12720SWyllys.Ingersoll@Sun.COM 
2182*12720SWyllys.Ingersoll@Sun.COM             }
2183*12720SWyllys.Ingersoll@Sun.COM 
2184*12720SWyllys.Ingersoll@Sun.COM             if ( i_bFIPS &&
2185*12720SWyllys.Ingersoll@Sun.COM                     !FIPScompatibleKMA(io_stFilteredCluster->__ptr[i].KMAVersion))
2186*12720SWyllys.Ingersoll@Sun.COM             {
2187*12720SWyllys.Ingersoll@Sun.COM                 io_stFilteredCluster->__ptr[i].Load += 0x80;
2188*12720SWyllys.Ingersoll@Sun.COM             }
2189*12720SWyllys.Ingersoll@Sun.COM         }
2190*12720SWyllys.Ingersoll@Sun.COM     }
2191*12720SWyllys.Ingersoll@Sun.COM 
2192*12720SWyllys.Ingersoll@Sun.COM     // sort ascending by load
2193*12720SWyllys.Ingersoll@Sun.COM 
2194*12720SWyllys.Ingersoll@Sun.COM     // gnome sort: the simplest sort algoritm
2195*12720SWyllys.Ingersoll@Sun.COM     {
2196*12720SWyllys.Ingersoll@Sun.COM         int i = 0;
2197*12720SWyllys.Ingersoll@Sun.COM         while (i < io_stFilteredCluster->__size)
2198*12720SWyllys.Ingersoll@Sun.COM         {
2199*12720SWyllys.Ingersoll@Sun.COM             if (i == 0 || io_stFilteredCluster->__ptr[i - 1].Load <= io_stFilteredCluster->__ptr[i].Load)
2200*12720SWyllys.Ingersoll@Sun.COM             {
2201*12720SWyllys.Ingersoll@Sun.COM                 i++;
2202*12720SWyllys.Ingersoll@Sun.COM             }
2203*12720SWyllys.Ingersoll@Sun.COM             else
2204*12720SWyllys.Ingersoll@Sun.COM             {
2205*12720SWyllys.Ingersoll@Sun.COM                 struct KMS_Discovery::KMS_Discovery_ClusterMember tmp = io_stFilteredCluster->__ptr[i];
2206*12720SWyllys.Ingersoll@Sun.COM                 io_stFilteredCluster->__ptr[i] = io_stFilteredCluster->__ptr[i - 1];
2207*12720SWyllys.Ingersoll@Sun.COM                 io_stFilteredCluster->__ptr[--i] = tmp;
2208*12720SWyllys.Ingersoll@Sun.COM             }
2209*12720SWyllys.Ingersoll@Sun.COM         }
2210*12720SWyllys.Ingersoll@Sun.COM     }
2211*12720SWyllys.Ingersoll@Sun.COM 
2212*12720SWyllys.Ingersoll@Sun.COM     // now filter the list, freeing memory allocated for copied elements that are not being retained
2213*12720SWyllys.Ingersoll@Sun.COM     {
2214*12720SWyllys.Ingersoll@Sun.COM         int i=KMS_MAX_CLUSTER_NUM;
2215*12720SWyllys.Ingersoll@Sun.COM         for (; i < io_stFilteredCluster->__size; i++)
2216*12720SWyllys.Ingersoll@Sun.COM         {
2217*12720SWyllys.Ingersoll@Sun.COM             free(io_stFilteredCluster->__ptr[i].KMAName);
2218*12720SWyllys.Ingersoll@Sun.COM             free(io_stFilteredCluster->__ptr[i].KMASiteID);
2219*12720SWyllys.Ingersoll@Sun.COM             free(io_stFilteredCluster->__ptr[i].KMAHostName);
2220*12720SWyllys.Ingersoll@Sun.COM             free(io_stFilteredCluster->__ptr[i].KMANetworkAddress);
2221*12720SWyllys.Ingersoll@Sun.COM             free(io_stFilteredCluster->__ptr[i].KMAVersion);
2222*12720SWyllys.Ingersoll@Sun.COM             free(io_stFilteredCluster->__ptr[i].KMAHostNameIPv6);
2223*12720SWyllys.Ingersoll@Sun.COM             free(io_stFilteredCluster->__ptr[i].KMANetworkAddressIPv6);
2224*12720SWyllys.Ingersoll@Sun.COM         }
2225*12720SWyllys.Ingersoll@Sun.COM     }
2226*12720SWyllys.Ingersoll@Sun.COM 
2227*12720SWyllys.Ingersoll@Sun.COM     io_stFilteredCluster->__size = KMS_MAX_CLUSTER_NUM;
2228*12720SWyllys.Ingersoll@Sun.COM 
2229*12720SWyllys.Ingersoll@Sun.COM     Log(AUDIT_CLIENT_FILTER_CLUSTER,
2230*12720SWyllys.Ingersoll@Sun.COM                 NULL,
2231*12720SWyllys.Ingersoll@Sun.COM                 NULL,
2232*12720SWyllys.Ingersoll@Sun.COM                 "success");
2233*12720SWyllys.Ingersoll@Sun.COM 
2234*12720SWyllys.Ingersoll@Sun.COM     return true;
2235*12720SWyllys.Ingersoll@Sun.COM };
2236*12720SWyllys.Ingersoll@Sun.COM 
2237*12720SWyllys.Ingersoll@Sun.COM /*---------------------------------------------------------------------------
2238*12720SWyllys.Ingersoll@Sun.COM  * Function: KMSClient_GetClusterInformation
2239*12720SWyllys.Ingersoll@Sun.COM  *
2240*12720SWyllys.Ingersoll@Sun.COM  *--------------------------------------------------------------------------*/
KMSClient_GetClusterInformation(KMSClientProfile * i_pProfile,utf8char * o_wsEntitySiteID,int i_iEntitySiteIDSize,int * o_pApplianceNum,KMSClusterEntry * o_pClusterEntryArray,int i_iClusterEntryArraySize)2241*12720SWyllys.Ingersoll@Sun.COM bool KMSClient_GetClusterInformation(
2242*12720SWyllys.Ingersoll@Sun.COM         KMSClientProfile *i_pProfile,
2243*12720SWyllys.Ingersoll@Sun.COM         utf8char *o_wsEntitySiteID,
2244*12720SWyllys.Ingersoll@Sun.COM         int i_iEntitySiteIDSize,
2245*12720SWyllys.Ingersoll@Sun.COM         int *o_pApplianceNum,
2246*12720SWyllys.Ingersoll@Sun.COM         KMSClusterEntry *o_pClusterEntryArray,
2247*12720SWyllys.Ingersoll@Sun.COM         int i_iClusterEntryArraySize)
2248*12720SWyllys.Ingersoll@Sun.COM {
2249*12720SWyllys.Ingersoll@Sun.COM    FATAL_ASSERT(i_pProfile);
2250*12720SWyllys.Ingersoll@Sun.COM    FATAL_ASSERT( o_wsEntitySiteID );
2251*12720SWyllys.Ingersoll@Sun.COM    FATAL_ASSERT( o_pApplianceNum );
2252*12720SWyllys.Ingersoll@Sun.COM    FATAL_ASSERT( o_pClusterEntryArray );
2253*12720SWyllys.Ingersoll@Sun.COM    FATAL_ASSERT( i_iEntitySiteIDSize <= KMS_MAX_ENTITY_ID+1 );
2254*12720SWyllys.Ingersoll@Sun.COM 
2255*12720SWyllys.Ingersoll@Sun.COM    CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
2256*12720SWyllys.Ingersoll@Sun.COM 
2257*12720SWyllys.Ingersoll@Sun.COM    bool bSuccess = true;
2258*12720SWyllys.Ingersoll@Sun.COM    char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
2259*12720SWyllys.Ingersoll@Sun.COM    char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
2260*12720SWyllys.Ingersoll@Sun.COM 
2261*12720SWyllys.Ingersoll@Sun.COM    char sURL[KMS_MAX_URL+1];
2262*12720SWyllys.Ingersoll@Sun.COM 
2263*12720SWyllys.Ingersoll@Sun.COM    // set URL from the initial appliance address
2264*12720SWyllys.Ingersoll@Sun.COM    utf8cstr sApplianceAddress = i_pProfile->m_wsApplianceAddress;
2265*12720SWyllys.Ingersoll@Sun.COM 
2266*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
2267*12720SWyllys.Ingersoll@Sun.COM     log_printf("KMSClient_GetClusterInformation : entered");
2268*12720SWyllys.Ingersoll@Sun.COM #endif
2269*12720SWyllys.Ingersoll@Sun.COM 
2270*12720SWyllys.Ingersoll@Sun.COM    K_snprintf(sURL,
2271*12720SWyllys.Ingersoll@Sun.COM            KMS_MAX_URL,
2272*12720SWyllys.Ingersoll@Sun.COM            "https://%s:%d",
2273*12720SWyllys.Ingersoll@Sun.COM            sApplianceAddress,
2274*12720SWyllys.Ingersoll@Sun.COM            i_pProfile->m_iPortForDiscoveryService);
2275*12720SWyllys.Ingersoll@Sun.COM    strncpy(i_pProfile->m_sURL, sURL, KMS_MAX_URL);
2276*12720SWyllys.Ingersoll@Sun.COM    i_pProfile->m_sURL[KMS_MAX_URL] = 0;
2277*12720SWyllys.Ingersoll@Sun.COM 
2278*12720SWyllys.Ingersoll@Sun.COM    // allocate and initialize a new soap env for the cluster discovery call
2279*12720SWyllys.Ingersoll@Sun.COM    struct soap *pstSoap = (struct soap*)i_pProfile->m_pvDiscoverySoap;
2280*12720SWyllys.Ingersoll@Sun.COM 
2281*12720SWyllys.Ingersoll@Sun.COM    if ( !i_pProfile->m_iEnrolled )
2282*12720SWyllys.Ingersoll@Sun.COM    {
2283*12720SWyllys.Ingersoll@Sun.COM         bSuccess = false;
2284*12720SWyllys.Ingersoll@Sun.COM    }
2285*12720SWyllys.Ingersoll@Sun.COM 
2286*12720SWyllys.Ingersoll@Sun.COM    if ( bSuccess )
2287*12720SWyllys.Ingersoll@Sun.COM    {
2288*12720SWyllys.Ingersoll@Sun.COM 	   // allocate discovery soap runtime
2289*12720SWyllys.Ingersoll@Sun.COM 	   if (pstSoap == NULL )
2290*12720SWyllys.Ingersoll@Sun.COM 	   {
2291*12720SWyllys.Ingersoll@Sun.COM    	   	   pstSoap = soap_new();
2292*12720SWyllys.Ingersoll@Sun.COM 		   i_pProfile->m_pvDiscoverySoap = pstSoap;
2293*12720SWyllys.Ingersoll@Sun.COM            /* soap_copy results in a segfault in sk_free() within libcrytpo.so
2294*12720SWyllys.Ingersoll@Sun.COM            pstSoap = soap_copy( (soap*)i_pProfile->m_pvSoap );
2295*12720SWyllys.Ingersoll@Sun.COM            */
2296*12720SWyllys.Ingersoll@Sun.COM            if (pstSoap == NULL)
2297*12720SWyllys.Ingersoll@Sun.COM            {
2298*12720SWyllys.Ingersoll@Sun.COM                bSuccess = false;
2299*12720SWyllys.Ingersoll@Sun.COM            }
2300*12720SWyllys.Ingersoll@Sun.COM            else
2301*12720SWyllys.Ingersoll@Sun.COM            {
2302*12720SWyllys.Ingersoll@Sun.COM                pstSoap->connect_timeout = i_pProfile->m_iTransactionTimeout;
2303*12720SWyllys.Ingersoll@Sun.COM                pstSoap->send_timeout = i_pProfile->m_iTransactionTimeout;
2304*12720SWyllys.Ingersoll@Sun.COM                pstSoap->recv_timeout = i_pProfile->m_iTransactionTimeout;
2305*12720SWyllys.Ingersoll@Sun.COM 
2306*12720SWyllys.Ingersoll@Sun.COM                soap_set_imode( pstSoap, (SOAP_XML_STRICT | SOAP_C_UTFSTRING) );
2307*12720SWyllys.Ingersoll@Sun.COM                soap_set_omode( pstSoap, (SOAP_XML_STRICT | SOAP_C_UTFSTRING) );
2308*12720SWyllys.Ingersoll@Sun.COM 
2309*12720SWyllys.Ingersoll@Sun.COM                soap_set_namespaces( pstSoap, KMS_Discovery_namespaces );
2310*12720SWyllys.Ingersoll@Sun.COM                bSuccess = K_soap_ssl_client_context(
2311*12720SWyllys.Ingersoll@Sun.COM                                i_pProfile,
2312*12720SWyllys.Ingersoll@Sun.COM                                pstSoap,
2313*12720SWyllys.Ingersoll@Sun.COM                                SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION
2314*12720SWyllys.Ingersoll@Sun.COM                                 ) == SOAP_OK;
2315*12720SWyllys.Ingersoll@Sun.COM                if ( !bSuccess )
2316*12720SWyllys.Ingersoll@Sun.COM                {
2317*12720SWyllys.Ingersoll@Sun.COM                     Log(AUDIT_CLIENT_GetClusterInformation,
2318*12720SWyllys.Ingersoll@Sun.COM                        NULL,
2319*12720SWyllys.Ingersoll@Sun.COM                        NULL,
2320*12720SWyllys.Ingersoll@Sun.COM                        "K_soap_ssl_client_context failed");
2321*12720SWyllys.Ingersoll@Sun.COM                     soap_destroy(pstSoap);
2322*12720SWyllys.Ingersoll@Sun.COM                     soap_end(pstSoap);
2323*12720SWyllys.Ingersoll@Sun.COM                     soap_done(pstSoap);
2324*12720SWyllys.Ingersoll@Sun.COM                }
2325*12720SWyllys.Ingersoll@Sun.COM            }
2326*12720SWyllys.Ingersoll@Sun.COM 	   }
2327*12720SWyllys.Ingersoll@Sun.COM    }
2328*12720SWyllys.Ingersoll@Sun.COM 
2329*12720SWyllys.Ingersoll@Sun.COM    // Discovery
2330*12720SWyllys.Ingersoll@Sun.COM    struct KMS_Discovery::KMS_Discovery__DiscoverClusterResponse stResponse;
2331*12720SWyllys.Ingersoll@Sun.COM 
2332*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
2333*12720SWyllys.Ingersoll@Sun.COM     log_printf("KMSClient_GetClusterInformation : call KMS_Discovery_DiscoverCluster");
2334*12720SWyllys.Ingersoll@Sun.COM #endif
2335*12720SWyllys.Ingersoll@Sun.COM 
2336*12720SWyllys.Ingersoll@Sun.COM     // SOAP - discover cluster
2337*12720SWyllys.Ingersoll@Sun.COM    if ( bSuccess )
2338*12720SWyllys.Ingersoll@Sun.COM    {
2339*12720SWyllys.Ingersoll@Sun.COM #ifdef DEBUG
2340*12720SWyllys.Ingersoll@Sun.COM       int iStartTickCount = K_GetTickCount();
2341*12720SWyllys.Ingersoll@Sun.COM       int iEndTickCount;
2342*12720SWyllys.Ingersoll@Sun.COM       char sDiscoverTimeMsg[100];
2343*12720SWyllys.Ingersoll@Sun.COM #endif
2344*12720SWyllys.Ingersoll@Sun.COM       bSuccess =
2345*12720SWyllys.Ingersoll@Sun.COM          KMS_Discovery::soap_call_KMS_Discovery__DiscoverCluster(
2346*12720SWyllys.Ingersoll@Sun.COM             pstSoap,
2347*12720SWyllys.Ingersoll@Sun.COM             sURL,
2348*12720SWyllys.Ingersoll@Sun.COM             NULL,
2349*12720SWyllys.Ingersoll@Sun.COM             NULL,
2350*12720SWyllys.Ingersoll@Sun.COM             stResponse ) == SOAP_OK;
2351*12720SWyllys.Ingersoll@Sun.COM #ifdef DEBUG
2352*12720SWyllys.Ingersoll@Sun.COM       iEndTickCount = K_GetTickCount();
2353*12720SWyllys.Ingersoll@Sun.COM       sprintf(sDiscoverTimeMsg, "DiscoverCluster soapcall elapsed time=%u ms",
2354*12720SWyllys.Ingersoll@Sun.COM               iEndTickCount-iStartTickCount);
2355*12720SWyllys.Ingersoll@Sun.COM       Log(AUDIT_CLIENT_GetClusterInformation,
2356*12720SWyllys.Ingersoll@Sun.COM            NULL,
2357*12720SWyllys.Ingersoll@Sun.COM            sApplianceAddress,
2358*12720SWyllys.Ingersoll@Sun.COM            sDiscoverTimeMsg);
2359*12720SWyllys.Ingersoll@Sun.COM #endif
2360*12720SWyllys.Ingersoll@Sun.COM 
2361*12720SWyllys.Ingersoll@Sun.COM       if ( !bSuccess )
2362*12720SWyllys.Ingersoll@Sun.COM       {
2363*12720SWyllys.Ingersoll@Sun.COM          GetSoapFault(sSoapFaultMsg, (struct soap*)pstSoap);
2364*12720SWyllys.Ingersoll@Sun.COM          GetPeerNetworkAddress(sKmaAddress, pstSoap);
2365*12720SWyllys.Ingersoll@Sun.COM          LogError(i_pProfile,AUDIT_CLIENT_GET_CLUSTER_INFORMATION_SOAP_ERROR,
2366*12720SWyllys.Ingersoll@Sun.COM                   NULL,
2367*12720SWyllys.Ingersoll@Sun.COM                   sKmaAddress,
2368*12720SWyllys.Ingersoll@Sun.COM                   sSoapFaultMsg );
2369*12720SWyllys.Ingersoll@Sun.COM 
2370*12720SWyllys.Ingersoll@Sun.COM          if ( !ServerError( sSoapFaultMsg, pstSoap->errnum ) )
2371*12720SWyllys.Ingersoll@Sun.COM          {
2372*12720SWyllys.Ingersoll@Sun.COM                 // do not failover if error is client related
2373*12720SWyllys.Ingersoll@Sun.COM                 soap_destroy( pstSoap );
2374*12720SWyllys.Ingersoll@Sun.COM                 soap_end( pstSoap );
2375*12720SWyllys.Ingersoll@Sun.COM                 soap_free( pstSoap );
2376*12720SWyllys.Ingersoll@Sun.COM                 return false;
2377*12720SWyllys.Ingersoll@Sun.COM          }
2378*12720SWyllys.Ingersoll@Sun.COM       }
2379*12720SWyllys.Ingersoll@Sun.COM 
2380*12720SWyllys.Ingersoll@Sun.COM       // If we did not succeed to Discover from the initial appliance,
2381*12720SWyllys.Ingersoll@Sun.COM       // try to discover from other appliances that we know about that are enabled.
2382*12720SWyllys.Ingersoll@Sun.COM       // Disabled Appliances are not attempted because they may have a stale view
2383*12720SWyllys.Ingersoll@Sun.COM       // of the cluster. In particular, they themselves are not aware that they
2384*12720SWyllys.Ingersoll@Sun.COM       // are disabled.
2385*12720SWyllys.Ingersoll@Sun.COM 
2386*12720SWyllys.Ingersoll@Sun.COM       if ( !bSuccess && i_pProfile->m_iClusterNum > 0 )
2387*12720SWyllys.Ingersoll@Sun.COM       {
2388*12720SWyllys.Ingersoll@Sun.COM          // Copy the profile's cluster array so that we don't have to lock the
2389*12720SWyllys.Ingersoll@Sun.COM          // profile around a SOAP call
2390*12720SWyllys.Ingersoll@Sun.COM 
2391*12720SWyllys.Ingersoll@Sun.COM          int j = 0;
2392*12720SWyllys.Ingersoll@Sun.COM          int iClusterNum = 0;
2393*12720SWyllys.Ingersoll@Sun.COM          KMSClusterEntry* aCluster =
2394*12720SWyllys.Ingersoll@Sun.COM             (KMSClusterEntry*)malloc(sizeof(KMSClusterEntry) * KMS_MAX_CLUSTER_NUM);
2395*12720SWyllys.Ingersoll@Sun.COM 
2396*12720SWyllys.Ingersoll@Sun.COM          bSuccess = ( aCluster != 0 );
2397*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
2398*12720SWyllys.Ingersoll@Sun.COM         if (!bSuccess)
2399*12720SWyllys.Ingersoll@Sun.COM            log_printf("Malloc %x aCluster returned null\n",
2400*12720SWyllys.Ingersoll@Sun.COM                       sizeof(KMSClusterEntry) * KMS_MAX_CLUSTER_NUM);
2401*12720SWyllys.Ingersoll@Sun.COM #endif
2402*12720SWyllys.Ingersoll@Sun.COM 
2403*12720SWyllys.Ingersoll@Sun.COM          if ( bSuccess )
2404*12720SWyllys.Ingersoll@Sun.COM          {
2405*12720SWyllys.Ingersoll@Sun.COM             iClusterNum = i_pProfile->m_iClusterNum;
2406*12720SWyllys.Ingersoll@Sun.COM             memcpy( aCluster, i_pProfile->m_aCluster,
2407*12720SWyllys.Ingersoll@Sun.COM                     sizeof(KMSClusterEntry) * iClusterNum );
2408*12720SWyllys.Ingersoll@Sun.COM 
2409*12720SWyllys.Ingersoll@Sun.COM             // initialize to false since all KMAs could be disabled
2410*12720SWyllys.Ingersoll@Sun.COM             bSuccess = false;
2411*12720SWyllys.Ingersoll@Sun.COM             for ( j = 0; j < iClusterNum; j++ )
2412*12720SWyllys.Ingersoll@Sun.COM             {
2413*12720SWyllys.Ingersoll@Sun.COM                if ( aCluster[j].m_iEnabled == FALSE )
2414*12720SWyllys.Ingersoll@Sun.COM                {
2415*12720SWyllys.Ingersoll@Sun.COM                   continue;
2416*12720SWyllys.Ingersoll@Sun.COM                }
2417*12720SWyllys.Ingersoll@Sun.COM 
2418*12720SWyllys.Ingersoll@Sun.COM                sApplianceAddress = aCluster[j].m_wsApplianceNetworkAddress;
2419*12720SWyllys.Ingersoll@Sun.COM                K_snprintf(sURL,
2420*12720SWyllys.Ingersoll@Sun.COM                        KMS_MAX_URL,
2421*12720SWyllys.Ingersoll@Sun.COM                        "https://%s:%d",
2422*12720SWyllys.Ingersoll@Sun.COM                        sApplianceAddress,
2423*12720SWyllys.Ingersoll@Sun.COM                        i_pProfile->m_iPortForDiscoveryService);
2424*12720SWyllys.Ingersoll@Sun.COM 
2425*12720SWyllys.Ingersoll@Sun.COM                Log(AUDIT_CLIENT_GetClusterInformation,
2426*12720SWyllys.Ingersoll@Sun.COM                    NULL,
2427*12720SWyllys.Ingersoll@Sun.COM                    sApplianceAddress,
2428*12720SWyllys.Ingersoll@Sun.COM                    "Failing over and trying this appliance");
2429*12720SWyllys.Ingersoll@Sun.COM 
2430*12720SWyllys.Ingersoll@Sun.COM                // SOAP - discover cluster
2431*12720SWyllys.Ingersoll@Sun.COM                bSuccess =
2432*12720SWyllys.Ingersoll@Sun.COM                   KMS_Discovery::soap_call_KMS_Discovery__DiscoverCluster(
2433*12720SWyllys.Ingersoll@Sun.COM                      pstSoap,
2434*12720SWyllys.Ingersoll@Sun.COM                      sURL,
2435*12720SWyllys.Ingersoll@Sun.COM                      NULL,
2436*12720SWyllys.Ingersoll@Sun.COM                      NULL,
2437*12720SWyllys.Ingersoll@Sun.COM                      stResponse ) == SOAP_OK;
2438*12720SWyllys.Ingersoll@Sun.COM 
2439*12720SWyllys.Ingersoll@Sun.COM                if ( !bSuccess )
2440*12720SWyllys.Ingersoll@Sun.COM                {
2441*12720SWyllys.Ingersoll@Sun.COM                   GetSoapFault(sSoapFaultMsg, (struct soap*)pstSoap);
2442*12720SWyllys.Ingersoll@Sun.COM                   GetPeerNetworkAddress(sKmaAddress, pstSoap);
2443*12720SWyllys.Ingersoll@Sun.COM                   LogError(i_pProfile,AUDIT_CLIENT_GET_CLUSTER_INFORMATION_SOAP_ERROR,
2444*12720SWyllys.Ingersoll@Sun.COM                            NULL,
2445*12720SWyllys.Ingersoll@Sun.COM                            sKmaAddress,
2446*12720SWyllys.Ingersoll@Sun.COM                            sSoapFaultMsg );
2447*12720SWyllys.Ingersoll@Sun.COM                }
2448*12720SWyllys.Ingersoll@Sun.COM                else
2449*12720SWyllys.Ingersoll@Sun.COM                {
2450*12720SWyllys.Ingersoll@Sun.COM                   // The discover succeeded
2451*12720SWyllys.Ingersoll@Sun.COM                   break;
2452*12720SWyllys.Ingersoll@Sun.COM                }
2453*12720SWyllys.Ingersoll@Sun.COM             }
2454*12720SWyllys.Ingersoll@Sun.COM          }
2455*12720SWyllys.Ingersoll@Sun.COM 
2456*12720SWyllys.Ingersoll@Sun.COM          if ( aCluster != 0 )
2457*12720SWyllys.Ingersoll@Sun.COM          {
2458*12720SWyllys.Ingersoll@Sun.COM             free(aCluster);
2459*12720SWyllys.Ingersoll@Sun.COM          }
2460*12720SWyllys.Ingersoll@Sun.COM 
2461*12720SWyllys.Ingersoll@Sun.COM          if ( bSuccess )
2462*12720SWyllys.Ingersoll@Sun.COM          {
2463*12720SWyllys.Ingersoll@Sun.COM             // Set the Profile's initial appliance to the Appliance
2464*12720SWyllys.Ingersoll@Sun.COM             // that we just succeeded to Discover from. KMSClient_SelectAppliance()
2465*12720SWyllys.Ingersoll@Sun.COM             // persists the updated config
2466*12720SWyllys.Ingersoll@Sun.COM             KMSClient_SelectAppliance( i_pProfile,
2467*12720SWyllys.Ingersoll@Sun.COM                                        i_pProfile->m_aCluster[j].m_wsApplianceNetworkAddress );
2468*12720SWyllys.Ingersoll@Sun.COM          }
2469*12720SWyllys.Ingersoll@Sun.COM       }
2470*12720SWyllys.Ingersoll@Sun.COM    }
2471*12720SWyllys.Ingersoll@Sun.COM 
2472*12720SWyllys.Ingersoll@Sun.COM    if ( bSuccess )
2473*12720SWyllys.Ingersoll@Sun.COM    {
2474*12720SWyllys.Ingersoll@Sun.COM       if (((int)strlen(stResponse.EntitySiteID) > i_iEntitySiteIDSize - 1))
2475*12720SWyllys.Ingersoll@Sun.COM       {
2476*12720SWyllys.Ingersoll@Sun.COM          bSuccess = false;
2477*12720SWyllys.Ingersoll@Sun.COM          LogError(i_pProfile,AUDIT_CLIENT_GET_CLUSTER_INFORMATION,
2478*12720SWyllys.Ingersoll@Sun.COM                   NULL,
2479*12720SWyllys.Ingersoll@Sun.COM                   NULL,
2480*12720SWyllys.Ingersoll@Sun.COM                   "returned site id size too large" );
2481*12720SWyllys.Ingersoll@Sun.COM       }
2482*12720SWyllys.Ingersoll@Sun.COM    }
2483*12720SWyllys.Ingersoll@Sun.COM 
2484*12720SWyllys.Ingersoll@Sun.COM    // copy returned cluster information into i_pProfile->m_aCluster after
2485*12720SWyllys.Ingersoll@Sun.COM    // filtering the cluster members to a list with size <= KMS_MAX_CLUSTER_NUM
2486*12720SWyllys.Ingersoll@Sun.COM    if ( bSuccess )
2487*12720SWyllys.Ingersoll@Sun.COM    {
2488*12720SWyllys.Ingersoll@Sun.COM       KMS_Discovery::KMS_Discovery__ArrayOfClusterMembers aFilteredCluster;
2489*12720SWyllys.Ingersoll@Sun.COM 
2490*12720SWyllys.Ingersoll@Sun.COM       bSuccess = FilterCluster(&stResponse, i_pProfile->m_eKMSmode == FIPS_MODE, &aFilteredCluster);
2491*12720SWyllys.Ingersoll@Sun.COM       if (!bSuccess )
2492*12720SWyllys.Ingersoll@Sun.COM       {
2493*12720SWyllys.Ingersoll@Sun.COM           LogError(i_pProfile, AUDIT_CLIENT_GET_CLUSTER_INFORMATION,
2494*12720SWyllys.Ingersoll@Sun.COM                   NULL,
2495*12720SWyllys.Ingersoll@Sun.COM                   NULL,
2496*12720SWyllys.Ingersoll@Sun.COM                   "cluster response filtering failed" );
2497*12720SWyllys.Ingersoll@Sun.COM       }
2498*12720SWyllys.Ingersoll@Sun.COM 
2499*12720SWyllys.Ingersoll@Sun.COM       if(bSuccess)
2500*12720SWyllys.Ingersoll@Sun.COM       {
2501*12720SWyllys.Ingersoll@Sun.COM          int i;
2502*12720SWyllys.Ingersoll@Sun.COM          bool bPersistClusterConfig = ClusterConfigChanged(i_pProfile,
2503*12720SWyllys.Ingersoll@Sun.COM                     stResponse.EntitySiteID,
2504*12720SWyllys.Ingersoll@Sun.COM                     &aFilteredCluster);
2505*12720SWyllys.Ingersoll@Sun.COM 
2506*12720SWyllys.Ingersoll@Sun.COM          strncpy(o_wsEntitySiteID,stResponse.EntitySiteID, i_iEntitySiteIDSize-1 );
2507*12720SWyllys.Ingersoll@Sun.COM          o_wsEntitySiteID[i_iEntitySiteIDSize-1] = '\0';
2508*12720SWyllys.Ingersoll@Sun.COM 
2509*12720SWyllys.Ingersoll@Sun.COM          strncpy(i_pProfile->m_wsEntitySiteID, stResponse.EntitySiteID, i_iEntitySiteIDSize-1 );
2510*12720SWyllys.Ingersoll@Sun.COM          i_pProfile->m_wsEntitySiteID[i_iEntitySiteIDSize-1] = '\0';
2511*12720SWyllys.Ingersoll@Sun.COM 
2512*12720SWyllys.Ingersoll@Sun.COM          // fill the aCluster array in the i_pProfile
2513*12720SWyllys.Ingersoll@Sun.COM          i_pProfile->m_iClusterNum = aFilteredCluster.__size;
2514*12720SWyllys.Ingersoll@Sun.COM          for (i = 0;  i < i_pProfile->m_iClusterNum; i++)
2515*12720SWyllys.Ingersoll@Sun.COM          {
2516*12720SWyllys.Ingersoll@Sun.COM             i_pProfile->m_aCluster[i].m_lApplianceID =
2517*12720SWyllys.Ingersoll@Sun.COM                (aFilteredCluster.__ptr+i)->KMAID;
2518*12720SWyllys.Ingersoll@Sun.COM             i_pProfile->m_aCluster[i].m_iEnabled =
2519*12720SWyllys.Ingersoll@Sun.COM                (aFilteredCluster.__ptr+i)->Enabled;
2520*12720SWyllys.Ingersoll@Sun.COM             i_pProfile->m_aCluster[i].m_iResponding =
2521*12720SWyllys.Ingersoll@Sun.COM                (aFilteredCluster.__ptr+i)->Responding;
2522*12720SWyllys.Ingersoll@Sun.COM 
2523*12720SWyllys.Ingersoll@Sun.COM             i_pProfile->m_aCluster[i].m_lLoad = (aFilteredCluster.__ptr+i)->Load;
2524*12720SWyllys.Ingersoll@Sun.COM             strncpy(i_pProfile->m_aCluster[i].m_wsApplianceAlias,
2525*12720SWyllys.Ingersoll@Sun.COM                    (aFilteredCluster.__ptr+i)->KMAName,
2526*12720SWyllys.Ingersoll@Sun.COM                    KMS_MAX_ENTITY_ID);
2527*12720SWyllys.Ingersoll@Sun.COM             i_pProfile->m_aCluster[i].m_wsApplianceAlias[KMS_MAX_ENTITY_ID] = '\0';
2528*12720SWyllys.Ingersoll@Sun.COM             // if the m_wsApplianceAddress is IPv6 then we'll store
2529*12720SWyllys.Ingersoll@Sun.COM             // KMA IPv6 addresses if they have one
2530*12720SWyllys.Ingersoll@Sun.COM             if ( strchr( i_pProfile->m_wsApplianceAddress, ':') )
2531*12720SWyllys.Ingersoll@Sun.COM             {
2532*12720SWyllys.Ingersoll@Sun.COM                 // KMAs prior to 2.1, or 2.1 KMAs at rep schema < 10
2533*12720SWyllys.Ingersoll@Sun.COM                 // will not have IPv6 attributes in the soap response
2534*12720SWyllys.Ingersoll@Sun.COM                 if ( (aFilteredCluster.__ptr+i)->KMANetworkAddressIPv6 &&
2535*12720SWyllys.Ingersoll@Sun.COM                       ValidIPv6KMAaddress((aFilteredCluster.__ptr+i)->KMANetworkAddressIPv6))
2536*12720SWyllys.Ingersoll@Sun.COM                 {
2537*12720SWyllys.Ingersoll@Sun.COM                     strcpy(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress, "[");
2538*12720SWyllys.Ingersoll@Sun.COM                     char * pLoc = strchr((aFilteredCluster.__ptr+i)->KMANetworkAddressIPv6,
2539*12720SWyllys.Ingersoll@Sun.COM                             '/');
2540*12720SWyllys.Ingersoll@Sun.COM                     if ( pLoc != NULL )
2541*12720SWyllys.Ingersoll@Sun.COM                     {
2542*12720SWyllys.Ingersoll@Sun.COM                         // remove prefix from address
2543*12720SWyllys.Ingersoll@Sun.COM                         *pLoc = '\0';
2544*12720SWyllys.Ingersoll@Sun.COM                         strcat(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
2545*12720SWyllys.Ingersoll@Sun.COM                                (aFilteredCluster.__ptr+i)->KMANetworkAddressIPv6 );
2546*12720SWyllys.Ingersoll@Sun.COM                     }
2547*12720SWyllys.Ingersoll@Sun.COM                     else
2548*12720SWyllys.Ingersoll@Sun.COM                     {
2549*12720SWyllys.Ingersoll@Sun.COM                         strcat(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
2550*12720SWyllys.Ingersoll@Sun.COM                                 (aFilteredCluster.__ptr + i)->KMANetworkAddressIPv6);
2551*12720SWyllys.Ingersoll@Sun.COM                     }
2552*12720SWyllys.Ingersoll@Sun.COM                     strcat(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress, "]");
2553*12720SWyllys.Ingersoll@Sun.COM                 }
2554*12720SWyllys.Ingersoll@Sun.COM                 else
2555*12720SWyllys.Ingersoll@Sun.COM                 {
2556*12720SWyllys.Ingersoll@Sun.COM                     // use the IPv4 address
2557*12720SWyllys.Ingersoll@Sun.COM                     strncpy(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
2558*12720SWyllys.Ingersoll@Sun.COM                            (aFilteredCluster.__ptr+i)->KMANetworkAddress,
2559*12720SWyllys.Ingersoll@Sun.COM                            KMS_MAX_NETWORK_ADDRESS);
2560*12720SWyllys.Ingersoll@Sun.COM                 }
2561*12720SWyllys.Ingersoll@Sun.COM             }
2562*12720SWyllys.Ingersoll@Sun.COM             else
2563*12720SWyllys.Ingersoll@Sun.COM             {
2564*12720SWyllys.Ingersoll@Sun.COM                 strncpy(i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
2565*12720SWyllys.Ingersoll@Sun.COM                        (aFilteredCluster.__ptr+i)->KMANetworkAddress,
2566*12720SWyllys.Ingersoll@Sun.COM                        KMS_MAX_NETWORK_ADDRESS);
2567*12720SWyllys.Ingersoll@Sun.COM             }
2568*12720SWyllys.Ingersoll@Sun.COM             i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress[KMS_MAX_NETWORK_ADDRESS] = '\0';
2569*12720SWyllys.Ingersoll@Sun.COM             strncpy(i_pProfile->m_aCluster[i].m_wsApplianceSiteID,
2570*12720SWyllys.Ingersoll@Sun.COM                    (aFilteredCluster.__ptr+i)->KMASiteID,
2571*12720SWyllys.Ingersoll@Sun.COM                    KMS_MAX_ENTITY_SITE_ID);
2572*12720SWyllys.Ingersoll@Sun.COM             i_pProfile->m_aCluster[i].m_wsApplianceSiteID[KMS_MAX_ENTITY_SITE_ID] = '\0';
2573*12720SWyllys.Ingersoll@Sun.COM 
2574*12720SWyllys.Ingersoll@Sun.COM             if ((aFilteredCluster.__ptr + i)->KMAVersion)
2575*12720SWyllys.Ingersoll@Sun.COM             {
2576*12720SWyllys.Ingersoll@Sun.COM                 strncpy(i_pProfile->m_aCluster[i].m_sKMAVersion,
2577*12720SWyllys.Ingersoll@Sun.COM                         (aFilteredCluster.__ptr + i)->KMAVersion,
2578*12720SWyllys.Ingersoll@Sun.COM                         KMS_MAX_VERSION_LENGTH);
2579*12720SWyllys.Ingersoll@Sun.COM                 i_pProfile->m_aCluster[i].m_sKMAVersion[KMS_MAX_VERSION_LENGTH] = '\0';
2580*12720SWyllys.Ingersoll@Sun.COM             }
2581*12720SWyllys.Ingersoll@Sun.COM             else
2582*12720SWyllys.Ingersoll@Sun.COM             {
2583*12720SWyllys.Ingersoll@Sun.COM                 i_pProfile->m_aCluster[i].m_sKMAVersion[0] = '\0';
2584*12720SWyllys.Ingersoll@Sun.COM             }
2585*12720SWyllys.Ingersoll@Sun.COM 
2586*12720SWyllys.Ingersoll@Sun.COM             if ((aFilteredCluster.__ptr + i)->KMS_Discovery__Locked)
2587*12720SWyllys.Ingersoll@Sun.COM             {
2588*12720SWyllys.Ingersoll@Sun.COM                 i_pProfile->m_aCluster[i].m_iKMALocked = TRUE;
2589*12720SWyllys.Ingersoll@Sun.COM             }
2590*12720SWyllys.Ingersoll@Sun.COM             else
2591*12720SWyllys.Ingersoll@Sun.COM             {
2592*12720SWyllys.Ingersoll@Sun.COM                 i_pProfile->m_aCluster[i].m_iKMALocked = FALSE;
2593*12720SWyllys.Ingersoll@Sun.COM             }
2594*12720SWyllys.Ingersoll@Sun.COM          }
2595*12720SWyllys.Ingersoll@Sun.COM 
2596*12720SWyllys.Ingersoll@Sun.COM          // now release malloc'd storage from filtering the cluster response
2597*12720SWyllys.Ingersoll@Sun.COM          FreeFilteredCluster( &aFilteredCluster, aFilteredCluster.__size );
2598*12720SWyllys.Ingersoll@Sun.COM 
2599*12720SWyllys.Ingersoll@Sun.COM          // fill the array specified by the caller
2600*12720SWyllys.Ingersoll@Sun.COM          *o_pApplianceNum = i_pProfile->m_iClusterNum;
2601*12720SWyllys.Ingersoll@Sun.COM          for (i = 0;  i < i_pProfile->m_iClusterNum; i++)
2602*12720SWyllys.Ingersoll@Sun.COM          {
2603*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_lApplianceID = i_pProfile->m_aCluster[i].m_lApplianceID;
2604*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_iEnabled = i_pProfile->m_aCluster[i].m_iEnabled;
2605*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_iResponding = i_pProfile->m_aCluster[i].m_iResponding;
2606*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_lLoad = i_pProfile->m_aCluster[i].m_lLoad;
2607*12720SWyllys.Ingersoll@Sun.COM             strncpy(o_pClusterEntryArray[i].m_wsApplianceAlias,
2608*12720SWyllys.Ingersoll@Sun.COM                    i_pProfile->m_aCluster[i].m_wsApplianceAlias,
2609*12720SWyllys.Ingersoll@Sun.COM                    KMS_MAX_ENTITY_ID);
2610*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_wsApplianceAlias[KMS_MAX_ENTITY_ID] = '\0';
2611*12720SWyllys.Ingersoll@Sun.COM             strncpy(o_pClusterEntryArray[i].m_wsApplianceNetworkAddress,
2612*12720SWyllys.Ingersoll@Sun.COM                    i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
2613*12720SWyllys.Ingersoll@Sun.COM                    KMS_MAX_NETWORK_ADDRESS);
2614*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_wsApplianceNetworkAddress[KMS_MAX_NETWORK_ADDRESS] = '\0';
2615*12720SWyllys.Ingersoll@Sun.COM             strncpy(o_pClusterEntryArray[i].m_wsApplianceSiteID,
2616*12720SWyllys.Ingersoll@Sun.COM                    i_pProfile->m_aCluster[i].m_wsApplianceSiteID,
2617*12720SWyllys.Ingersoll@Sun.COM                    KMS_MAX_ENTITY_SITE_ID);
2618*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_wsApplianceSiteID[KMS_MAX_ENTITY_SITE_ID] = '\0';
2619*12720SWyllys.Ingersoll@Sun.COM             strncpy(o_pClusterEntryArray[i].m_sKMAVersion, i_pProfile->m_aCluster[i].m_sKMAVersion,
2620*12720SWyllys.Ingersoll@Sun.COM                     KMS_MAX_VERSION_LENGTH);
2621*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_sKMAVersion[KMS_MAX_VERSION_LENGTH] = '\0';
2622*12720SWyllys.Ingersoll@Sun.COM          }
2623*12720SWyllys.Ingersoll@Sun.COM 
2624*12720SWyllys.Ingersoll@Sun.COM          i_pProfile->m_iLastClusterDiscoveryTime = K_GetTickCount() / 1000;
2625*12720SWyllys.Ingersoll@Sun.COM          i_pProfile->m_bIsClusterDiscoveryCalled = true;
2626*12720SWyllys.Ingersoll@Sun.COM 
2627*12720SWyllys.Ingersoll@Sun.COM          if ( bPersistClusterConfig )
2628*12720SWyllys.Ingersoll@Sun.COM          {
2629*12720SWyllys.Ingersoll@Sun.COM              bSuccess = StoreCluster(i_pProfile);
2630*12720SWyllys.Ingersoll@Sun.COM              if (!bSuccess)
2631*12720SWyllys.Ingersoll@Sun.COM              {
2632*12720SWyllys.Ingersoll@Sun.COM                  Log(AUDIT_CLIENT_GetClusterInformation,
2633*12720SWyllys.Ingersoll@Sun.COM                      NULL,
2634*12720SWyllys.Ingersoll@Sun.COM                      NULL,
2635*12720SWyllys.Ingersoll@Sun.COM                      "Could not store cluster");
2636*12720SWyllys.Ingersoll@Sun.COM              }
2637*12720SWyllys.Ingersoll@Sun.COM          }
2638*12720SWyllys.Ingersoll@Sun.COM       }
2639*12720SWyllys.Ingersoll@Sun.COM    }
2640*12720SWyllys.Ingersoll@Sun.COM 
2641*12720SWyllys.Ingersoll@Sun.COM    // cleanup
2642*12720SWyllys.Ingersoll@Sun.COM    if (pstSoap)
2643*12720SWyllys.Ingersoll@Sun.COM    {
2644*12720SWyllys.Ingersoll@Sun.COM       soap_destroy(pstSoap);
2645*12720SWyllys.Ingersoll@Sun.COM       soap_end(pstSoap);
2646*12720SWyllys.Ingersoll@Sun.COM       if (!bSuccess)
2647*12720SWyllys.Ingersoll@Sun.COM       {
2648*12720SWyllys.Ingersoll@Sun.COM           soap_free(pstSoap);
2649*12720SWyllys.Ingersoll@Sun.COM       }
2650*12720SWyllys.Ingersoll@Sun.COM       else
2651*12720SWyllys.Ingersoll@Sun.COM       {
2652*12720SWyllys.Ingersoll@Sun.COM         // we want to persist discovery soap runtime to avoid ssl handshakes so soap_free() is not called
2653*12720SWyllys.Ingersoll@Sun.COM       }
2654*12720SWyllys.Ingersoll@Sun.COM    }
2655*12720SWyllys.Ingersoll@Sun.COM 
2656*12720SWyllys.Ingersoll@Sun.COM    // if we're enrolled but cannot get cluster information from an appliance, then we'll try to load
2657*12720SWyllys.Ingersoll@Sun.COM    // it from the profile
2658*12720SWyllys.Ingersoll@Sun.COM    if ( !bSuccess && i_pProfile->m_iEnrolled )
2659*12720SWyllys.Ingersoll@Sun.COM    {
2660*12720SWyllys.Ingersoll@Sun.COM       int bClusterInformationFound = false;
2661*12720SWyllys.Ingersoll@Sun.COM 
2662*12720SWyllys.Ingersoll@Sun.COM       bSuccess = LoadClusterInformation( i_pProfile, bClusterInformationFound );
2663*12720SWyllys.Ingersoll@Sun.COM 
2664*12720SWyllys.Ingersoll@Sun.COM       if ( bSuccess && bClusterInformationFound )
2665*12720SWyllys.Ingersoll@Sun.COM       {
2666*12720SWyllys.Ingersoll@Sun.COM          Log(AUDIT_CLIENT_GetClusterInformation,
2667*12720SWyllys.Ingersoll@Sun.COM                  NULL,
2668*12720SWyllys.Ingersoll@Sun.COM                  NULL,
2669*12720SWyllys.Ingersoll@Sun.COM                  "Using persisted cluster information");
2670*12720SWyllys.Ingersoll@Sun.COM 
2671*12720SWyllys.Ingersoll@Sun.COM          strncpy(o_wsEntitySiteID, i_pProfile->m_wsEntitySiteID, i_iEntitySiteIDSize-1);
2672*12720SWyllys.Ingersoll@Sun.COM          o_wsEntitySiteID[i_iEntitySiteIDSize-1] = '\0';
2673*12720SWyllys.Ingersoll@Sun.COM 
2674*12720SWyllys.Ingersoll@Sun.COM          // fill the array specified by the caller
2675*12720SWyllys.Ingersoll@Sun.COM          *o_pApplianceNum = i_pProfile->m_iClusterNum;
2676*12720SWyllys.Ingersoll@Sun.COM          for (int i = 0;  i < i_pProfile->m_iClusterNum; i++)
2677*12720SWyllys.Ingersoll@Sun.COM          {
2678*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_lApplianceID = i_pProfile->m_aCluster[i].m_lApplianceID;
2679*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_iEnabled = i_pProfile->m_aCluster[i].m_iEnabled;
2680*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_iResponding = TRUE; // since cluster info comes from a file, set it to TRUE
2681*12720SWyllys.Ingersoll@Sun.COM 
2682*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_lLoad = i_pProfile->m_aCluster[i].m_lLoad;
2683*12720SWyllys.Ingersoll@Sun.COM             strncpy(o_pClusterEntryArray[i].m_wsApplianceAlias,
2684*12720SWyllys.Ingersoll@Sun.COM                    i_pProfile->m_aCluster[i].m_wsApplianceAlias,
2685*12720SWyllys.Ingersoll@Sun.COM                    KMS_MAX_ENTITY_ID);
2686*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_wsApplianceAlias[KMS_MAX_ENTITY_ID] = '\0';
2687*12720SWyllys.Ingersoll@Sun.COM             strncpy(o_pClusterEntryArray[i].m_wsApplianceNetworkAddress,
2688*12720SWyllys.Ingersoll@Sun.COM                    i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress,
2689*12720SWyllys.Ingersoll@Sun.COM                    KMS_MAX_NETWORK_ADDRESS);
2690*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_wsApplianceNetworkAddress[KMS_MAX_NETWORK_ADDRESS] = '\0';
2691*12720SWyllys.Ingersoll@Sun.COM             strncpy(o_pClusterEntryArray[i].m_wsApplianceSiteID,
2692*12720SWyllys.Ingersoll@Sun.COM                    i_pProfile->m_aCluster[i].m_wsApplianceSiteID,
2693*12720SWyllys.Ingersoll@Sun.COM                    KMS_MAX_ENTITY_SITE_ID);
2694*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_wsApplianceSiteID[KMS_MAX_ENTITY_SITE_ID] = '\0';
2695*12720SWyllys.Ingersoll@Sun.COM             strncpy(o_pClusterEntryArray[i].m_sKMAVersion,
2696*12720SWyllys.Ingersoll@Sun.COM                     i_pProfile->m_aCluster[i].m_sKMAVersion,
2697*12720SWyllys.Ingersoll@Sun.COM                     KMS_MAX_VERSION_LENGTH);
2698*12720SWyllys.Ingersoll@Sun.COM             o_pClusterEntryArray[i].m_sKMAVersion[KMS_MAX_VERSION_LENGTH] = '\0';
2699*12720SWyllys.Ingersoll@Sun.COM          }
2700*12720SWyllys.Ingersoll@Sun.COM 
2701*12720SWyllys.Ingersoll@Sun.COM          i_pProfile->m_iLastClusterDiscoveryTime = K_GetTickCount() / 1000;
2702*12720SWyllys.Ingersoll@Sun.COM       }
2703*12720SWyllys.Ingersoll@Sun.COM       else if ( bSuccess && !bClusterInformationFound )
2704*12720SWyllys.Ingersoll@Sun.COM       {
2705*12720SWyllys.Ingersoll@Sun.COM          // if we're here, then we need to return an error
2706*12720SWyllys.Ingersoll@Sun.COM          bSuccess = false;
2707*12720SWyllys.Ingersoll@Sun.COM       }
2708*12720SWyllys.Ingersoll@Sun.COM    }
2709*12720SWyllys.Ingersoll@Sun.COM 
2710*12720SWyllys.Ingersoll@Sun.COM    return bSuccess;
2711*12720SWyllys.Ingersoll@Sun.COM }
2712*12720SWyllys.Ingersoll@Sun.COM 
KMSClient_NoFIPSCompatibleKMAs(const KMSClientProfile * const i_pProfile)2713*12720SWyllys.Ingersoll@Sun.COM bool KMSClient_NoFIPSCompatibleKMAs(const KMSClientProfile * const i_pProfile)
2714*12720SWyllys.Ingersoll@Sun.COM {
2715*12720SWyllys.Ingersoll@Sun.COM     bool bNoFIPScompatibleKMA = true;
2716*12720SWyllys.Ingersoll@Sun.COM     for (int i=0; i < i_pProfile->m_iClusterNum; i++)
2717*12720SWyllys.Ingersoll@Sun.COM     {
2718*12720SWyllys.Ingersoll@Sun.COM         if ( FIPScompatibleKMA(i_pProfile->m_aCluster[i].m_sKMAVersion))
2719*12720SWyllys.Ingersoll@Sun.COM         {
2720*12720SWyllys.Ingersoll@Sun.COM             bNoFIPScompatibleKMA = false;
2721*12720SWyllys.Ingersoll@Sun.COM             break;
2722*12720SWyllys.Ingersoll@Sun.COM         }
2723*12720SWyllys.Ingersoll@Sun.COM     }
2724*12720SWyllys.Ingersoll@Sun.COM     return bNoFIPScompatibleKMA;
2725*12720SWyllys.Ingersoll@Sun.COM }
2726*12720SWyllys.Ingersoll@Sun.COM 
2727*12720SWyllys.Ingersoll@Sun.COM /*---------------------------------------------------------------------------
2728*12720SWyllys.Ingersoll@Sun.COM  * Function: KMSClient_SelectAppliance
2729*12720SWyllys.Ingersoll@Sun.COM  *
2730*12720SWyllys.Ingersoll@Sun.COM  *--------------------------------------------------------------------------*/
KMSClient_SelectAppliance(KMSClientProfile * i_pProfile,utf8char * i_wsApplianceAddress)2731*12720SWyllys.Ingersoll@Sun.COM bool KMSClient_SelectAppliance(KMSClientProfile *i_pProfile,
2732*12720SWyllys.Ingersoll@Sun.COM                                 utf8char *i_wsApplianceAddress)
2733*12720SWyllys.Ingersoll@Sun.COM {
2734*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT(i_pProfile);
2735*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT(i_wsApplianceAddress);
2736*12720SWyllys.Ingersoll@Sun.COM 
2737*12720SWyllys.Ingersoll@Sun.COM     CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
2738*12720SWyllys.Ingersoll@Sun.COM 
2739*12720SWyllys.Ingersoll@Sun.COM     bool bSuccess = true;
2740*12720SWyllys.Ingersoll@Sun.COM 
2741*12720SWyllys.Ingersoll@Sun.COM     if(strlen(i_wsApplianceAddress) >= KMS_MAX_NETWORK_ADDRESS)
2742*12720SWyllys.Ingersoll@Sun.COM     {
2743*12720SWyllys.Ingersoll@Sun.COM         LogError(i_pProfile,AUDIT_CLIENT_SELECT_APPLIANCE,
2744*12720SWyllys.Ingersoll@Sun.COM             NULL,
2745*12720SWyllys.Ingersoll@Sun.COM             NULL,
2746*12720SWyllys.Ingersoll@Sun.COM             "Appliance Address too large" );
2747*12720SWyllys.Ingersoll@Sun.COM         bSuccess = false;
2748*12720SWyllys.Ingersoll@Sun.COM     }
2749*12720SWyllys.Ingersoll@Sun.COM 
2750*12720SWyllys.Ingersoll@Sun.COM     if(bSuccess)
2751*12720SWyllys.Ingersoll@Sun.COM     {
2752*12720SWyllys.Ingersoll@Sun.COM         strncpy(i_pProfile->m_wsApplianceAddress,
2753*12720SWyllys.Ingersoll@Sun.COM             i_wsApplianceAddress,
2754*12720SWyllys.Ingersoll@Sun.COM             KMS_MAX_NETWORK_ADDRESS);
2755*12720SWyllys.Ingersoll@Sun.COM         i_pProfile->m_wsApplianceAddress[KMS_MAX_NETWORK_ADDRESS] = 0;
2756*12720SWyllys.Ingersoll@Sun.COM     }
2757*12720SWyllys.Ingersoll@Sun.COM 
2758*12720SWyllys.Ingersoll@Sun.COM     bSuccess = StoreConfig( i_pProfile );
2759*12720SWyllys.Ingersoll@Sun.COM 
2760*12720SWyllys.Ingersoll@Sun.COM     return bSuccess;
2761*12720SWyllys.Ingersoll@Sun.COM }
2762*12720SWyllys.Ingersoll@Sun.COM 
KMSClient_ProfileLoaded(KMSClientProfile * i_pProfile)2763*12720SWyllys.Ingersoll@Sun.COM bool KMSClient_ProfileLoaded( KMSClientProfile *i_pProfile )
2764*12720SWyllys.Ingersoll@Sun.COM {
2765*12720SWyllys.Ingersoll@Sun.COM 
2766*12720SWyllys.Ingersoll@Sun.COM #if defined(DEBUG) && defined(METAWARE)
2767*12720SWyllys.Ingersoll@Sun.COM    log_printf ("profile: %x", i_pProfile);
2768*12720SWyllys.Ingersoll@Sun.COM    log_printf ("profile: enrolled %x", i_pProfile->m_iEnrolled);
2769*12720SWyllys.Ingersoll@Sun.COM    log_printf ("profile: version  %x", i_pProfile->m_iVersion);
2770*12720SWyllys.Ingersoll@Sun.COM #endif
2771*12720SWyllys.Ingersoll@Sun.COM 
2772*12720SWyllys.Ingersoll@Sun.COM     // more extensive tests could be performed but this should suffice
2773*12720SWyllys.Ingersoll@Sun.COM     if ( i_pProfile &&
2774*12720SWyllys.Ingersoll@Sun.COM         i_pProfile->m_iEnrolled &&
2775*12720SWyllys.Ingersoll@Sun.COM 		i_pProfile->m_iVersion == KMS_AGENT_VERSION )
2776*12720SWyllys.Ingersoll@Sun.COM     {
2777*12720SWyllys.Ingersoll@Sun.COM         return true;
2778*12720SWyllys.Ingersoll@Sun.COM     }
2779*12720SWyllys.Ingersoll@Sun.COM     else
2780*12720SWyllys.Ingersoll@Sun.COM     {
2781*12720SWyllys.Ingersoll@Sun.COM         return false;
2782*12720SWyllys.Ingersoll@Sun.COM     }
2783*12720SWyllys.Ingersoll@Sun.COM }
2784*12720SWyllys.Ingersoll@Sun.COM 
2785*12720SWyllys.Ingersoll@Sun.COM /*---------------------------------------------------------------------------
2786*12720SWyllys.Ingersoll@Sun.COM  * Function: KMSClient_DeleteProfile
2787*12720SWyllys.Ingersoll@Sun.COM  *
2788*12720SWyllys.Ingersoll@Sun.COM  *--------------------------------------------------------------------------*/
KMSClient_DeleteProfile(utf8char * i_wsProfileName)2789*12720SWyllys.Ingersoll@Sun.COM bool KMSClient_DeleteProfile(utf8char *i_wsProfileName)
2790*12720SWyllys.Ingersoll@Sun.COM {
2791*12720SWyllys.Ingersoll@Sun.COM     FATAL_ASSERT( i_wsProfileName && (strlen(i_wsProfileName) > 0) );
2792*12720SWyllys.Ingersoll@Sun.COM 
2793*12720SWyllys.Ingersoll@Sun.COM     bool bSuccess = true;
2794*12720SWyllys.Ingersoll@Sun.COM 
2795*12720SWyllys.Ingersoll@Sun.COM     if (ProfileExists(g_wsWorkingDirectory, /* pass in default */
2796*12720SWyllys.Ingersoll@Sun.COM                       i_wsProfileName))
2797*12720SWyllys.Ingersoll@Sun.COM     {
2798*12720SWyllys.Ingersoll@Sun.COM         bSuccess = DeleteStorageProfile(i_wsProfileName);
2799*12720SWyllys.Ingersoll@Sun.COM     }
2800*12720SWyllys.Ingersoll@Sun.COM 
2801*12720SWyllys.Ingersoll@Sun.COM     return bSuccess;
2802*12720SWyllys.Ingersoll@Sun.COM }
2803*12720SWyllys.Ingersoll@Sun.COM 
2804*12720SWyllys.Ingersoll@Sun.COM /*---------------------------------------------------------------------------
2805*12720SWyllys.Ingersoll@Sun.COM  * Function: KMSClient_UnloadProfile
2806*12720SWyllys.Ingersoll@Sun.COM  *
2807*12720SWyllys.Ingersoll@Sun.COM  *--------------------------------------------------------------------------*/
KMSClient_UnloadProfile(KMSClientProfile * i_pProfile)2808*12720SWyllys.Ingersoll@Sun.COM bool KMSClient_UnloadProfile(KMSClientProfile *i_pProfile)
2809*12720SWyllys.Ingersoll@Sun.COM {
2810*12720SWyllys.Ingersoll@Sun.COM     if(i_pProfile != NULL && i_pProfile->m_pLock != NULL )
2811*12720SWyllys.Ingersoll@Sun.COM     {
2812*12720SWyllys.Ingersoll@Sun.COM #ifdef KMSUSERPKCS12
2813*12720SWyllys.Ingersoll@Sun.COM 	/* Delete the private client key file if it's still around */
2814*12720SWyllys.Ingersoll@Sun.COM 	CleanupPrivateKeyFile(i_pProfile);
2815*12720SWyllys.Ingersoll@Sun.COM #endif
2816*12720SWyllys.Ingersoll@Sun.COM         if (i_pProfile->m_pAgentLoadBalancer != NULL)
2817*12720SWyllys.Ingersoll@Sun.COM         {
2818*12720SWyllys.Ingersoll@Sun.COM             delete reinterpret_cast
2819*12720SWyllys.Ingersoll@Sun.COM                 <CAgentLoadBalancer *> (i_pProfile->m_pAgentLoadBalancer);
2820*12720SWyllys.Ingersoll@Sun.COM         }
2821*12720SWyllys.Ingersoll@Sun.COM         if (i_pProfile->m_pDataUnitCache != NULL)
2822*12720SWyllys.Ingersoll@Sun.COM         {
2823*12720SWyllys.Ingersoll@Sun.COM             delete reinterpret_cast<CDataUnitCache *> (i_pProfile->m_pDataUnitCache);
2824*12720SWyllys.Ingersoll@Sun.COM         }
2825*12720SWyllys.Ingersoll@Sun.COM         K_DestroyMutex((K_MUTEX_HANDLE)i_pProfile->m_pLock);
2826*12720SWyllys.Ingersoll@Sun.COM         i_pProfile->m_pLock = 0;
2827*12720SWyllys.Ingersoll@Sun.COM 
2828*12720SWyllys.Ingersoll@Sun.COM         if ( i_pProfile->m_pvSoap )
2829*12720SWyllys.Ingersoll@Sun.COM         {
2830*12720SWyllys.Ingersoll@Sun.COM             soap_destroy( (struct soap*)i_pProfile->m_pvSoap );
2831*12720SWyllys.Ingersoll@Sun.COM             soap_end( (struct soap*)i_pProfile->m_pvSoap );
2832*12720SWyllys.Ingersoll@Sun.COM             soap_done( (struct soap*)i_pProfile->m_pvSoap );
2833*12720SWyllys.Ingersoll@Sun.COM 
2834*12720SWyllys.Ingersoll@Sun.COM             free( (struct soap*)i_pProfile->m_pvSoap );
2835*12720SWyllys.Ingersoll@Sun.COM             i_pProfile->m_pvSoap = 0;
2836*12720SWyllys.Ingersoll@Sun.COM         }
2837*12720SWyllys.Ingersoll@Sun.COM 
2838*12720SWyllys.Ingersoll@Sun.COM         if ( i_pProfile->m_pvDiscoverySoap)
2839*12720SWyllys.Ingersoll@Sun.COM         {
2840*12720SWyllys.Ingersoll@Sun.COM             soap_destroy( (struct soap*)i_pProfile->m_pvDiscoverySoap );
2841*12720SWyllys.Ingersoll@Sun.COM             soap_end( (struct soap*)i_pProfile->m_pvDiscoverySoap );
2842*12720SWyllys.Ingersoll@Sun.COM             soap_done( (struct soap*)i_pProfile->m_pvDiscoverySoap );
2843*12720SWyllys.Ingersoll@Sun.COM 
2844*12720SWyllys.Ingersoll@Sun.COM             free( (struct soap*)i_pProfile->m_pvDiscoverySoap );
2845*12720SWyllys.Ingersoll@Sun.COM             i_pProfile->m_pvDiscoverySoap = 0;
2846*12720SWyllys.Ingersoll@Sun.COM         }
2847*12720SWyllys.Ingersoll@Sun.COM     }
2848*12720SWyllys.Ingersoll@Sun.COM 
2849*12720SWyllys.Ingersoll@Sun.COM     i_pProfile->m_iEnrolled = FALSE;
2850*12720SWyllys.Ingersoll@Sun.COM 
2851*12720SWyllys.Ingersoll@Sun.COM     return true; /* always return true, maybe there are cases which return false in the future */
2852*12720SWyllys.Ingersoll@Sun.COM }
2853*12720SWyllys.Ingersoll@Sun.COM 
FIPScompatibleKMA(const char * const i_sKMAVersion)2854*12720SWyllys.Ingersoll@Sun.COM bool FIPScompatibleKMA(
2855*12720SWyllys.Ingersoll@Sun.COM         const char * const i_sKMAVersion) {
2856*12720SWyllys.Ingersoll@Sun.COM     return (strcmp(i_sKMAVersion,
2857*12720SWyllys.Ingersoll@Sun.COM             FIPS_COMPATIBLE_KMA_VERSION) >= 0);
2858*12720SWyllys.Ingersoll@Sun.COM }
2859*12720SWyllys.Ingersoll@Sun.COM 
2860*12720SWyllys.Ingersoll@Sun.COM #ifdef KMSUSERPKCS12
2861*12720SWyllys.Ingersoll@Sun.COM extern "C"
2862*12720SWyllys.Ingersoll@Sun.COM KMS_AGENT_STATUS
KMSAgent_GetProfileStatus(char * i_pProfileName,KMSAGENT_PROFILE_FLAGS * flags)2863*12720SWyllys.Ingersoll@Sun.COM KMSAgent_GetProfileStatus(
2864*12720SWyllys.Ingersoll@Sun.COM 	char* i_pProfileName,
2865*12720SWyllys.Ingersoll@Sun.COM 	KMSAGENT_PROFILE_FLAGS *flags)
2866*12720SWyllys.Ingersoll@Sun.COM {
2867*12720SWyllys.Ingersoll@Sun.COM 	/*
2868*12720SWyllys.Ingersoll@Sun.COM 	 * Determine how "initialized" the KMS token is by checking for
2869*12720SWyllys.Ingersoll@Sun.COM 	 * the profile config file and also the entity key container (pkcs#12).
2870*12720SWyllys.Ingersoll@Sun.COM 	 */
2871*12720SWyllys.Ingersoll@Sun.COM 	if (ProfileExists(g_wsWorkingDirectory, i_pProfileName)) {
2872*12720SWyllys.Ingersoll@Sun.COM 		*flags |= KMSAGENT_PROFILE_EXISTS_FLAG;
2873*12720SWyllys.Ingersoll@Sun.COM 		if (ClientKeyP12Exists(i_pProfileName))
2874*12720SWyllys.Ingersoll@Sun.COM 			*flags |= KMSAGENT_CLIENTKEY_EXISTS_FLAG;
2875*12720SWyllys.Ingersoll@Sun.COM 	}
2876*12720SWyllys.Ingersoll@Sun.COM 	return (KMS_AGENT_STATUS_OK);
2877*12720SWyllys.Ingersoll@Sun.COM }
2878*12720SWyllys.Ingersoll@Sun.COM #endif
2879