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.
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.
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]
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
27 * \file KMSAgentStorage.cpp
28 * This file provides an implementation of the KMSAgentStorage.h
29 * interface utilizing a filesystem for storage of KMS Client
32 * For storage of Certificates and Private key material the PKICommon
43 #ifdef K_SOLARIS_PLATFORM
45 #include <cryptoutil.h>
53 #include "KMSClientProfile.h" // must be before agentstorage
54 #include "KMSAgentPKICommon.h" // must be before agentstorage
55 #include "KMSAgentStorage.h"
57 #include "SYSCommon.h"
58 #include "AutoMutex.h"
59 #include "KMSAuditLogger.h"
60 #include "KMSClientProfileImpl.h"
62 #include "KMSAgent_direct.h"
63 #ifdef K_SOLARIS_PLATFORM
66 #include "k_setupssl.h" // K_ssl_client_context
69 extern "C" int K_ssl_client_context(struct soap
*soap
,
71 const char *keyfile
, // NULL - SERVER
72 const char *password
, // NULL - SERVER
74 const char *capath
, // ALWAYS NULL
75 const char *randfile
); // ALWAYS NULL
80 #define CA_CERTIFICATE_FILE "ca.crt"
81 #define CLIENT_KEY_FILE "clientkey.pem"
83 #define PROFILE_CONFIG_FILE "profile.cfg"
84 #define PROFILE_CLUSTER_CONFIG_FILE "cluster.cfg"
86 static char g_sWorkingDirectory
[KMS_MAX_PATH_LENGTH
+1];
87 static char g_sStringbuf
[10000]; // too large to be on the 9840D stack
89 static void BuildFullProfilePathWithName(utf8cstr o_pProfilePath
,
90 const char* const i_pWorkingDirectory
,
91 const char* const i_pProfileName
)
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) );
100 #if defined(DEBUG_TRACE) && defined(METAWARE)
101 ECPT_TRACE_ENTRY
*trace
= NULL
;
102 ECPT_TRACE( trace
, BuildFullProfilePathWithName
);
105 strncpy(o_pProfilePath
, i_pWorkingDirectory
,
108 if ( o_pProfilePath
[ strlen(o_pProfilePath
) -1 ] != PATH_SEPARATOR
)
110 len
= strlen(o_pProfilePath
);
111 o_pProfilePath
[ len
] = PATH_SEPARATOR
;
112 o_pProfilePath
[ len
+ 1 ] = '\0';
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';
123 static void BuildFullProfilePath(utf8cstr o_sProfilePath
,
124 const char* const i_pWorkingDirectory
,
125 const char* const i_pProfileName
)
127 FATAL_ASSERT( o_sProfilePath
);
128 FATAL_ASSERT( i_pWorkingDirectory
);
129 FATAL_ASSERT( i_pProfileName
);
130 FATAL_ASSERT( (strlen(i_pProfileName
) > 0) );
132 BuildFullProfilePathWithName( o_sProfilePath
,
139 #ifdef K_SOLARIS_PLATFORM
140 static struct flock cfgfl
= {
144 static struct flock clusterfl
= {
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
;
154 flock_fd(int fd
, int cmd
, struct flock
*fl
, pthread_mutex_t
*mutex
)
158 (void) pthread_mutex_lock(mutex
);
162 while ((ret
= fcntl(fd
, F_SETLKW
, fl
)) == -1) {
166 (void) pthread_mutex_unlock(mutex
);
172 static bool Profile_WriteConfigFile(KMSClientProfile
*i_pProfile
,
173 const char *i_pFileName
)
175 FATAL_ASSERT( i_pProfile
);
176 FATAL_ASSERT( i_pFileName
);
178 CAutoMutex
oAutoMutex( (K_MUTEX_HANDLE
)i_pProfile
->m_pLock
);
180 #if defined(DEBUG_TRACE) && defined(METAWARE)
181 ECPT_TRACE_ENTRY
*trace
= NULL
;
182 ECPT_TRACE( trace
, Profile_WriteConfigFile
);
185 char *sp
= g_sStringbuf
;
186 size_t bytesWritten
= 0;
188 // save config parameters
190 myFILE
*fp
= fopen(i_pFileName
, "w");
194 AUDIT_PROFILE_WRITE_CONFIG_FILE_OPEN_CONFIGURATION_FILE_FAILED
,
202 #ifdef K_SOLARIS_PLATFORM
204 (void) flock_fd(fd
, F_WRLCK
, &cfgfl
, &cfg_mutex
);
207 const char* const sProfileName
= i_pProfile
->m_wsProfileName
;
209 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "ProfileName=%s\n", sProfileName
);
211 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "AgentID=%s\n", i_pProfile
->m_wsEntityID
);
213 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "ClusterDiscoveryFrequency=%d\n",
214 i_pProfile
->m_iClusterDiscoveryFrequency
);
216 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "CAServicePortNumber=%d\n",
217 i_pProfile
->m_iPortForCAService
);
219 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "CertificateServicePortNumber=%d\n",
220 i_pProfile
->m_iPortForCertificateService
);
222 if(i_pProfile
->m_iPortForAgentService
!= 0)
224 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "AgentServicePortNumber=%d\n",
225 i_pProfile
->m_iPortForAgentService
);
228 if(i_pProfile
->m_iPortForDiscoveryService
!= 0)
230 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "DiscoveryServicePortNumber=%d\n",
231 i_pProfile
->m_iPortForDiscoveryService
);
234 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "ApplianceAddress=%s\n", i_pProfile
->m_wsApplianceAddress
);
236 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "Timeout=%d\n", i_pProfile
->m_iTransactionTimeout
);
238 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "FailoverLimt=%d\n", i_pProfile
->m_iFailoverLimit
);
240 sp
+= K_snprintf(sp
, sizeof(i_pProfile
->m_wsProfileName
), "HexHashedPassphrase=%s\n", i_pProfile
->m_sHexHashedPassphrase
);
242 bytesWritten
= fputs(g_sStringbuf
, fp
);
244 #ifdef K_SOLARIS_PLATFORM
245 (void) flock_fd(fd
, F_UNLCK
, &cfgfl
, &cfg_mutex
);
249 if ( strlen(g_sStringbuf
) != bytesWritten
)
251 if ( bytesWritten
< 0 )
262 static bool Profile_ReadConfigFile
263 ( KMSClientProfile
*i_pProfile
,
264 const char *i_pFileName
)
266 FATAL_ASSERT( i_pProfile
);
267 FATAL_ASSERT( i_pFileName
);
269 #if defined(DEBUG_TRACE) && defined(METAWARE)
270 ECPT_TRACE_ENTRY
*trace
= NULL
;
271 ECPT_TRACE( trace
, Profile_ReadConfigFile
) ;
274 CAutoMutex
oAutoMutex( (K_MUTEX_HANDLE
)i_pProfile
->m_pLock
);
276 const int iMaxLineSize
= 1024;
279 char acBuffer
[iMaxLineSize
+1];
281 fp
= fopen(i_pFileName
, "r");
285 AUDIT_PROFILE_READ_CONFIG_FILE_OPEN_CONFIGURATION_FILE_FAILED
,
292 #ifdef K_SOLARIS_PLATFORM
294 (void) flock_fd(fd
, F_RDLCK
, &cfgfl
, &cfg_mutex
);
296 // read file one line by one line
300 char *pName
, *pValue
;
302 memset(acBuffer
, 0, iMaxLineSize
+1);
304 //---------------------------
305 // get info from the file
306 //---------------------------
307 if(fgets(acBuffer
, iMaxLineSize
+1, fp
) == NULL
)
310 if(strlen(acBuffer
) < 3)
313 if(acBuffer
[0] == '#' ||
314 acBuffer
[0] == ';' ||
315 acBuffer
[0] == '[') // jump comments
321 for(i
= 0; acBuffer
[i
] != '\0'; i
++)
323 if(acBuffer
[i
] == '=')
324 pValue
= acBuffer
+ i
+ 1;
326 if(acBuffer
[i
] == '=' ||
327 acBuffer
[i
] == '\r' ||
335 AUDIT_PROFILE_READ_CONFIG_FILE_INVALID_CONFIGURATION_FILE_FORMAT
,
339 #ifdef K_SOLARIS_PLATFORM
340 (void) flock_fd(fd
, F_UNLCK
, &cfgfl
, &cfg_mutex
);
346 if(strcmp(pName
, "ProfileName") == 0)
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;
353 if(strcmp(pName
, "AgentID") == 0)
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;
360 if(strcmp(pName
, "ClusterDiscoveryFrequency") == 0)
362 sscanf(pValue
, "%d", &(i_pProfile
->m_iClusterDiscoveryFrequency
));
365 if(strcmp(pName
, "CAServicePortNumber") == 0)
367 sscanf(pValue
, "%d", &(i_pProfile
->m_iPortForCAService
));
370 if(strcmp(pName
, "CertificateServicePortNumber") == 0)
372 sscanf(pValue
, "%d", &(i_pProfile
->m_iPortForCertificateService
));
375 if(strcmp(pName
, "AgentServicePortNumber") == 0)
377 sscanf(pValue
, "%d", &(i_pProfile
->m_iPortForAgentService
));
380 if(strcmp(pName
, "DiscoveryServicePortNumber") == 0)
382 sscanf(pValue
, "%d", &(i_pProfile
->m_iPortForDiscoveryService
));
385 if(strcmp(pName
, "ApplianceAddress") == 0)
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;
393 if(strcmp(pName
, "Timeout") == 0)
395 sscanf(pValue
, "%d", &(i_pProfile
->m_iTransactionTimeout
));
398 if(strcmp(pName
, "FailoverLimt") == 0)
400 sscanf(pValue
, "%d", &(i_pProfile
->m_iFailoverLimit
));
403 if(strcmp(pName
, "HexHashedPassphrase") == 0)
405 sscanf(pValue
, "%s", i_pProfile
->m_sHexHashedPassphrase
);
409 #ifdef K_SOLARIS_PLATFORM
410 (void) flock_fd(fd
, F_UNLCK
, &cfgfl
, &cfg_mutex
);
424 extern "C" bool ProfileExists(
425 const char* const i_pWorkingDirectory
,
426 const char* const i_pProfileName
)
428 FATAL_ASSERT( i_pWorkingDirectory
);
429 FATAL_ASSERT( i_pProfileName
);
431 #if defined(DEBUG_TRACE) && defined(METAWARE)
432 ECPT_TRACE_ENTRY
*trace
= NULL
;
433 ECPT_TRACE( trace
, ProfileExists
);
437 // the profile is stored in the working folder
438 strncpy( g_sWorkingDirectory
,
440 KMS_MAX_PATH_LENGTH
);
442 char sFullProfileDir
[KMS_MAX_FILE_NAME
+1];
443 BuildFullProfilePath( sFullProfileDir
,
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
);
452 // just try to open the file to test if it exists
454 bool bProfileExists
= false;
456 myFILE
* pfFile
= fopen( sConfigFile
, "rb" );
458 if ( pfFile
!= NULL
)
460 bProfileExists
= true;
465 return bProfileExists
;
473 KMSClientProfile
* const io_pProfile
,
474 const char* const i_pWorkingDirectory
,
475 const char* const i_pProfileName
)
477 FATAL_ASSERT( io_pProfile
);
478 FATAL_ASSERT( i_pWorkingDirectory
);
479 FATAL_ASSERT( i_pProfileName
);
480 FATAL_ASSERT( (strlen(i_pProfileName
) > 0) );
482 #if defined(DEBUG_TRACE) && defined(METAWARE)
483 ECPT_TRACE_ENTRY
*trace
= NULL
;
484 ECPT_TRACE( trace
, CreateProfile
);
488 bool bSuccess
= false;
489 CAutoMutex
oAutoMutex( (K_MUTEX_HANDLE
)io_pProfile
->m_pLock
);
491 char sFullProfileDir
[KMS_MAX_FILE_NAME
];
492 BuildFullProfilePath( sFullProfileDir
,
496 bSuccess
= ( K_CreateDirectory( sFullProfileDir
) == 0 );
500 Log(AUDIT_CLIENT_LOAD_PROFILE_CREATE_DIRECTORY_FAILED
,
505 strncpy( g_sWorkingDirectory
, i_pWorkingDirectory
, KMS_MAX_PATH_LENGTH
);
507 bSuccess
= StoreConfig( io_pProfile
);
510 Log(AUDIT_CLIENT_LOAD_PROFILE_CREATE_PROFILE_CONFIG_FAILED
,
517 Log(AUDIT_CLIENT_LOAD_PROFILE_CREATE_PROFILE_CONFIG_SUCCEEDED
,
528 * Store the configuration to persistent storage
531 KMSClientProfile
* const i_pProfile
)
533 FATAL_ASSERT( i_pProfile
);
535 #if defined(DEBUG_TRACE) && defined(METAWARE)
536 ECPT_TRACE_ENTRY
*trace
= NULL
;
537 ECPT_TRACE( trace
, StoreConfig
) ;
540 char sConfigFile
[KMS_MAX_FILE_NAME
];
541 BuildFullProfilePath( sConfigFile
,
542 g_sWorkingDirectory
, i_pProfile
->m_wsProfileName
);
544 strncat( sConfigFile
, PROFILE_CONFIG_FILE
, KMS_MAX_FILE_NAME
);
546 return Profile_WriteConfigFile(i_pProfile
, sConfigFile
);
550 * Store the cluster to persistent storage
553 KMSClientProfile
* const i_pProfile
)
555 FATAL_ASSERT( i_pProfile
);
559 char *sp
= g_sStringbuf
;
561 char sFullProfileDir
[KMS_MAX_FILE_NAME
+1];
562 BuildFullProfilePath( sFullProfileDir
,
563 g_sWorkingDirectory
, i_pProfile
->m_wsProfileName
);
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
);
570 #if defined(DEBUG_TRACE) && defined(METAWARE)
571 ECPT_TRACE_ENTRY
*trace
= NULL
;
572 ECPT_TRACE( trace
, StoreCluster
);
576 fp
= fopen(sClusterFile
, "w");
580 AUDIT_CLIENT_SAVE_CLUSTER_INFORMATION_OPEN_CLUSTER_FILE_FAILED
,
587 #ifdef K_SOLARIS_PLATFORM
589 (void) flock_fd(fd
, F_WRLCK
, &clusterfl
, &cluster_mutex
);
592 sp
+= K_snprintf(sp
, sizeof(g_sStringbuf
), "EntitySiteID=%s\n\n", i_pProfile
->m_wsEntitySiteID
);
594 for (int i
= 0; i
< i_pProfile
->m_iClusterNum
; i
++)
598 sp
+= K_snprintf(sp
, sizeof(g_sStringbuf
), "\n");
601 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
),"<StartAppliance>\n")) < 0 )
603 #ifdef K_SOLARIS_PLATFORM
604 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
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; }
617 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
), "ApplianceID=%lld\n",
618 i_pProfile
->m_aCluster
[i
].m_lApplianceID
)) < 0 )
620 #ifdef K_SOLARIS_PLATFORM
621 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
628 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
), "Enabled=%d\n",
629 i_pProfile
->m_aCluster
[i
].m_iEnabled
)) < 0 )
631 #ifdef K_SOLARIS_PLATFORM
632 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
638 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
), "Responding=%d\n",
639 i_pProfile
->m_aCluster
[i
].m_iResponding
)) < 0 )
641 #ifdef K_SOLARIS_PLATFORM
642 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
648 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
), "Load=%lld\n",
649 i_pProfile
->m_aCluster
[i
].m_lLoad
)) < 0 )
651 #ifdef K_SOLARIS_PLATFORM
652 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
658 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
), "ApplianceAlias=%s\n",
659 i_pProfile
->m_aCluster
[i
].m_wsApplianceAlias
)) < 0 )
661 #ifdef K_SOLARIS_PLATFORM
662 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
668 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
), "ApplianceNetworkAddress=%s\n",
669 i_pProfile
->m_aCluster
[i
].m_wsApplianceNetworkAddress
)) < 0 )
671 #ifdef K_SOLARIS_PLATFORM
672 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
678 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
), "ApplianceSiteID=%s\n",
679 i_pProfile
->m_aCluster
[i
].m_wsApplianceSiteID
)) < 0 )
681 #ifdef K_SOLARIS_PLATFORM
682 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
688 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
), "KMAVersion=%s\n",
689 i_pProfile
->m_aCluster
[i
].m_sKMAVersion
)) < 0 )
691 #ifdef K_SOLARIS_PLATFORM
692 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
698 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
), "KMALocked=%d\n",
699 i_pProfile
->m_aCluster
[i
].m_iKMALocked
)) < 0 )
701 #ifdef K_SOLARIS_PLATFORM
702 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
708 if (( sCount
= K_snprintf(sp
, sizeof(g_sStringbuf
), "<EndAppliance>\n")) < 0 )
710 #ifdef K_SOLARIS_PLATFORM
711 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
718 fputs(g_sStringbuf
, fp
);
719 #ifdef K_SOLARIS_PLATFORM
720 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
723 Log(AUDIT_CLIENT_SAVE_CLUSTER_INFORMATION_SUCCEEDED
,
732 * get the configuration file from persistent storage
735 KMSClientProfile
* const io_pProfile
)
737 FATAL_ASSERT( io_pProfile
);
738 char sFullProfileDir
[KMS_MAX_FILE_NAME
+1];
740 BuildFullProfilePath( sFullProfileDir
,
742 io_pProfile
->m_wsProfileName
);
744 char sConfigFile
[KMS_MAX_FILE_NAME
+1];
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
);
750 return Profile_ReadConfigFile( io_pProfile
, sConfigFile
);
754 * get the cluster information from persistent storage
757 KMSClientProfile
* const io_pProfile
,
758 int& o_bClusterInformationFound
)
761 FATAL_ASSERT( io_pProfile
);
763 const int iMaxLineSize
= 1024;
766 char acBuffer
[iMaxLineSize
+1];
767 char sFullProfileDir
[KMS_MAX_FILE_NAME
+1];
769 BuildFullProfilePath( sFullProfileDir
,
771 io_pProfile
->m_wsProfileName
);
773 char sClusterFile
[KMS_MAX_FILE_NAME
+1];
775 #if defined(DEBUG_TRACE) && defined(METAWARE)
776 ECPT_TRACE_ENTRY
*trace
= NULL
;
777 ECPT_TRACE( trace
, GetCluster
);
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
);
784 fp
= fopen( sClusterFile
, "r" );
789 // Assume file doesn't exist. This isn't an error (no support for
790 // errno in metaware).
791 o_bClusterInformationFound
= 0;
794 if ( errno
== ENOENT
)
796 // File doesn't exist. This isn't an error.
797 o_bClusterInformationFound
= 0;
801 LogError(io_pProfile
,
802 AUDIT_CLIENT_LOAD_CLUSTER_INFORMATION_OPEN_CLUSTER_FILE_FAILED
,
810 #ifdef K_SOLARIS_PLATFORM
812 (void) flock_fd(fd
, F_WRLCK
, &clusterfl
, &cluster_mutex
);
815 o_bClusterInformationFound
= 1;
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
++ )
821 io_pProfile
->m_aCluster
[i
].m_sKMAVersion
[0] = '\0';
825 // read file one line by one line
829 char *pName
, *pValue
;
831 memset(acBuffer
, 0, iMaxLineSize
+1);
833 // get info from the file
834 if(fgets(acBuffer
, iMaxLineSize
+1, fp
) == NULL
)
837 if(strlen(acBuffer
) < 3)
840 if(acBuffer
[0] == '#' ||
841 acBuffer
[0] == ';' ||
842 acBuffer
[0] == '[') // jump comments
845 pName
= acBuffer
; pValue
= NULL
;
846 for(i
= 0; acBuffer
[i
] != '\0'; i
++)
848 if(acBuffer
[i
] == '=')
849 pValue
= acBuffer
+ i
+ 1;
851 if(acBuffer
[i
] == '=' ||
852 acBuffer
[i
] == '\r' ||
857 if(strcmp(pName
, "<StartAppliance>") == 0)
861 if(strcmp(pName
, "<EndAppliance>") == 0)
868 if(strcmp(pName
,"<StartAppliance>") == 0)
871 if(strcmp(pName
,"<EndAppliance>") == 0)
874 #ifdef K_SOLARIS_PLATFORM
875 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
879 LogError(io_pProfile
,
880 AUDIT_CLIENT_LOAD_CLUSTER_INFORMATION_INVALID_CLUSTER_FILE_FORMAT
,
887 if(strcmp(pName
, "EntitySiteID") == 0)
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;
895 if(strcmp(pName
, "ApplianceID") == 0)
898 sscanf(pValue
, "%lld",
899 &(io_pProfile
->m_aCluster
[iClusterNum
].m_lApplianceID
));
901 sscanf(pValue
, "%lld",
902 &(io_pProfile
->m_aCluster
[iClusterNum
].m_lApplianceID
));
905 if(strcmp(pName
, "Enabled") == 0)
908 &(io_pProfile
->m_aCluster
[iClusterNum
].m_iEnabled
));
911 // assume it is responding by default
912 io_pProfile
->m_aCluster
[iClusterNum
].
913 m_iResponding
= TRUE
;
915 if(strcmp(pName
, "Load") == 0)
917 sscanf(pValue
, "%lld",
918 &(io_pProfile
->m_aCluster
[iClusterNum
].m_lLoad
));
920 if(strcmp(pName
, "ApplianceAlias") == 0)
922 utf8cstr wsValue
= pValue
;
923 strncpy(io_pProfile
->m_aCluster
[iClusterNum
].m_wsApplianceAlias
,
926 io_pProfile
->m_aCluster
[iClusterNum
].
927 m_wsApplianceAlias
[KMS_MAX_ENTITY_ID
] = 0;
930 if(strcmp(pName
, "ApplianceNetworkAddress") == 0)
932 utf8cstr wsValue
= pValue
;
933 strncpy(io_pProfile
->m_aCluster
[iClusterNum
].
934 m_wsApplianceNetworkAddress
,
936 KMS_MAX_NETWORK_ADDRESS
);
937 io_pProfile
->m_aCluster
[iClusterNum
].
938 m_wsApplianceNetworkAddress
[KMS_MAX_NETWORK_ADDRESS
] = 0;
940 if(strcmp(pName
, "ApplianceSiteID") == 0)
942 utf8cstr wsValue
= pValue
;
943 strncpy(io_pProfile
->m_aCluster
[iClusterNum
].m_wsApplianceSiteID
,
945 KMS_MAX_ENTITY_SITE_ID
);
946 io_pProfile
->m_aCluster
[iClusterNum
].
947 m_wsApplianceSiteID
[KMS_MAX_ENTITY_SITE_ID
] = 0;
949 if(strcmp(pName
, "KMAVersion") == 0)
951 utf8cstr wsValue
= pValue
;
952 strncpy(io_pProfile
->m_aCluster
[iClusterNum
].m_sKMAVersion
,
954 KMS_MAX_VERSION_LENGTH
);
955 io_pProfile
->m_aCluster
[iClusterNum
].
956 m_sKMAVersion
[KMS_MAX_VERSION_LENGTH
] = '\0';
958 if(strcmp(pName
, "KMALocked") == 0)
961 &(io_pProfile
->m_aCluster
[iClusterNum
].m_iKMALocked
));
964 io_pProfile
->m_iClusterNum
= iClusterNum
;
966 #ifdef K_SOLARIS_PLATFORM
967 (void) flock_fd(fd
, F_UNLCK
, &clusterfl
, &cluster_mutex
);
977 bool DeleteCluster( KMSClientProfile
* const io_pProfile
)
979 FATAL_ASSERT( io_pProfile
);
980 FATAL_ASSERT( io_pProfile
->m_wsProfileName
);
982 #if defined(DEBUG_TRACE) && defined(METAWARE)
983 ECPT_TRACE_ENTRY
*trace
= NULL
;
984 ECPT_TRACE( trace
, DeleteCluster
);
987 bool bSuccess
= true;
988 char sFullProfileDir
[KMS_MAX_FILE_NAME
];
989 char sClusterInformationFile
[KMS_MAX_FILE_NAME
];
991 BuildFullProfilePathWithName( sFullProfileDir
, g_sWorkingDirectory
,
992 io_pProfile
->m_wsProfileName
);
994 strcpy( sClusterInformationFile
, sFullProfileDir
);
995 strncat( sClusterInformationFile
, PROFILE_CLUSTER_CONFIG_FILE
,
998 myFILE
* pfFile
= fopen( sClusterInformationFile
, "rb" );
1000 if ( pfFile
!= NULL
)
1003 if ( my_unlink(sClusterInformationFile
) )
1010 /*! StoreCACertificate
1011 * Store CA Certificate to a persistent storage file
1013 * @param i_pCACertificate
1015 * @returns boolean success or failure
1017 bool StoreCACertificate(
1018 KMSClientProfile
* const i_pProfile
,
1019 CCertificate
* const i_pCACertificate
)
1021 FATAL_ASSERT( i_pProfile
);
1022 FATAL_ASSERT( i_pCACertificate
);
1024 char sCACertificateFile
[KMS_MAX_FILE_NAME
];
1026 #if defined(DEBUG_TRACE) && defined(METAWARE)
1027 ECPT_TRACE_ENTRY
*trace
= NULL
;
1028 ECPT_TRACE( trace
, StoreCACertificate
);
1031 BuildFullProfilePath( sCACertificateFile
,
1032 g_sWorkingDirectory
,
1033 i_pProfile
->m_wsProfileName
);
1035 strncat( sCACertificateFile
, CA_CERTIFICATE_FILE
, KMS_MAX_FILE_NAME
);
1037 // OVERLOADED Save method - 2 parameters means save to a file
1038 if ( !( i_pCACertificate
->Save(sCACertificateFile
, PKI_FORMAT
)) )
1040 LogError(i_pProfile
,
1041 AUDIT_CLIENT_LOAD_PROFILE_SAVE_CA_CERTIFICATE_FAILED
,
1044 sCACertificateFile
);
1052 * Store Private Keys a persistent storage file
1055 #ifndef K_SOLARIS_PLATFORM
1059 KMSClientProfile
* const i_pProfile
,
1060 CCertificate
* const i_pAgentCertificate
,
1061 CPrivateKey
* const i_pAgentPrivateKey
,
1062 const char* const i_sHexHashedPassphrase
)
1064 FATAL_ASSERT( i_pProfile
);
1065 FATAL_ASSERT( i_pAgentCertificate
);
1068 char sClientKeyFile
[KMS_MAX_FILE_NAME
];
1070 #if defined(DEBUG_TRACE) && defined(METAWARE)
1071 ECPT_TRACE_ENTRY
*trace
= NULL
;
1072 ECPT_TRACE( trace
, StoreAgentPKI
) ;
1075 BuildFullProfilePath( sClientKeyFile
,
1076 g_sWorkingDirectory
,
1077 i_pProfile
->m_wsProfileName
);
1079 strncat( sClientKeyFile
,
1080 #ifdef KMSUSERPKCS12
1085 KMS_MAX_FILE_NAME
);
1089 // save Certificate and Private Key to file named sClientKeyFile(CLIENT_KEY_FILE)
1090 bSuccess
= oPKI
.ExportCertAndKeyToFile(
1091 i_pAgentCertificate
,
1094 i_sHexHashedPassphrase
,
1095 #ifdef KMSUSERPKCS12
1104 LogError(i_pProfile
,
1105 AUDIT_CLIENT_LOAD_PROFILE_EXPORT_CERTIFICATE_AND_KEY_FAILED
,
1114 * Store PKI objects to persistent storage files
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
)
1123 FATAL_ASSERT( io_pProfile
);
1124 FATAL_ASSERT( i_pAgentCertificate
);
1126 bool bSuccess
= false;
1128 bSuccess
= StoreCACertificate( io_pProfile
, i_pCACertificate
);
1132 bSuccess
= StoreAgentPKI( io_pProfile
,
1133 i_pAgentCertificate
,
1135 i_sHexHashedPassphrase
);
1140 io_pProfile
->m_iEnrolled
= TRUE
;
1146 #ifdef KMSUSERPKCS12
1149 * Test to see if the PKCS12 file exists.
1151 bool ClientKeyP12Exists(char *profileName
)
1153 bool bSuccess
= true;
1154 char sFullProfileDir
[KMS_MAX_FILE_NAME
+1];
1155 char sAgentPK12File
[KMS_MAX_FILE_NAME
+1];
1158 BuildFullProfilePath(sFullProfileDir
,
1159 g_sWorkingDirectory
, profileName
);
1161 strncpy( sAgentPK12File
, sFullProfileDir
, KMS_MAX_FILE_NAME
);
1162 strncat( sAgentPK12File
, CLIENT_PK12_FILE
, KMS_MAX_FILE_NAME
);
1165 if (stat(sAgentPK12File
, &statp
) == -1)
1167 else if (statp
.st_size
> 0)
1174 * Load the cert and the private key from the PKCS12 file.
1176 bool GetPKCS12CertAndKey(
1177 KMSClientProfile
* const io_pProfile
,
1178 utf8char
*i_pPassphrase
,
1179 CCertificate
*i_pEntityCert
,
1180 CPrivateKey
*i_pEntityPrivateKey
)
1182 bool bSuccess
= true;
1183 char sFullProfileDir
[KMS_MAX_FILE_NAME
+1];
1184 char sAgentPK12File
[KMS_MAX_FILE_NAME
+1];
1186 BuildFullProfilePath(sFullProfileDir
,
1187 g_sWorkingDirectory
, io_pProfile
->m_wsProfileName
);
1189 strncpy( sAgentPK12File
, sFullProfileDir
, KMS_MAX_FILE_NAME
);
1190 strncat( sAgentPK12File
, CLIENT_PK12_FILE
, KMS_MAX_FILE_NAME
);
1192 bSuccess
= i_pEntityCert
->LoadPKCS12CertAndKey(
1193 sAgentPK12File
, FILE_FORMAT_PKCS12
,
1194 i_pEntityPrivateKey
, i_pPassphrase
);
1197 io_pProfile
->m_iLastErrorCode
= KMS_AGENT_LOCAL_AUTH_FAILURE
;
1202 bool StoreTempAgentPKI(
1203 KMSClientProfile
* const i_pProfile
,
1204 CCertificate
* i_pAgentCertificate
,
1205 CPrivateKey
* i_pAgentPrivateKey
)
1207 FATAL_ASSERT( i_pProfile
);
1208 FATAL_ASSERT( i_pAgentCertificate
);
1211 char sClientKeyFile
[KMS_MAX_FILE_NAME
];
1213 BuildFullProfilePath( sClientKeyFile
,
1214 g_sWorkingDirectory
,
1215 i_pProfile
->m_wsProfileName
);
1217 strncat(sClientKeyFile
,
1219 KMS_MAX_FILE_NAME
);
1223 // save Certificate and Private Key to file named sClientKeyFile(CLIENT_KEY_FILE)
1224 bSuccess
= oPKI
.ExportCertAndKeyToFile(
1225 i_pAgentCertificate
,
1233 LogError(i_pProfile
,
1234 AUDIT_CLIENT_LOAD_PROFILE_EXPORT_CERTIFICATE_AND_KEY_FAILED
,
1242 void CleanupPrivateKeyFile(KMSClientProfile
* const io_pProfile
)
1244 char sClientKeyFile
[KMS_MAX_FILE_NAME
];
1246 BuildFullProfilePath( sClientKeyFile
,
1247 g_sWorkingDirectory
,
1248 io_pProfile
->m_wsProfileName
);
1250 strncat(sClientKeyFile
,
1252 KMS_MAX_FILE_NAME
);
1254 (void) unlink(sClientKeyFile
);
1260 * GetPKIcerts verifies that CA and Agent certificates are available in
1261 * persistent storage and updates profile with an indicator
1264 KMSClientProfile
* const io_pProfile
)
1266 FATAL_ASSERT( io_pProfile
);
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
1276 #if defined(DEBUG_TRACE) && defined(METAWARE)
1277 ECPT_TRACE_ENTRY
*trace
= NULL
;
1278 ECPT_TRACE( trace
, GetPKIcerts
);
1281 io_pProfile
->m_iEnrolled
= FALSE
;
1283 BuildFullProfilePath( sFullProfileDir
,
1284 g_sWorkingDirectory
, io_pProfile
->m_wsProfileName
);
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
);
1290 #ifdef K_SOLARIS_PLATFORM
1292 * stat(2) is preferred over fopen(3C)
1293 * fopen for checking if a file is present.
1296 if (stat(sCAcertFile
, &statp
)) {
1297 LogError(io_pProfile
,
1298 AUDIT_CLIENT_LOAD_PROFILE_FAILED
,
1301 "Test for presence of CA Certificate failed" );
1306 pfFile
= fopen( sCAcertFile
, "rb" );
1308 if ( pfFile
!= NULL
)
1314 LogError(io_pProfile
,
1315 AUDIT_CLIENT_LOAD_PROFILE_FAILED
,
1318 "Test for presence of CA Certificate failed" );
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
);
1329 #ifdef K_SOLARIS_PLATFORM
1331 * stat(2) is safer than "fopen" for checking if a file is
1334 if (stat(sAgentCertFile
, &statp
)) {
1335 LogError(io_pProfile
,
1336 AUDIT_CLIENT_LOAD_PROFILE_FAILED
,
1339 "Test for presence of Agent Certificate failed" );
1344 pfFile
= fopen( sAgentCertFile
, "rb" );
1346 if ( pfFile
!= NULL
)
1352 LogError(io_pProfile
,
1353 AUDIT_CLIENT_LOAD_PROFILE_FAILED
,
1356 "Test for presence of Agent Certificate failed" );
1361 io_pProfile
->m_iEnrolled
= TRUE
;
1367 * DeleteStorageProfile
1369 bool DeleteStorageProfile(
1370 const char* const i_pName
)
1372 FATAL_ASSERT( i_pName
);
1374 #if defined(DEBUG_TRACE) && defined(METAWARE)
1375 ECPT_TRACE_ENTRY
*trace
= NULL
;
1376 ECPT_TRACE( trace
, DeleteStorageProfile
);
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];
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
);
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
);
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
);
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
);
1409 myFILE
* pfFile
= fopen( sConfigFile
, "rb" );
1411 if ( pfFile
!= NULL
)
1414 if ( my_unlink(sConfigFile
) )
1418 pfFile
= fopen( sClusterInformationFile
, "rb" );
1420 if ( pfFile
!= NULL
)
1423 if ( my_unlink(sClusterInformationFile
) )
1427 pfFile
= fopen( sCACertificateFile
, "rb" );
1429 if ( pfFile
!= NULL
)
1432 if ( my_unlink(sCACertificateFile
) )
1436 pfFile
= fopen( sClientKeyFile
, "rb" );
1438 if ( pfFile
!= NULL
)
1441 if ( my_unlink(sClientKeyFile
) )
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
);
1450 /* Just unlink, no need to open/close first. */
1451 if ( my_unlink(sClientP12File
) )
1455 pfFile
= fopen( sFullProfileDir
, "rb" );
1457 if ( pfFile
!= NULL
)
1460 if ( my_rmdir(sFullProfileDir
) )
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
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)
1479 * @returns 0=success, non-zero=fail
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
1486 FATAL_ASSERT( i_pProfile
);
1487 FATAL_ASSERT( io_pSoap
);
1489 #if defined(DEBUG_TRACE) && defined(METAWARE)
1490 ECPT_TRACE_ENTRY
*trace
= NULL
;
1491 ECPT_TRACE( trace
, K_soap_ssl_client_context
) ;
1495 char sCACertificateFile
[KMS_MAX_FILE_NAME
];
1496 char sClientKeyFile
[KMS_MAX_FILE_NAME
];
1499 BuildFullProfilePath( sCACertificateFile
, // out
1500 g_sWorkingDirectory
, // out
1501 i_pProfile
->m_wsProfileName
); // in
1503 strncat( sCACertificateFile
, // path
1504 CA_CERTIFICATE_FILE
, // name
1505 KMS_MAX_FILE_NAME
);
1510 case SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION
:
1512 BuildFullProfilePath( sClientKeyFile
,
1513 g_sWorkingDirectory
,
1514 i_pProfile
->m_wsProfileName
);
1516 strncat( sClientKeyFile
, // path
1517 CLIENT_KEY_FILE
, // name
1518 KMS_MAX_FILE_NAME
);
1520 // this sends the following to the SSL Layer
1522 return K_ssl_client_context(
1525 sClientKeyFile
, // keyfile - client cert and private key
1526 i_pProfile
->m_sHexHashedPassphrase
, // password
1527 sCACertificateFile
, // cafile - CA certificate
1531 return soap_ssl_client_context(
1533 #ifndef SOAP_SSL_SKIP_HOST_CHECK
1536 i_iFlags
| SOAP_SSL_SKIP_HOST_CHECK
, // flags
1538 sClientKeyFile
, // keyfile - client cert and private key
1539 i_pProfile
->m_sHexHashedPassphrase
, // password
1540 sCACertificateFile
, // cafile - CA certificate
1545 case SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION
:
1548 return K_ssl_client_context(
1553 sCACertificateFile
, // cafile
1557 return soap_ssl_client_context(
1559 #ifndef SOAP_SSL_SKIP_HOST_CHECK
1562 i_iFlags
| SOAP_SSL_SKIP_HOST_CHECK
, // flags
1566 sCACertificateFile
, // cafile
1572 // unauthenticated sessions are not supported