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