xref: /onnv-gate/usr/src/lib/libkmsagent/common/KMSAgentStorage.cpp (revision 12720:3db6e0082404)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 /**
27  *  \file   KMSAgentStorage.cpp
28  *  This file provides an implementation of the KMSAgentStorage.h
29  *  interface utilizing a filesystem for storage of KMS Client
30  *  Profile elements.
31  *
32  *  For storage of Certificates and Private key material the PKICommon
33  *  interface is used.
34  */
35 
36 #include <stdio.h>
37 #include <string.h>
38 
39 #ifndef METAWARE
40 #include <errno.h>
41 #endif
42 
43 #ifdef K_SOLARIS_PLATFORM
44 #ifndef SOLARIS10
45 #include <cryptoutil.h>
46 #endif
47 #include <pthread.h>
48 #include <fcntl.h>
49 #endif
50 
51 #include "stdsoap2.h"
52 
53 #include "KMSClientProfile.h"  // must be before agentstorage
54 #include "KMSAgentPKICommon.h" // must be before agentstorage
55 #include "KMSAgentStorage.h"
56 
57 #include "SYSCommon.h"
58 #include "AutoMutex.h"
59 #include "KMSAuditLogger.h"
60 #include "KMSClientProfileImpl.h"
61 
62 #include "KMSAgent_direct.h"
63 #ifdef K_SOLARIS_PLATFORM
64 #include "KMSAgent.h"
65 #endif
66 #include "k_setupssl.h"        // K_ssl_client_context
67 
68 #ifdef METAWARE
69 extern "C" int K_ssl_client_context(struct soap *soap,
70                                     int flags,
71                                     const char *keyfile,  // NULL - SERVER
72                                     const char *password, // NULL - SERVER
73                                     const char *cafile,
74                                     const char *capath,   // ALWAYS NULL
75                                     const char *randfile); // ALWAYS NULL
76 #include "debug.h"
77 #endif
78 
79 
80 #define CA_CERTIFICATE_FILE    "ca.crt"
81 #define CLIENT_KEY_FILE        "clientkey.pem"
82 
83 #define PROFILE_CONFIG_FILE         "profile.cfg"
84 #define PROFILE_CLUSTER_CONFIG_FILE "cluster.cfg"
85 
86 static char g_sWorkingDirectory[KMS_MAX_PATH_LENGTH+1];
87 static char g_sStringbuf[10000]; // too large to be on the 9840D stack
88 
BuildFullProfilePathWithName(utf8cstr o_pProfilePath,const char * const i_pWorkingDirectory,const char * const i_pProfileName)89 static void BuildFullProfilePathWithName(utf8cstr          o_pProfilePath,
90                                          const char* const i_pWorkingDirectory,
91                                          const char* const i_pProfileName)
92 {
93    int len;
94    FATAL_ASSERT( o_pProfilePath );
95    FATAL_ASSERT( i_pWorkingDirectory );
96    FATAL_ASSERT( i_pProfileName );
97    FATAL_ASSERT( (strlen(i_pWorkingDirectory) > 0) );
98    FATAL_ASSERT( (strlen(i_pProfileName) > 0) );
99 
100 #if defined(DEBUG_TRACE) && defined(METAWARE)
101    ECPT_TRACE_ENTRY   *trace = NULL;
102    ECPT_TRACE( trace, BuildFullProfilePathWithName );
103 #endif
104 
105    strncpy(o_pProfilePath, i_pWorkingDirectory,
106            KMS_MAX_FILE_NAME );
107 
108    if ( o_pProfilePath[ strlen(o_pProfilePath) -1 ] != PATH_SEPARATOR )
109    {
110       len = strlen(o_pProfilePath);
111       o_pProfilePath[ len ] = PATH_SEPARATOR ;
112       o_pProfilePath[ len + 1 ] = '\0';
113    }
114 
115    strncat( o_pProfilePath, i_pProfileName, KMS_MAX_FILE_NAME );
116    len = strlen(o_pProfilePath);
117    o_pProfilePath[ len ] = PATH_SEPARATOR ;
118    o_pProfilePath[ len +1 ] = '\0';
119 
120    return;
121 }
122 
BuildFullProfilePath(utf8cstr o_sProfilePath,const char * const i_pWorkingDirectory,const char * const i_pProfileName)123 static void BuildFullProfilePath(utf8cstr          o_sProfilePath,
124                                  const char* const i_pWorkingDirectory,
125                                  const char* const i_pProfileName)
126 {
127    FATAL_ASSERT( o_sProfilePath );
128    FATAL_ASSERT( i_pWorkingDirectory );
129    FATAL_ASSERT( i_pProfileName );
130    FATAL_ASSERT( (strlen(i_pProfileName) > 0) );
131 
132    BuildFullProfilePathWithName( o_sProfilePath,
133                                  i_pWorkingDirectory,
134                                  i_pProfileName );
135 
136    return;
137 }
138 
139 #ifdef K_SOLARIS_PLATFORM
140 static struct flock cfgfl = {
141 	0, 0, 0, 0, 0, 0,
142 	{0, 0, 0, 0}
143 };
144 static struct flock clusterfl = {
145 	0, 0, 0, 0, 0, 0,
146 	{0, 0, 0, 0}
147 };
148 
149 pthread_mutex_t cfg_mutex = PTHREAD_MUTEX_INITIALIZER;
150 pthread_mutex_t cluster_mutex = PTHREAD_MUTEX_INITIALIZER;
151 pthread_mutex_t keyfile_mutex = PTHREAD_MUTEX_INITIALIZER;
152 
153 static int
flock_fd(int fd,int cmd,struct flock * fl,pthread_mutex_t * mutex)154 flock_fd(int fd, int cmd, struct flock *fl, pthread_mutex_t *mutex)
155 {
156 	int ret = 0;
157 
158 	(void) pthread_mutex_lock(mutex);
159 
160 	fl->l_type = cmd;
161 
162 	while ((ret = fcntl(fd, F_SETLKW, fl)) == -1) {
163 		if (errno != EINTR)
164 			break;
165 	}
166 	(void) pthread_mutex_unlock(mutex);
167 	return (ret);
168 }
169 
170 #endif
171 
Profile_WriteConfigFile(KMSClientProfile * i_pProfile,const char * i_pFileName)172 static bool Profile_WriteConfigFile(KMSClientProfile *i_pProfile,
173                                     const char *i_pFileName)
174 {
175    FATAL_ASSERT( i_pProfile );
176    FATAL_ASSERT( i_pFileName );
177 
178    CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
179 
180 #if defined(DEBUG_TRACE) && defined(METAWARE)
181    ECPT_TRACE_ENTRY   *trace = NULL;
182    ECPT_TRACE( trace, Profile_WriteConfigFile );
183 #endif
184 
185    char *sp = g_sStringbuf;
186    size_t  bytesWritten = 0;
187 
188    // save config parameters
189 
190    myFILE *fp = fopen(i_pFileName, "w");
191    if(fp == NULL)
192    {
193       LogError(i_pProfile,
194                AUDIT_PROFILE_WRITE_CONFIG_FILE_OPEN_CONFIGURATION_FILE_FAILED,
195                NULL,
196                NULL,
197                i_pFileName);
198 
199       return false;
200    }
201 
202 #ifdef K_SOLARIS_PLATFORM
203    int fd = fileno(fp);
204    (void) flock_fd(fd, F_WRLCK, &cfgfl, &cfg_mutex);
205 #endif
206 
207 const char* const sProfileName = i_pProfile->m_wsProfileName;
208 
209    sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "ProfileName=%s\n", sProfileName);
210 
211    sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "AgentID=%s\n", i_pProfile->m_wsEntityID);
212 
213    sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "ClusterDiscoveryFrequency=%d\n",
214                  i_pProfile->m_iClusterDiscoveryFrequency);
215 
216    sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "CAServicePortNumber=%d\n",
217                  i_pProfile->m_iPortForCAService);
218 
219    sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "CertificateServicePortNumber=%d\n",
220                  i_pProfile->m_iPortForCertificateService);
221 
222    if(i_pProfile->m_iPortForAgentService != 0)
223    {
224       sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "AgentServicePortNumber=%d\n",
225                     i_pProfile->m_iPortForAgentService);
226    }
227 
228    if(i_pProfile->m_iPortForDiscoveryService != 0)
229    {
230       sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "DiscoveryServicePortNumber=%d\n",
231                     i_pProfile->m_iPortForDiscoveryService);
232    }
233 
234    sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "ApplianceAddress=%s\n", i_pProfile->m_wsApplianceAddress);
235 
236    sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "Timeout=%d\n", i_pProfile->m_iTransactionTimeout);
237 
238    sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "FailoverLimt=%d\n", i_pProfile->m_iFailoverLimit);
239 
240    sp += K_snprintf(sp, sizeof(i_pProfile->m_wsProfileName), "HexHashedPassphrase=%s\n", i_pProfile->m_sHexHashedPassphrase);
241 
242    bytesWritten = fputs(g_sStringbuf, fp);
243 
244 #ifdef K_SOLARIS_PLATFORM
245    (void) flock_fd(fd, F_UNLCK, &cfgfl, &cfg_mutex);
246 #endif
247 
248 #ifndef WIN32
249    if ( strlen(g_sStringbuf) != bytesWritten )
250 #else
251    if ( bytesWritten < 0 )
252 #endif
253    {
254       fclose(fp);
255       return false;
256    }
257    fclose(fp);
258 
259    return true;
260 }
261 
Profile_ReadConfigFile(KMSClientProfile * i_pProfile,const char * i_pFileName)262 static bool Profile_ReadConfigFile
263 ( KMSClientProfile *i_pProfile,
264   const char *i_pFileName)
265 {
266    FATAL_ASSERT( i_pProfile  );
267    FATAL_ASSERT( i_pFileName );
268 
269 #if defined(DEBUG_TRACE) && defined(METAWARE)
270    ECPT_TRACE_ENTRY   *trace = NULL;
271    ECPT_TRACE( trace, Profile_ReadConfigFile ) ;
272 #endif
273 
274    CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)i_pProfile->m_pLock );
275 
276    const int iMaxLineSize = 1024;
277 
278    myFILE *fp;
279    char acBuffer[iMaxLineSize+1];
280 
281    fp = fopen(i_pFileName, "r");
282    if(fp == NULL)
283    {
284       LogError(i_pProfile,
285                AUDIT_PROFILE_READ_CONFIG_FILE_OPEN_CONFIGURATION_FILE_FAILED,
286                NULL,
287                NULL,
288                i_pFileName);
289       return false;
290    }
291 
292 #ifdef K_SOLARIS_PLATFORM
293    int fd = fileno(fp);
294    (void) flock_fd(fd, F_RDLCK, &cfgfl, &cfg_mutex);
295 #endif
296    // read file one line by one line
297    while(1)
298    {
299       int i;
300       char *pName, *pValue;
301 
302       memset(acBuffer, 0, iMaxLineSize+1);
303 
304       //---------------------------
305       // get info from the file
306       //---------------------------
307       if(fgets(acBuffer, iMaxLineSize+1, fp) == NULL)
308          break;
309 
310       if(strlen(acBuffer) < 3)
311          continue;
312 
313       if(acBuffer[0] == '#' ||
314          acBuffer[0] == ';' ||
315          acBuffer[0] == '[')  // jump comments
316          continue;
317 
318       pName = acBuffer;
319       pValue = NULL;
320 
321       for(i = 0; acBuffer[i] != '\0'; i++)
322       {
323          if(acBuffer[i] == '=')
324             pValue = acBuffer + i + 1;
325 
326          if(acBuffer[i] == '=' ||
327             acBuffer[i] == '\r' ||
328             acBuffer[i] == '\n')
329             acBuffer[i] = '\0';
330       }
331 
332       if(pValue == NULL)
333       {
334          LogError(i_pProfile,
335                   AUDIT_PROFILE_READ_CONFIG_FILE_INVALID_CONFIGURATION_FILE_FORMAT,
336                   NULL,
337                   NULL,
338                   i_pFileName);
339 #ifdef K_SOLARIS_PLATFORM
340 	(void) flock_fd(fd, F_UNLCK, &cfgfl, &cfg_mutex);
341 #endif
342          fclose(fp);
343          return false;
344       }
345 
346       if(strcmp(pName, "ProfileName") == 0)
347       {
348          utf8cstr wsValue = pValue;
349          strncpy(i_pProfile->m_wsProfileName, wsValue, KMS_MAX_ENTITY_ID);
350          i_pProfile->m_wsProfileName[KMS_MAX_ENTITY_ID] = 0;
351       }
352 
353       if(strcmp(pName, "AgentID") == 0)
354       {
355          utf8cstr wsValue = pValue;
356          strncpy(i_pProfile->m_wsEntityID, wsValue, KMS_MAX_ENTITY_ID);
357          i_pProfile->m_wsEntityID[KMS_MAX_ENTITY_ID] = 0;
358       }
359 
360       if(strcmp(pName, "ClusterDiscoveryFrequency") == 0)
361       {
362          sscanf(pValue, "%d", &(i_pProfile->m_iClusterDiscoveryFrequency));
363       }
364 
365       if(strcmp(pName, "CAServicePortNumber") == 0)
366       {
367          sscanf(pValue, "%d", &(i_pProfile->m_iPortForCAService));
368       }
369 
370       if(strcmp(pName, "CertificateServicePortNumber") == 0)
371       {
372          sscanf(pValue, "%d", &(i_pProfile->m_iPortForCertificateService));
373       }
374 
375       if(strcmp(pName, "AgentServicePortNumber") == 0)
376       {
377          sscanf(pValue, "%d", &(i_pProfile->m_iPortForAgentService));
378       }
379 
380       if(strcmp(pName, "DiscoveryServicePortNumber") == 0)
381       {
382          sscanf(pValue, "%d", &(i_pProfile->m_iPortForDiscoveryService));
383       }
384 
385       if(strcmp(pName, "ApplianceAddress") == 0)
386       {
387          utf8cstr wsValue = pValue;
388          strncpy(i_pProfile->m_wsApplianceAddress,
389                  wsValue, KMS_MAX_NETWORK_ADDRESS);
390          i_pProfile->m_wsApplianceAddress[KMS_MAX_NETWORK_ADDRESS] = 0;
391       }
392 
393       if(strcmp(pName, "Timeout") == 0)
394       {
395          sscanf(pValue, "%d", &(i_pProfile->m_iTransactionTimeout));
396       }
397 
398       if(strcmp(pName, "FailoverLimt") == 0)
399       {
400          sscanf(pValue, "%d", &(i_pProfile->m_iFailoverLimit));
401       }
402 
403       if(strcmp(pName, "HexHashedPassphrase") == 0)
404       {
405          sscanf(pValue, "%s", i_pProfile->m_sHexHashedPassphrase);
406       }
407    }
408 
409 #ifdef K_SOLARIS_PLATFORM
410    (void) flock_fd(fd, F_UNLCK, &cfgfl, &cfg_mutex);
411 #endif
412    fclose(fp);
413 
414    return true;
415 }
416 
417 
418 
419 
420 
421 /*! ProfileExists
422  *
423  */
ProfileExists(const char * const i_pWorkingDirectory,const char * const i_pProfileName)424 extern "C" bool ProfileExists(
425    const char* const i_pWorkingDirectory,
426    const char* const i_pProfileName)
427 {
428    FATAL_ASSERT( i_pWorkingDirectory );
429    FATAL_ASSERT( i_pProfileName );
430 
431 #if defined(DEBUG_TRACE) && defined(METAWARE)
432    ECPT_TRACE_ENTRY   *trace = NULL;
433    ECPT_TRACE( trace, ProfileExists );
434 #endif
435 
436 
437    // the profile is stored in the working folder
438    strncpy( g_sWorkingDirectory,
439             i_pWorkingDirectory,
440             KMS_MAX_PATH_LENGTH );
441 
442    char sFullProfileDir[KMS_MAX_FILE_NAME+1];
443    BuildFullProfilePath( sFullProfileDir,
444                          i_pWorkingDirectory,
445                          i_pProfileName );
446 
447    char sConfigFile[KMS_MAX_FILE_NAME+1] = "";
448    strncpy( sConfigFile, sFullProfileDir, KMS_MAX_FILE_NAME );
449    sConfigFile[KMS_MAX_FILE_NAME] = '\0';
450    strncat( sConfigFile, PROFILE_CONFIG_FILE, KMS_MAX_FILE_NAME );
451 
452    // just try to open the file to test if it exists
453 
454    bool bProfileExists = false;
455 
456    myFILE* pfFile = fopen( sConfigFile, "rb" );
457 
458    if ( pfFile != NULL )
459    {
460       bProfileExists = true;
461 
462       fclose(pfFile);
463    }
464 
465    return bProfileExists;
466 }
467 
468 
469 /*! CreateProfile
470  *
471  */
CreateProfile(KMSClientProfile * const io_pProfile,const char * const i_pWorkingDirectory,const char * const i_pProfileName)472 bool CreateProfile(
473    KMSClientProfile* const io_pProfile,
474    const char* const       i_pWorkingDirectory,
475    const char* const       i_pProfileName)
476 {
477    FATAL_ASSERT( io_pProfile );
478    FATAL_ASSERT( i_pWorkingDirectory );
479    FATAL_ASSERT( i_pProfileName );
480    FATAL_ASSERT( (strlen(i_pProfileName) > 0) );
481 
482 #if defined(DEBUG_TRACE) && defined(METAWARE)
483    ECPT_TRACE_ENTRY   *trace = NULL;
484    ECPT_TRACE( trace, CreateProfile );
485 
486 #endif
487 
488    bool bSuccess = false;
489    CAutoMutex oAutoMutex( (K_MUTEX_HANDLE)io_pProfile->m_pLock );
490 
491    char sFullProfileDir[KMS_MAX_FILE_NAME];
492    BuildFullProfilePath( sFullProfileDir,
493                          i_pWorkingDirectory,
494                          i_pProfileName );
495 
496    bSuccess = ( K_CreateDirectory( sFullProfileDir ) == 0 );
497 
498    if ( !bSuccess )
499    {
500       Log(AUDIT_CLIENT_LOAD_PROFILE_CREATE_DIRECTORY_FAILED,
501           NULL,
502           NULL,
503           NULL );
504    }
505    strncpy( g_sWorkingDirectory, i_pWorkingDirectory, KMS_MAX_PATH_LENGTH );
506 
507    bSuccess = StoreConfig( io_pProfile );
508    if ( !bSuccess )
509    {
510       Log(AUDIT_CLIENT_LOAD_PROFILE_CREATE_PROFILE_CONFIG_FAILED,
511           NULL,
512           NULL,
513           NULL );
514    }
515    else
516    {
517       Log(AUDIT_CLIENT_LOAD_PROFILE_CREATE_PROFILE_CONFIG_SUCCEEDED,
518           NULL,
519           NULL,
520           NULL );
521    }
522 
523    return bSuccess;
524 }
525 
526 
527 /*! StoreConfig
528  * Store the configuration to persistent storage
529  */
StoreConfig(KMSClientProfile * const i_pProfile)530 bool StoreConfig(
531    KMSClientProfile* const i_pProfile )
532 {
533    FATAL_ASSERT( i_pProfile );
534 
535 #if defined(DEBUG_TRACE) && defined(METAWARE)
536    ECPT_TRACE_ENTRY   *trace = NULL;
537    ECPT_TRACE( trace, StoreConfig ) ;
538 #endif
539 
540    char sConfigFile[KMS_MAX_FILE_NAME];
541    BuildFullProfilePath( sConfigFile,
542                          g_sWorkingDirectory, i_pProfile->m_wsProfileName );
543 
544    strncat( sConfigFile, PROFILE_CONFIG_FILE, KMS_MAX_FILE_NAME );
545 
546    return Profile_WriteConfigFile(i_pProfile, sConfigFile );
547 }
548 
549 /*! StoreCluster
550  * Store the cluster to persistent storage
551  */
StoreCluster(KMSClientProfile * const i_pProfile)552 bool StoreCluster(
553    KMSClientProfile* const i_pProfile )
554 {
555    FATAL_ASSERT( i_pProfile );
556 
557    myFILE *fp;
558    int sCount;
559    char *sp = g_sStringbuf;
560 
561    char sFullProfileDir[KMS_MAX_FILE_NAME+1];
562    BuildFullProfilePath( sFullProfileDir,
563                          g_sWorkingDirectory, i_pProfile->m_wsProfileName );
564 
565    char sClusterFile[KMS_MAX_FILE_NAME+1] = "";
566    strncpy( sClusterFile, sFullProfileDir, KMS_MAX_FILE_NAME );
567    sClusterFile[KMS_MAX_FILE_NAME] = '\0';
568    strncat( sClusterFile, PROFILE_CLUSTER_CONFIG_FILE, KMS_MAX_FILE_NAME );
569 
570 #if defined(DEBUG_TRACE) && defined(METAWARE)
571    ECPT_TRACE_ENTRY   *trace = NULL;
572    ECPT_TRACE( trace, StoreCluster );
573 #endif
574 
575 
576    fp = fopen(sClusterFile, "w");
577    if (fp == NULL)
578    {
579       LogError(i_pProfile,
580                AUDIT_CLIENT_SAVE_CLUSTER_INFORMATION_OPEN_CLUSTER_FILE_FAILED,
581                NULL,
582                NULL,
583                sClusterFile );
584       return false;
585    }
586 
587 #ifdef K_SOLARIS_PLATFORM
588    int fd = fileno(fp);
589    (void) flock_fd(fd, F_WRLCK, &clusterfl, &cluster_mutex);
590 #endif
591 
592    sp += K_snprintf(sp, sizeof(g_sStringbuf), "EntitySiteID=%s\n\n", i_pProfile->m_wsEntitySiteID);
593 
594    for (int i = 0;  i < i_pProfile->m_iClusterNum; i++)
595    {
596       if ( i > 0 )
597       {
598          sp += K_snprintf(sp, sizeof(g_sStringbuf), "\n");
599       }
600 
601       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf),"<StartAppliance>\n")) < 0 )
602       {
603 #ifdef K_SOLARIS_PLATFORM
604 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
605 #endif
606         fclose(fp);
607 	return false; }
608       sp += sCount;
609 
610 #ifdef WIN32
611       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "ApplianceID=%I64d\n",
612                              i_pProfile->m_aCluster[i].m_lApplianceID)) < 0 )
613       { fclose(fp); return false; }
614       sp += sCount;
615 
616 #else
617       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "ApplianceID=%lld\n",
618                              i_pProfile->m_aCluster[i].m_lApplianceID)) < 0 )
619       {
620 #ifdef K_SOLARIS_PLATFORM
621 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
622 #endif
623         fclose(fp);
624 	return false; }
625       sp += sCount;
626 #endif
627 
628       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "Enabled=%d\n",
629                              i_pProfile->m_aCluster[i].m_iEnabled)) < 0 )
630 	{
631 #ifdef K_SOLARIS_PLATFORM
632 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
633 #endif
634         fclose(fp);
635 	return false; }
636       sp += sCount;
637 
638       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "Responding=%d\n",
639                              i_pProfile->m_aCluster[i].m_iResponding)) < 0 )
640 	{
641 #ifdef K_SOLARIS_PLATFORM
642 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
643 #endif
644         fclose(fp);
645 	return false; }
646       sp += sCount;
647 
648       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "Load=%lld\n",
649                              i_pProfile->m_aCluster[i].m_lLoad)) < 0 )
650 	{
651 #ifdef K_SOLARIS_PLATFORM
652 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
653 #endif
654         fclose(fp);
655 	return false; }
656       sp += sCount;
657 
658       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "ApplianceAlias=%s\n",
659                              i_pProfile->m_aCluster[i].m_wsApplianceAlias)) < 0 )
660 	{
661 #ifdef K_SOLARIS_PLATFORM
662 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
663 #endif
664         fclose(fp);
665 	return false; }
666       sp += sCount;
667 
668       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "ApplianceNetworkAddress=%s\n",
669                              i_pProfile->m_aCluster[i].m_wsApplianceNetworkAddress)) < 0 )
670 	{
671 #ifdef K_SOLARIS_PLATFORM
672 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
673 #endif
674         fclose(fp);
675 	return false; }
676       sp += sCount;
677 
678       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "ApplianceSiteID=%s\n",
679                              i_pProfile->m_aCluster[i].m_wsApplianceSiteID)) < 0 )
680 	{
681 #ifdef K_SOLARIS_PLATFORM
682 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
683 #endif
684         fclose(fp);
685 	return false; }
686       sp += sCount;
687 
688       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "KMAVersion=%s\n",
689                              i_pProfile->m_aCluster[i].m_sKMAVersion)) < 0 )
690 	{
691 #ifdef K_SOLARIS_PLATFORM
692 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
693 #endif
694         fclose(fp);
695 	return false; }
696       sp += sCount;
697 
698       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "KMALocked=%d\n",
699                              i_pProfile->m_aCluster[i].m_iKMALocked)) < 0 )
700 	{
701 #ifdef K_SOLARIS_PLATFORM
702 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
703 #endif
704         fclose(fp);
705 	return false; }
706       sp += sCount;
707 
708       if (( sCount = K_snprintf(sp, sizeof(g_sStringbuf), "<EndAppliance>\n")) < 0 )
709 	{
710 #ifdef K_SOLARIS_PLATFORM
711 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
712 #endif
713         fclose(fp);
714 	return false; }
715       sp += sCount;
716    }
717 
718    fputs(g_sStringbuf, fp);
719 #ifdef K_SOLARIS_PLATFORM
720 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
721 #endif
722    fclose(fp);
723    Log(AUDIT_CLIENT_SAVE_CLUSTER_INFORMATION_SUCCEEDED,
724           NULL,
725           NULL,
726           NULL );
727 
728    return true;
729 }
730 
731 /*! GetConfig
732  * get the configuration file from persistent storage
733  */
GetConfig(KMSClientProfile * const io_pProfile)734 bool GetConfig(
735    KMSClientProfile* const io_pProfile )
736 {
737    FATAL_ASSERT( io_pProfile );
738    char sFullProfileDir[KMS_MAX_FILE_NAME+1];
739 
740    BuildFullProfilePath( sFullProfileDir,
741                          g_sWorkingDirectory,
742                          io_pProfile->m_wsProfileName );
743 
744    char sConfigFile[KMS_MAX_FILE_NAME+1];
745 
746    strncpy( sConfigFile, sFullProfileDir, KMS_MAX_FILE_NAME );
747    sConfigFile[KMS_MAX_FILE_NAME] = '\0';
748    strncat( sConfigFile, PROFILE_CONFIG_FILE, KMS_MAX_FILE_NAME );
749 
750    return Profile_ReadConfigFile( io_pProfile, sConfigFile );
751 }
752 
753 /** GetCluster
754  * get the cluster information from persistent storage
755  */
GetCluster(KMSClientProfile * const io_pProfile,int & o_bClusterInformationFound)756 bool GetCluster(
757    KMSClientProfile* const io_pProfile,
758    int&                   o_bClusterInformationFound )
759 
760 {
761    FATAL_ASSERT( io_pProfile );
762 
763    const int iMaxLineSize = 1024;
764 
765    myFILE *fp;
766    char acBuffer[iMaxLineSize+1];
767    char sFullProfileDir[KMS_MAX_FILE_NAME+1];
768 
769    BuildFullProfilePath( sFullProfileDir,
770                          g_sWorkingDirectory,
771                          io_pProfile->m_wsProfileName );
772 
773    char sClusterFile[KMS_MAX_FILE_NAME+1];
774 
775 #if defined(DEBUG_TRACE) && defined(METAWARE)
776    ECPT_TRACE_ENTRY   *trace = NULL;
777    ECPT_TRACE( trace, GetCluster );
778 #endif
779 
780    strncpy( sClusterFile, sFullProfileDir, KMS_MAX_FILE_NAME );
781    sClusterFile[KMS_MAX_FILE_NAME] = '\0';
782    strncat( sClusterFile, PROFILE_CLUSTER_CONFIG_FILE, KMS_MAX_FILE_NAME );
783 
784    fp = fopen( sClusterFile, "r" );
785 
786    if ( fp == NULL )
787    {
788 #ifdef METAWARE
789       // Assume file doesn't exist.  This isn't an error (no support for
790       // errno in metaware).
791       o_bClusterInformationFound = 0;
792       return true;
793 #else
794       if ( errno == ENOENT )
795       {
796          // File doesn't exist.  This isn't an error.
797          o_bClusterInformationFound = 0;
798          return true;
799       }
800 
801       LogError(io_pProfile,
802                AUDIT_CLIENT_LOAD_CLUSTER_INFORMATION_OPEN_CLUSTER_FILE_FAILED,
803                NULL,
804                NULL,
805                sClusterFile );
806       return false;
807 #endif
808    }
809 
810 #ifdef K_SOLARIS_PLATFORM
811    int fd = fileno(fp);
812    (void) flock_fd(fd, F_WRLCK, &clusterfl, &cluster_mutex);
813 #endif
814 
815    o_bClusterInformationFound = 1;
816    int i;
817    // KMAVersion is new to Cluster config with 2.1 KMS and will not exist
818    // in persisted cluster configs from earlier agents
819    for ( i = 0; i < KMS_MAX_CLUSTER_NUM; i++ )
820    {
821         io_pProfile->m_aCluster[i].m_sKMAVersion[0] = '\0';
822    }
823 
824    int iClusterNum = 0;
825    // read file one line by one line
826    while(1)
827    {
828       int i;
829       char *pName, *pValue;
830 
831       memset(acBuffer, 0, iMaxLineSize+1);
832 
833       // get info from the file
834       if(fgets(acBuffer, iMaxLineSize+1, fp) == NULL)
835          break;
836 
837       if(strlen(acBuffer) < 3)
838          continue;
839 
840       if(acBuffer[0] == '#' ||
841          acBuffer[0] == ';' ||
842          acBuffer[0] == '[')  // jump comments
843          continue;
844 
845       pName = acBuffer; pValue = NULL;
846       for(i = 0; acBuffer[i] != '\0'; i++)
847       {
848          if(acBuffer[i] == '=')
849             pValue = acBuffer + i + 1;
850 
851          if(acBuffer[i] == '=' ||
852             acBuffer[i] == '\r' ||
853             acBuffer[i] == '\n')
854             acBuffer[i] = '\0';
855       }
856 
857       if(strcmp(pName, "<StartAppliance>") == 0)
858       {
859          continue;
860       }
861       if(strcmp(pName, "<EndAppliance>") == 0)
862       {
863          iClusterNum++;
864       }
865 
866       if(pValue == NULL)
867       {
868          if(strcmp(pName,"<StartAppliance>") == 0)
869             continue;
870 
871          if(strcmp(pName,"<EndAppliance>") == 0)
872             continue;
873 
874 #ifdef K_SOLARIS_PLATFORM
875 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
876 #endif
877          fclose(fp);
878 
879          LogError(io_pProfile,
880                   AUDIT_CLIENT_LOAD_CLUSTER_INFORMATION_INVALID_CLUSTER_FILE_FORMAT,
881                   NULL,
882                   NULL,
883                   sClusterFile );
884          return false;
885       }
886 
887       if(strcmp(pName, "EntitySiteID") == 0)
888       {
889          utf8cstr wsValue = pValue;
890          strncpy(io_pProfile->m_wsEntitySiteID, wsValue, KMS_MAX_ENTITY_SITE_ID);
891          io_pProfile->m_wsEntitySiteID[KMS_MAX_ENTITY_SITE_ID] = 0;
892       }
893 
894 
895       if(strcmp(pName, "ApplianceID") == 0)
896       {
897 #ifdef WIN32
898          sscanf(pValue, "%lld",
899                 &(io_pProfile->m_aCluster[iClusterNum].m_lApplianceID));
900 #else
901          sscanf(pValue, "%lld",
902                 &(io_pProfile->m_aCluster[iClusterNum].m_lApplianceID));
903 #endif
904       }
905       if(strcmp(pName, "Enabled") == 0)
906       {
907          sscanf(pValue, "%d",
908                 &(io_pProfile->m_aCluster[iClusterNum].m_iEnabled));
909       }
910 
911       // assume it is responding by default
912       io_pProfile->m_aCluster[iClusterNum].
913          m_iResponding = TRUE;
914 
915       if(strcmp(pName, "Load") == 0)
916       {
917          sscanf(pValue, "%lld",
918                 &(io_pProfile->m_aCluster[iClusterNum].m_lLoad));
919       }
920       if(strcmp(pName, "ApplianceAlias") == 0)
921       {
922          utf8cstr wsValue = pValue;
923          strncpy(io_pProfile->m_aCluster[iClusterNum].m_wsApplianceAlias,
924                  wsValue,
925                  KMS_MAX_ENTITY_ID);
926          io_pProfile->m_aCluster[iClusterNum].
927             m_wsApplianceAlias[KMS_MAX_ENTITY_ID] = 0;
928 
929       }
930       if(strcmp(pName, "ApplianceNetworkAddress") == 0)
931       {
932          utf8cstr wsValue = pValue;
933          strncpy(io_pProfile->m_aCluster[iClusterNum].
934                  m_wsApplianceNetworkAddress,
935                  wsValue,
936                  KMS_MAX_NETWORK_ADDRESS);
937          io_pProfile->m_aCluster[iClusterNum].
938             m_wsApplianceNetworkAddress[KMS_MAX_NETWORK_ADDRESS] = 0;
939       }
940       if(strcmp(pName, "ApplianceSiteID") == 0)
941       {
942          utf8cstr wsValue = pValue;
943          strncpy(io_pProfile->m_aCluster[iClusterNum].m_wsApplianceSiteID,
944                  wsValue,
945                  KMS_MAX_ENTITY_SITE_ID);
946          io_pProfile->m_aCluster[iClusterNum].
947             m_wsApplianceSiteID[KMS_MAX_ENTITY_SITE_ID] = 0;
948       }
949       if(strcmp(pName, "KMAVersion") == 0)
950       {
951          utf8cstr wsValue = pValue;
952          strncpy(io_pProfile->m_aCluster[iClusterNum].m_sKMAVersion,
953                  wsValue,
954                  KMS_MAX_VERSION_LENGTH);
955          io_pProfile->m_aCluster[iClusterNum].
956             m_sKMAVersion[KMS_MAX_VERSION_LENGTH] = '\0';
957       }
958       if(strcmp(pName, "KMALocked") == 0)
959       {
960          sscanf(pValue, "%d",
961             &(io_pProfile->m_aCluster[iClusterNum].m_iKMALocked));
962       }
963    }
964    io_pProfile->m_iClusterNum = iClusterNum;
965 
966 #ifdef K_SOLARIS_PLATFORM
967 	(void) flock_fd(fd, F_UNLCK, &clusterfl, &cluster_mutex);
968 #endif
969    fclose(fp);
970 
971    return true;
972 }
973 
974 /*! DeleteCluster
975  *
976  */
DeleteCluster(KMSClientProfile * const io_pProfile)977 bool DeleteCluster( KMSClientProfile* const io_pProfile )
978 {
979    FATAL_ASSERT( io_pProfile );
980    FATAL_ASSERT( io_pProfile->m_wsProfileName );
981 
982 #if defined(DEBUG_TRACE) && defined(METAWARE)
983    ECPT_TRACE_ENTRY   *trace = NULL;
984    ECPT_TRACE( trace, DeleteCluster );
985 #endif
986 
987    bool bSuccess = true;
988    char sFullProfileDir[KMS_MAX_FILE_NAME];
989    char sClusterInformationFile[KMS_MAX_FILE_NAME];
990 
991    BuildFullProfilePathWithName( sFullProfileDir, g_sWorkingDirectory,
992                                  io_pProfile->m_wsProfileName );
993 
994    strcpy( sClusterInformationFile, sFullProfileDir );
995    strncat( sClusterInformationFile, PROFILE_CLUSTER_CONFIG_FILE,
996             KMS_MAX_FILE_NAME );
997 
998    myFILE* pfFile = fopen( sClusterInformationFile, "rb" );
999 
1000    if ( pfFile != NULL )
1001    {
1002       fclose(pfFile);
1003       if ( my_unlink(sClusterInformationFile) )
1004          bSuccess = false;
1005    }
1006 
1007    return true;
1008 }
1009 
1010 /*! StoreCACertificate
1011  *  Store CA Certificate to a persistent storage file
1012  *  @param i_pProfile
1013  *  @param i_pCACertificate
1014  *
1015  *  @returns     boolean success or failure
1016  */
StoreCACertificate(KMSClientProfile * const i_pProfile,CCertificate * const i_pCACertificate)1017 bool StoreCACertificate(
1018    KMSClientProfile* const i_pProfile,
1019    CCertificate* const     i_pCACertificate )
1020 {
1021    FATAL_ASSERT( i_pProfile );
1022    FATAL_ASSERT( i_pCACertificate );
1023 
1024    char sCACertificateFile[KMS_MAX_FILE_NAME];
1025 
1026 #if defined(DEBUG_TRACE) && defined(METAWARE)
1027    ECPT_TRACE_ENTRY   *trace = NULL;
1028    ECPT_TRACE( trace, StoreCACertificate );
1029 #endif
1030 
1031    BuildFullProfilePath( sCACertificateFile,
1032                          g_sWorkingDirectory,
1033                          i_pProfile->m_wsProfileName );
1034 
1035    strncat( sCACertificateFile, CA_CERTIFICATE_FILE, KMS_MAX_FILE_NAME );
1036 
1037    // OVERLOADED Save method - 2 parameters means save to a file
1038    if ( !( i_pCACertificate->Save(sCACertificateFile, PKI_FORMAT)) )
1039    {
1040       LogError(i_pProfile,
1041                AUDIT_CLIENT_LOAD_PROFILE_SAVE_CA_CERTIFICATE_FAILED,
1042                NULL,
1043                NULL,
1044                sCACertificateFile );
1045       return false;
1046    }
1047    return true;
1048 
1049 }
1050 
1051 /*! StoreAgentPKI
1052  *  Store Private Keys a persistent storage file
1053  *
1054  */
1055 #ifndef K_SOLARIS_PLATFORM
1056 static
1057 #endif
StoreAgentPKI(KMSClientProfile * const i_pProfile,CCertificate * const i_pAgentCertificate,CPrivateKey * const i_pAgentPrivateKey,const char * const i_sHexHashedPassphrase)1058 bool StoreAgentPKI(
1059    KMSClientProfile* const i_pProfile,
1060    CCertificate* const     i_pAgentCertificate,
1061    CPrivateKey* const      i_pAgentPrivateKey,
1062    const char* const       i_sHexHashedPassphrase )
1063 {
1064    FATAL_ASSERT( i_pProfile );
1065    FATAL_ASSERT( i_pAgentCertificate );
1066 
1067    bool bSuccess;
1068    char sClientKeyFile[KMS_MAX_FILE_NAME];
1069 
1070 #if defined(DEBUG_TRACE) && defined(METAWARE)
1071    ECPT_TRACE_ENTRY   *trace = NULL;
1072    ECPT_TRACE( trace, StoreAgentPKI ) ;
1073 #endif
1074 
1075    BuildFullProfilePath( sClientKeyFile,
1076          g_sWorkingDirectory,
1077          i_pProfile->m_wsProfileName );
1078 
1079    strncat( sClientKeyFile,
1080 #ifdef KMSUSERPKCS12
1081    	CLIENT_PK12_FILE,
1082 #else
1083             CLIENT_KEY_FILE,
1084 #endif
1085             KMS_MAX_FILE_NAME );
1086 
1087    CPKI oPKI;
1088 
1089    // save Certificate and Private Key to file named sClientKeyFile(CLIENT_KEY_FILE)
1090    bSuccess = oPKI.ExportCertAndKeyToFile(
1091       i_pAgentCertificate,
1092       i_pAgentPrivateKey,
1093       sClientKeyFile,
1094       i_sHexHashedPassphrase,
1095 #ifdef KMSUSERPKCS12
1096       PKCS12_FORMAT
1097 #else
1098       PKI_FORMAT
1099 #endif
1100       );
1101 
1102    if ( !bSuccess )
1103    {
1104       LogError(i_pProfile,
1105                AUDIT_CLIENT_LOAD_PROFILE_EXPORT_CERTIFICATE_AND_KEY_FAILED,
1106                NULL,
1107                NULL,
1108                sClientKeyFile );
1109    }
1110    return bSuccess;
1111 }
1112 
1113 /*! StorePKIcerts
1114  * Store PKI objects to persistent storage files
1115  */
StorePKIcerts(KMSClientProfile * const io_pProfile,CCertificate * const i_pCACertificate,CCertificate * const i_pAgentCertificate,CPrivateKey * const i_pAgentPrivateKey,const char * const i_sHexHashedPassphrase)1116 bool StorePKIcerts(
1117    KMSClientProfile* const     io_pProfile,
1118    CCertificate* const         i_pCACertificate,
1119    CCertificate* const         i_pAgentCertificate,
1120    CPrivateKey* const          i_pAgentPrivateKey,
1121    const char* const           i_sHexHashedPassphrase )
1122 {
1123    FATAL_ASSERT( io_pProfile );
1124    FATAL_ASSERT( i_pAgentCertificate );
1125 
1126    bool bSuccess = false;
1127 
1128    bSuccess = StoreCACertificate( io_pProfile, i_pCACertificate );
1129 
1130    if ( bSuccess )
1131    {
1132       bSuccess = StoreAgentPKI( io_pProfile,
1133                                 i_pAgentCertificate,
1134                                 i_pAgentPrivateKey,
1135                                 i_sHexHashedPassphrase );
1136    }
1137 
1138    if ( bSuccess )
1139    {
1140        io_pProfile->m_iEnrolled = TRUE;
1141    }
1142 
1143    return bSuccess;
1144 }
1145 
1146 #ifdef KMSUSERPKCS12
1147 
1148 /*
1149  * Test to see if the PKCS12 file exists.
1150  */
ClientKeyP12Exists(char * profileName)1151 bool ClientKeyP12Exists(char *profileName)
1152 {
1153 	bool bSuccess = true;
1154 	char sFullProfileDir[KMS_MAX_FILE_NAME+1];
1155 	char sAgentPK12File[KMS_MAX_FILE_NAME+1];
1156 	struct stat statp;
1157 
1158 	BuildFullProfilePath(sFullProfileDir,
1159 	    g_sWorkingDirectory, profileName);
1160 
1161 	strncpy( sAgentPK12File, sFullProfileDir, KMS_MAX_FILE_NAME );
1162 	strncat( sAgentPK12File, CLIENT_PK12_FILE, KMS_MAX_FILE_NAME );
1163 
1164 	bSuccess = false;
1165 	if (stat(sAgentPK12File, &statp) == -1)
1166 		bSuccess = false;
1167 	else if (statp.st_size > 0)
1168 		bSuccess = true;
1169 
1170 	return (bSuccess);
1171 }
1172 
1173 /*
1174  * Load the cert and the private key from the PKCS12 file.
1175  */
GetPKCS12CertAndKey(KMSClientProfile * const io_pProfile,utf8char * i_pPassphrase,CCertificate * i_pEntityCert,CPrivateKey * i_pEntityPrivateKey)1176 bool GetPKCS12CertAndKey(
1177 	KMSClientProfile* const io_pProfile,
1178 	utf8char	*i_pPassphrase,
1179 	CCertificate	*i_pEntityCert,
1180 	CPrivateKey	*i_pEntityPrivateKey)
1181 {
1182 	bool bSuccess = true;
1183 	char sFullProfileDir[KMS_MAX_FILE_NAME+1];
1184 	char sAgentPK12File[KMS_MAX_FILE_NAME+1];
1185 
1186 	BuildFullProfilePath(sFullProfileDir,
1187 	    g_sWorkingDirectory, io_pProfile->m_wsProfileName );
1188 
1189 	strncpy( sAgentPK12File, sFullProfileDir, KMS_MAX_FILE_NAME );
1190 	strncat( sAgentPK12File, CLIENT_PK12_FILE, KMS_MAX_FILE_NAME );
1191 
1192 	bSuccess = i_pEntityCert->LoadPKCS12CertAndKey(
1193 	    sAgentPK12File, FILE_FORMAT_PKCS12,
1194 	    i_pEntityPrivateKey, i_pPassphrase);
1195 
1196 	if (!bSuccess)
1197 		io_pProfile->m_iLastErrorCode = KMS_AGENT_LOCAL_AUTH_FAILURE;
1198 
1199 	return (bSuccess);
1200 }
1201 
StoreTempAgentPKI(KMSClientProfile * const i_pProfile,CCertificate * i_pAgentCertificate,CPrivateKey * i_pAgentPrivateKey)1202 bool StoreTempAgentPKI(
1203    KMSClientProfile* const i_pProfile,
1204    CCertificate* i_pAgentCertificate,
1205    CPrivateKey* i_pAgentPrivateKey)
1206 {
1207    FATAL_ASSERT( i_pProfile );
1208    FATAL_ASSERT( i_pAgentCertificate );
1209 
1210    bool bSuccess;
1211    char sClientKeyFile[KMS_MAX_FILE_NAME];
1212 
1213    BuildFullProfilePath( sClientKeyFile,
1214                          g_sWorkingDirectory,
1215                          i_pProfile->m_wsProfileName );
1216 
1217    strncat(sClientKeyFile,
1218            CLIENT_KEY_FILE,
1219            KMS_MAX_FILE_NAME );
1220 
1221    CPKI oPKI;
1222 
1223    // save Certificate and Private Key to file named sClientKeyFile(CLIENT_KEY_FILE)
1224    bSuccess = oPKI.ExportCertAndKeyToFile(
1225       i_pAgentCertificate,
1226       i_pAgentPrivateKey,
1227       sClientKeyFile,
1228       NULL,
1229       PKI_FORMAT);
1230 
1231    if ( !bSuccess )
1232    {
1233       LogError(i_pProfile,
1234                AUDIT_CLIENT_LOAD_PROFILE_EXPORT_CERTIFICATE_AND_KEY_FAILED,
1235                NULL,
1236                NULL,
1237                sClientKeyFile );
1238    }
1239    return bSuccess;
1240 }
1241 
CleanupPrivateKeyFile(KMSClientProfile * const io_pProfile)1242 void CleanupPrivateKeyFile(KMSClientProfile* const io_pProfile)
1243 {
1244    char sClientKeyFile[KMS_MAX_FILE_NAME];
1245 
1246    BuildFullProfilePath( sClientKeyFile,
1247                          g_sWorkingDirectory,
1248                          io_pProfile->m_wsProfileName );
1249 
1250    strncat(sClientKeyFile,
1251            CLIENT_KEY_FILE,
1252            KMS_MAX_FILE_NAME );
1253 
1254    (void) unlink(sClientKeyFile);
1255    return;
1256 }
1257 #endif /* PKCS12 */
1258 
1259 /**
1260  *  GetPKIcerts verifies that CA and Agent certificates are available in
1261  *  persistent storage and updates profile with an indicator
1262  */
GetPKIcerts(KMSClientProfile * const io_pProfile)1263 bool GetPKIcerts(
1264    KMSClientProfile* const     io_pProfile )
1265 {
1266    FATAL_ASSERT( io_pProfile );
1267 
1268    bool bSuccess = true;
1269    char sFullProfileDir[KMS_MAX_FILE_NAME+1];
1270    char sCAcertFile[KMS_MAX_FILE_NAME+1];
1271    char sAgentCertFile[KMS_MAX_FILE_NAME+1];
1272 #ifndef K_SOLARIS_PLATFORM
1273    myFILE* pfFile;
1274 #endif
1275 
1276 #if defined(DEBUG_TRACE) && defined(METAWARE)
1277    ECPT_TRACE_ENTRY   *trace = NULL;
1278    ECPT_TRACE( trace, GetPKIcerts );
1279 #endif
1280 
1281   io_pProfile->m_iEnrolled = FALSE;
1282 
1283    BuildFullProfilePath( sFullProfileDir,
1284        g_sWorkingDirectory, io_pProfile->m_wsProfileName );
1285 
1286    strncpy( sCAcertFile, sFullProfileDir, KMS_MAX_FILE_NAME );
1287    sCAcertFile[KMS_MAX_FILE_NAME] = '\0';
1288    strncat( sCAcertFile, CA_CERTIFICATE_FILE, KMS_MAX_FILE_NAME );
1289 
1290 #ifdef K_SOLARIS_PLATFORM
1291 	/*
1292 	 * stat(2) is preferred over fopen(3C)
1293 	 * fopen for checking if a file is present.
1294 	 */
1295 	struct stat statp;
1296 	if (stat(sCAcertFile, &statp)) {
1297 		LogError(io_pProfile,
1298 			AUDIT_CLIENT_LOAD_PROFILE_FAILED,
1299 			NULL,
1300 			NULL,
1301 			"Test for presence of CA Certificate failed" );
1302 		return false;
1303 	}
1304 
1305 #else
1306    pfFile = fopen( sCAcertFile, "rb" );
1307 
1308    if ( pfFile != NULL )
1309    {
1310       fclose(pfFile);
1311    }
1312    else
1313    {
1314       LogError(io_pProfile,
1315                AUDIT_CLIENT_LOAD_PROFILE_FAILED,
1316                NULL,
1317                NULL,
1318                "Test for presence of CA Certificate failed" );
1319       return false;
1320    }
1321 #endif
1322 
1323    // open the file containing client certificate and private key
1324    // checking if the file exists.
1325    strncpy( sAgentCertFile, sFullProfileDir, KMS_MAX_FILE_NAME );
1326    sAgentCertFile[KMS_MAX_FILE_NAME] = '\0';
1327    strncat( sAgentCertFile, CLIENT_KEY_FILE, KMS_MAX_FILE_NAME );
1328 
1329 #ifdef K_SOLARIS_PLATFORM
1330 	/*
1331 	 * stat(2) is safer than "fopen" for checking if a file is
1332 	 * present or not.
1333 	 */
1334 	if (stat(sAgentCertFile, &statp)) {
1335 		LogError(io_pProfile,
1336 			AUDIT_CLIENT_LOAD_PROFILE_FAILED,
1337 			NULL,
1338 			NULL,
1339 			"Test for presence of Agent Certificate failed" );
1340 		return false;
1341 	}
1342 #else
1343 
1344    pfFile = fopen( sAgentCertFile, "rb" );
1345 
1346    if ( pfFile != NULL )
1347    {
1348       fclose(pfFile);
1349    }
1350    else
1351    {
1352       LogError(io_pProfile,
1353                AUDIT_CLIENT_LOAD_PROFILE_FAILED,
1354                NULL,
1355                NULL,
1356                "Test for presence of Agent Certificate failed" );
1357       return false;
1358    }
1359 #endif
1360 
1361    io_pProfile->m_iEnrolled = TRUE;
1362 
1363    return bSuccess;
1364 }
1365 
1366 /**
1367  * DeleteStorageProfile
1368  */
DeleteStorageProfile(const char * const i_pName)1369 bool DeleteStorageProfile(
1370    const char* const i_pName)
1371 {
1372    FATAL_ASSERT( i_pName );
1373 
1374 #if defined(DEBUG_TRACE) && defined(METAWARE)
1375    ECPT_TRACE_ENTRY   *trace = NULL;
1376    ECPT_TRACE( trace, DeleteStorageProfile );
1377 #endif
1378 
1379    bool bSuccess = true;
1380    char sFullProfileDir[KMS_MAX_FILE_NAME+1];
1381    char sConfigFile[KMS_MAX_FILE_NAME+1];
1382    char sClusterInformationFile[KMS_MAX_FILE_NAME+1];
1383    char sCACertificateFile[KMS_MAX_FILE_NAME+1];
1384    char sClientKeyFile[KMS_MAX_FILE_NAME+1];
1385 #ifdef KMSUSERPKCS12
1386    char sClientP12File[KMS_MAX_FILE_NAME+1];
1387 #endif
1388 
1389    BuildFullProfilePathWithName( sFullProfileDir,
1390                                  g_sWorkingDirectory, i_pName );
1391    strncpy( sConfigFile, sFullProfileDir, KMS_MAX_FILE_NAME );
1392    sConfigFile[KMS_MAX_FILE_NAME] = '\0';
1393    strncat( sConfigFile, PROFILE_CONFIG_FILE, KMS_MAX_FILE_NAME );
1394 
1395    strncpy( sClusterInformationFile, sFullProfileDir, KMS_MAX_FILE_NAME );
1396    sClusterInformationFile[KMS_MAX_FILE_NAME] = '\0';
1397    strncat( sClusterInformationFile,
1398             PROFILE_CLUSTER_CONFIG_FILE,
1399             KMS_MAX_FILE_NAME );
1400 
1401    strncpy( sCACertificateFile, sFullProfileDir, KMS_MAX_FILE_NAME );
1402    sCACertificateFile[KMS_MAX_FILE_NAME] = '\0';
1403    strncat( sCACertificateFile, CA_CERTIFICATE_FILE, KMS_MAX_FILE_NAME );
1404 
1405    strncpy( sClientKeyFile, sFullProfileDir, KMS_MAX_FILE_NAME );
1406    sClientKeyFile[KMS_MAX_FILE_NAME] = '\0';
1407    strncat( sClientKeyFile, CLIENT_KEY_FILE, KMS_MAX_FILE_NAME );
1408 
1409    myFILE* pfFile = fopen( sConfigFile, "rb" );
1410 
1411    if ( pfFile != NULL )
1412    {
1413       fclose(pfFile);
1414       if ( my_unlink(sConfigFile) )
1415          bSuccess = false;
1416    }
1417 
1418    pfFile = fopen( sClusterInformationFile, "rb" );
1419 
1420    if ( pfFile != NULL )
1421    {
1422       fclose(pfFile);
1423       if ( my_unlink(sClusterInformationFile) )
1424          bSuccess = false;
1425    }
1426 
1427    pfFile = fopen( sCACertificateFile, "rb" );
1428 
1429    if ( pfFile != NULL )
1430    {
1431       fclose(pfFile);
1432       if ( my_unlink(sCACertificateFile) )
1433          bSuccess = false;
1434    }
1435 
1436    pfFile = fopen( sClientKeyFile, "rb" );
1437 
1438    if ( pfFile != NULL )
1439    {
1440       fclose(pfFile);
1441       if ( my_unlink(sClientKeyFile) )
1442          bSuccess = false;
1443    }
1444 
1445 #ifdef KMSUSERPKCS12
1446    strncpy( sClientP12File, sFullProfileDir, KMS_MAX_FILE_NAME );
1447    sClientP12File[KMS_MAX_FILE_NAME] = '\0';
1448    strncat( sClientP12File, CLIENT_KEY_FILE, KMS_MAX_FILE_NAME );
1449 
1450    /* Just unlink, no need to open/close first. */
1451    if ( my_unlink(sClientP12File) )
1452          bSuccess = false;
1453 #endif
1454 
1455    pfFile = fopen( sFullProfileDir, "rb" );
1456 
1457    if ( pfFile != NULL )
1458    {
1459       fclose(pfFile);
1460       if ( my_rmdir(sFullProfileDir) )
1461          bSuccess = false;
1462    }
1463 
1464    return bSuccess;
1465 }
1466 
1467 
1468 
1469 
1470 /**
1471  * K_soap_ssl_client_context
1472  * Parse client context and send to soap, either using a soap call
1473  *  for openSSL or user implemented call for Treck SSL
1474  *
1475  * @param i_pProfile     - pointer to KMSClientProfile
1476  * @param io_pSoap       - pointer to soap structure
1477  * @param i_iFlags       - input flags (CLIENT or SERVER auth)
1478  *
1479  * @returns 0=success, non-zero=fail
1480  */
K_soap_ssl_client_context(KMSClientProfile * const i_pProfile,struct soap * io_pSoap,unsigned short i_iFlags)1481 int K_soap_ssl_client_context
1482 (  KMSClientProfile* const   i_pProfile,  // input KMSClientProfile
1483    struct soap *             io_pSoap,    // i/o soap profile
1484    unsigned short            i_iFlags )   // input flags
1485 {
1486    FATAL_ASSERT( i_pProfile );
1487    FATAL_ASSERT( io_pSoap );
1488 
1489 #if defined(DEBUG_TRACE) && defined(METAWARE)
1490    ECPT_TRACE_ENTRY   *trace = NULL;
1491    ECPT_TRACE( trace, K_soap_ssl_client_context ) ;
1492 #endif
1493 
1494 
1495    char sCACertificateFile[KMS_MAX_FILE_NAME];
1496    char sClientKeyFile[KMS_MAX_FILE_NAME];
1497 
1498 
1499    BuildFullProfilePath( sCACertificateFile,            // out
1500                          g_sWorkingDirectory,           // out
1501                          i_pProfile->m_wsProfileName ); // in
1502 
1503    strncat( sCACertificateFile,   // path
1504             CA_CERTIFICATE_FILE,  // name
1505             KMS_MAX_FILE_NAME );
1506 
1507 
1508    switch ( i_iFlags )
1509    {
1510       case SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION:
1511       {
1512          BuildFullProfilePath( sClientKeyFile,
1513                                g_sWorkingDirectory,
1514                                i_pProfile->m_wsProfileName );
1515 
1516          strncat( sClientKeyFile,      // path
1517                   CLIENT_KEY_FILE,     // name
1518                   KMS_MAX_FILE_NAME );
1519 
1520          // this sends the following to the SSL Layer
1521 #ifdef METAWARE
1522          return K_ssl_client_context(
1523             io_pSoap,                           // i/o
1524             i_iFlags,                           // flags
1525             sClientKeyFile,                     // keyfile - client cert and private key
1526             i_pProfile->m_sHexHashedPassphrase, // password
1527             sCACertificateFile,                 // cafile - CA certificate
1528             NULL,                               // capath
1529             NULL );                             // randfile
1530 #else
1531          return soap_ssl_client_context(
1532             io_pSoap,                           // i/o
1533 #ifndef SOAP_SSL_SKIP_HOST_CHECK
1534             i_iFlags,                           // flags
1535 #else
1536             i_iFlags | SOAP_SSL_SKIP_HOST_CHECK, // flags
1537 #endif
1538             sClientKeyFile,                     // keyfile - client cert and private key
1539             i_pProfile->m_sHexHashedPassphrase, // password
1540             sCACertificateFile,                 // cafile - CA certificate
1541             NULL,                               // capath
1542             NULL );                             // randfile
1543 #endif
1544       }
1545       case SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION:
1546       {
1547 #ifdef METAWARE
1548          return K_ssl_client_context(
1549             io_pSoap,                           // i/o
1550             i_iFlags,                           // flags
1551             NULL,                               // keyfile
1552             NULL,                               // password
1553             sCACertificateFile,                 // cafile
1554             NULL,                               // capath
1555             NULL );                             // randfile
1556 #else
1557          return soap_ssl_client_context(
1558             io_pSoap,                           // i/o
1559 #ifndef SOAP_SSL_SKIP_HOST_CHECK
1560             i_iFlags,                           // flags
1561 #else
1562             i_iFlags | SOAP_SSL_SKIP_HOST_CHECK, // flags
1563 #endif
1564             NULL,                               // keyfile
1565             NULL,                               // password
1566             sCACertificateFile,                 // cafile
1567             NULL,                               // capath
1568             NULL );                             // randfile
1569 #endif
1570       }
1571       default:
1572          // unauthenticated sessions are not supported
1573          return 1;
1574    }
1575 }
1576