2 * This file is part of the OpenPTS project.
4 * The Initial Developer of the Original Code is International
5 * Business Machines Corporation. Portions created by IBM
6 * Corporation are Copyright (C) 2011 International Business
7 * Machines Corporation. All Rights Reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the Common Public License as published by
11 * IBM Corporation; either version 1 of the License, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * Common Public License for more details.
19 * You should have received a copy of the Common Public License
20 * along with this program; if not, a copy can be viewed at
21 * http://www.opensource.org/licenses/cpl1.0.php.
26 * \brief FSM action for Auto RM Update (ARU)
27 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
29 * cleanup 2012-01-05 SM
32 * ARU information is stored in conf instead of ctx since this is part of
33 * the platform information. The ctx hold volatile information for an
35 * Thus, we have to maintain the ARU info in the conf. e.g reset ARU info
36 * before used within other ctx.
39 * IML -> FSM -> ARU info -> update operation -> IML
41 * So. The test is not easy.
54 #include <search.h> // hash table
56 #include <sys/types.h>
57 #include <sys/socket.h>
59 #include <netinet/in.h>
63 #include <sys/wait.h> // Linux waitpid
65 #include <openssl/sha.h>
72 OPENPTS_UPDATE_CONTEXT *newUpdateCtx() {
73 OPENPTS_UPDATE_CONTEXT *ctx;
76 ctx = xmalloc(sizeof(OPENPTS_UPDATE_CONTEXT));
78 LOG(LOG_ERR, "no memory");
81 memset(ctx, 0, sizeof(OPENPTS_UPDATE_CONTEXT));
83 for (i = 0; i < MAX_PCRNUM; i++) {
84 for (j = 0; j < MAX_SSLEVEL; j++) {
85 ctx->snapshot[i][j] = NULL;
95 OPENPTS_UPDATE_SNAPSHOT *newUpdateSnapshot() {
96 OPENPTS_UPDATE_SNAPSHOT *uss;
98 uss = xmalloc(sizeof(OPENPTS_UPDATE_SNAPSHOT));
100 LOG(LOG_ERR, "no memory");
103 memset(uss, 0, sizeof(OPENPTS_UPDATE_SNAPSHOT));
111 void freeUpdateSnapshot(OPENPTS_UPDATE_SNAPSHOT *uss) {
118 void freeUpdateCtx(OPENPTS_UPDATE_CONTEXT* ctx) {
123 /* subset of action.c */
127 * reset FSM in snapshot for FSM update
131 int resetFsm(OPENPTS_SNAPSHOT *ss) {
134 LOG(LOG_ERR, "null input");
138 /* free event wrapper chain */
139 if (ss->start != NULL) {
140 freeEventWrapperChain(ss->start);
144 if (ss->fsm_behavior != NULL) {
145 /* just reset the FSM to initial state */
146 OPENPTS_FSM_CONTEXT *fsm_behaviour = ss->fsm_behavior;
147 OPENPTS_FSM_Transition *fsm_trans = fsm_behaviour->fsm_trans;
149 /* just reset the FSM to initial state */
150 fsm_behaviour->curr_state = NULL;
151 fsm_behaviour->status = 0;
153 while (fsm_trans != NULL) {
154 fsm_trans->event_num = 0;
155 fsm_trans = fsm_trans->next;
159 if (ss->fsm_binary != NULL) {
161 freeFsmContext(ss->fsm_binary);
162 ss->fsm_binary = NULL;
166 // TODO set to SS[n-1]
167 memset(ss->curr_pcr, 0, SHA1_DIGEST_SIZE);
168 memset(ss->tpm_pcr, 0, SHA1_DIGEST_SIZE);
177 * doAction - startUpdate
179 * allocate OPENPTS_UPDATE_SNAPSHOT
181 int startUpdate(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
182 TSS_PCR_EVENT *event;
183 OPENPTS_UPDATE_CONTEXT *update;
184 OPENPTS_UPDATE_SNAPSHOT *uss;
185 OPENPTS_CONFIG *conf;
186 OPENPTS_EVENT_UPDATE_START *start;
187 int target_pcr_index;
188 int target_snapshot_level;
193 DEBUG_CAL("startUpdate() - start\n");
197 LOG(LOG_ERR, "null input\n");
202 LOG(LOG_ERR, "null input\n");
206 if (conf->enable_aru == 0) {
211 conf->target_newrm_exist = 0;
214 if (eventWrapper == NULL) {
215 LOG(LOG_ERR, "null input");
218 event = eventWrapper->event;
220 LOG(LOG_ERR, "null input");
224 if (event->ulEventLength <= 20) { // TODO sizeof
225 LOG(LOG_ERR, "startUpdate() - bad eventdata\n");
228 if (event->rgbEvent == NULL) {
229 LOG(LOG_ERR, "null input");
232 if (conf->update == NULL) {
233 LOG(LOG_ERR, "null input");
237 update = (OPENPTS_UPDATE_CONTEXT *) conf->update;
238 start = (OPENPTS_EVENT_UPDATE_START *) event->rgbEvent;
240 // Convert the Endian
241 if (ctx->conf->iml_endian != 0) {
242 target_pcr_index = b2l(start->target_pcr_index);
243 target_snapshot_level = b2l(start->target_snapshot_level);
244 event_num = b2l(start->event_num);
245 update_type = b2l(start->update_type);
246 data_length = b2l(start->data_length);
248 target_pcr_index = start->target_pcr_index;
249 target_snapshot_level = start->target_snapshot_level;
250 event_num = start->event_num;
251 update_type = start->update_type;
252 data_length = start->data_length;
255 DEBUG("Update pcr=%08x level=%08x count=%d endian=%d",
257 target_snapshot_level,
259 ctx->conf->iml_endian);
261 if (target_pcr_index >= MAX_PCRNUM) {
262 LOG(LOG_ERR, "startUpdate() - Bad PCR index %d 0x%08x\n",
263 target_pcr_index, target_pcr_index);
264 return PTS_INTERNAL_ERROR;
266 if (target_snapshot_level >= MAX_SSLEVEL) {
267 LOG(LOG_ERR, "startUpdate() - Bad SS Level %d 0x%08x\n",
268 target_snapshot_level, target_snapshot_level);
269 return PTS_INTERNAL_ERROR;
272 /* set current target to OPENPTS_UPDATE_CONTEXT */
273 update->target_pcr_index = target_pcr_index;
274 update->target_snapshot_level = target_snapshot_level;
276 /* setup OPENPTS_UPDATE_SNAPSHOT */
279 [target_snapshot_level] == NULL) {
280 /* 1st update of this PCR/Level */
281 /* malloc OPENPTS_UPDATE_SNAPSHOT */
282 uss = newUpdateSnapshot();
284 LOG(LOG_ERR, "newUpdateSnapshot() fail");
288 /* already exist => replace */
290 // TODO reset previous OPENPTS_UPDATE_SNAPSHOT
291 DEBUG("OPENPTS_UPDATE_SNAPSHOT exist, reset this\n");
292 uss = update->snapshot
294 [target_snapshot_level];
298 uss->event_count = 0;
300 uss->ew_start_update = eventWrapper;
304 [target_snapshot_level] = uss;
306 conf->update_exist = 1;
307 DEBUG_CAL("startUpdate() - update exit\n");
313 * doAction - deputyEvent
315 int deputyEvent(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
316 int rc = PTS_SUCCESS;
317 TSS_PCR_EVENT *event;
318 OPENPTS_UPDATE_CONTEXT *update;
319 OPENPTS_CONFIG *conf;
320 OPENPTS_UPDATE_SNAPSHOT *uss;
322 DEBUG_CAL("deputyEvent() - start\n");
326 LOG(LOG_ERR, "null input\n");
331 LOG(LOG_ERR, "null input\n");
336 if (ctx->conf->enable_aru == 0) {
342 if (eventWrapper == NULL) {
343 LOG(LOG_ERR, "null input");
346 event = eventWrapper->event;
348 LOG(LOG_ERR, "null input");
351 update = conf->update;
352 if (update == NULL) {
353 LOG(LOG_ERR, "null input");
357 /* OPENPTS_UPDATE_SNAPSHOT */
358 uss = update->snapshot
359 [update->target_pcr_index]
360 [update->target_snapshot_level];
362 LOG(LOG_ERR, "null input");
366 /* copy to update[] */
367 if (uss->event_count == 0) {
368 /* link to 1st event */
369 uss->ew_deputy_first = eventWrapper;
370 uss->ew_deputy_last = eventWrapper;
373 uss->ew_deputy_last = eventWrapper;
381 * doAction - endUpdate
383 int endUpdate(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
384 TSS_PCR_EVENT *event;
385 OPENPTS_UPDATE_CONTEXT *update;
386 OPENPTS_UPDATE_SNAPSHOT *uss;
387 OPENPTS_CONFIG *conf;
388 OPENPTS_EVENT_UPDATE_START *start;
391 DEBUG_CAL("endUpdate() - start\n");
395 LOG(LOG_ERR, "null input\n");
400 LOG(LOG_ERR, "null input\n");
405 if (conf->enable_aru == 0) {
407 DEBUG("endUpdate() - done(skip), conf->enable_aru == 0\n");
411 // TODO find the last aru event set
412 /* Set flag for Update */
413 conf->update_exist = 1;
414 DEBUG("endUpdate() - update exist\n");
417 if (eventWrapper == NULL) {
418 LOG(LOG_ERR, "null input");
421 event = eventWrapper->event;
423 LOG(LOG_ERR, "null input");
426 update = conf->update;
427 if (update == NULL) {
428 LOG(LOG_ERR, "null input");
432 uss = update->snapshot
433 [update->target_pcr_index]
434 [update->target_snapshot_level];
436 LOG(LOG_ERR, "null input");
440 /* start structure */
443 LOG(LOG_ERR, "null input");
447 // Convert the Endian
448 if (ctx->conf->iml_endian != 0) {
449 event_num = b2l(start->event_num);
451 event_num = start->event_num;
454 uss->ew_end_update = eventWrapper;
456 /* check the event num */
457 if (uss->event_count != event_num) {
458 /* actual event number is different with the number in start event */
459 LOG(LOG_ERR, "number of events (%08x) are not same with definition at start (%08x), BAD eventlog?\n",
460 uss->event_count, event_num);
461 return PTS_INVALID_SNAPSHOT;
468 * doAction - updateCollector
470 int updateCollector(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
471 TSS_PCR_EVENT *event;
472 OPENPTS_EVENT_COLLECTOR_UPDATE *update = NULL;
473 OPENPTS_CONFIG *conf;
475 DEBUG("updateCollector() - start\n");
479 LOG(LOG_ERR, "null input\n");
484 LOG(LOG_ERR, "null input\n");
489 if (eventWrapper == NULL) {
490 LOG(LOG_ERR, "null input");
493 event = eventWrapper->event;
495 LOG(LOG_ERR, "null input");
499 if (event->ulEventLength != sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE)) {
500 LOG(LOG_ERR, "updateCollector() - Bad eventData size %d != %d\n",
501 event->ulEventLength,
502 sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE));
503 return PTS_INVALID_SNAPSHOT;
507 update = (OPENPTS_EVENT_COLLECTOR_UPDATE *)event->rgbEvent;
509 /* save RM_UUID to conf */
510 if (conf->target_newrm_uuid == NULL) {
511 conf->target_newrm_uuid = xmalloc(sizeof(PTS_UUID));
512 if (NULL == conf->target_newrm_uuid) {
513 LOG(LOG_ERR, "no memory");
517 memcpy(conf->target_newrm_uuid, &update->new_manifest_uuid, sizeof(PTS_UUID));
519 /* Already processed => Clear Update FLag */
520 conf->update_exist = 0;
522 /* Notification for Verifier side */
523 conf->target_newrm_exist = 1;
526 // TODO if TCDS was restart, the eventlog used by PTSCD was gone.
528 DEBUG("updateCollector() - done, clear update_exist flag\n");
541 * SS -> W -> W -> W - Original PCR4
543 * W -> W -> W -> W -> W - Update PCR11
548 * Delete target chain
550 * SS -> - Original PCR4
552 * W -> W -> W -> W -> W - Update PCR11
557 * Move update to target location
561 * SS -> W -> W -> W - Original PCR4
563 * W ----------------> W - Update PCR11
571 int updateSnapshot(OPENPTS_CONTEXT *ctx, OPENPTS_UPDATE_SNAPSHOT *uss, int i, int j) {
572 OPENPTS_SNAPSHOT *ss;
573 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
574 OPENPTS_EVENT_UPDATE_START *start;
577 int target_pcr_index;
578 int target_snapshot_level;
583 DEBUG_CAL("updateSnapshot() - start, pcr=%d level=%d %d events exist!!!\n", i, j, uss->event_count);
587 LOG(LOG_ERR, "null input");
591 LOG(LOG_ERR, "null input");
596 /* start structure */
598 // Convert the Endian
599 if (ctx->conf->iml_endian != 0) {
600 target_pcr_index = b2l(start->target_pcr_index);
601 target_snapshot_level = b2l(start->target_snapshot_level);
602 event_num = b2l(start->event_num);
603 update_type = b2l(start->update_type);
604 data_length = b2l(start->data_length);
606 target_pcr_index = start->target_pcr_index;
607 target_snapshot_level = start->target_snapshot_level;
608 event_num = start->event_num;
609 update_type = start->update_type;
610 data_length = start->data_length;
613 /* update target snaposhot */
614 ss = getSnapshotFromTable(ctx->ss_table, i, j);
616 LOG(LOG_ERR, "null snapshot\n");
620 // TODO remove fillowing counters
622 ctx->ss_table->update_num[ss->level]++;
625 // DEBUG("Update by FSM %s\n", ss->fsm_behavior->uml_file);
626 // verbose |= DEBUG_FSM_FLAG;
628 // Step 1. getIml() - IML --> BHV-FSM --> SS->eventWrapper chain
629 // Step 2. writeAllCoreValue() in rm.c - SS->eventWrapper chain -> BIN-FSM is generated
631 /* reset/free target snapshot */
632 // delete EW chain, delete BIN-FSM
633 resetFsm(ss); // fsm.c
636 if (update_type == UPDATE_IPL_IMAGE) {
637 /* get iml.ipl.maxcount value from eventdata */
642 pnum = (UINT32 *)start->data;
644 if (ctx->conf->iml_endian != 0) {
648 /* WORK NEEDED: I guess that bosrenew should really pass in all IPL events including the final one */
651 LOG(LOG_INFO, "UPDATE_IPL_IMAGE iml.ipl.maxcount=%d (0x%x)\n", num, num);
652 snprintf(buf, BUF_SIZE, "%d", num);
653 setProperty(ctx, "iml.ipl.maxcount", buf);
657 eventWrapper = uss->ew_deputy_first;
658 while ((eventWrapper != NULL) && (count < uss->event_count)) {
659 /*Change PCR index */
660 eventWrapper->event->ulPcrIndex = i;
661 /* set sw->ss link */
662 rc = updateFsm(ctx, ss->fsm_behavior, eventWrapper); // TODO ignore the pcr_index
663 if (rc == OPENPTS_FSM_ERROR) {
664 /* FSM detect invalid IML, or bad FSM for this IML */
665 DEBUG("[RM%02d-PCR%02d] updateFsm() => OPENPTS_FSM_ERROR ===> rc=PTS_INVALID_SNAPSHOT, added Reason\n",
666 target_snapshot_level, target_pcr_index);
667 addReason(ctx, target_pcr_index, NLS(MS_OPENPTS, OPENPTS_ARU_IML_VALIDATION_FAILED,
668 "[RM%02d-PCR%02d] IML validation by FSM has failed. State='%s' at the FSM is '%s'"),
669 target_snapshot_level,
671 ss->fsm_behavior->curr_state->name,
672 ss->fsm_behavior->uml_file);
673 ctx->ss_table->error[start->target_pcr_index] = PTS_INVALID_SNAPSHOT;
674 rc = PTS_INVALID_SNAPSHOT;
675 } else if (rc == OPENPTS_FSM_FINISH) {
676 /* OK, FSM finish successfly */
677 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
680 /* Move to next level (0->1) */
681 incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
682 } else if (rc == OPENPTS_FSM_SUCCESS) {
685 } else if (rc == OPENPTS_FSM_TRANSIT) {
686 // TRANSIT, Skip update SS chain
687 // TODO set by updateFsm
688 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
690 /* Move to next level (0->1) */
691 incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
693 } else if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
694 // TRANSIT, Skip update SS chain
695 // TODO set by updateFsm
696 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
698 /* Move to next level (0->1) */
699 incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
702 LOG(LOG_ERR, "updateFsm rc=%d\n", rc);
705 /* update SS chain */
706 if (ss->event_num == 0) {
708 ss->start = eventWrapper;
709 ss->end = eventWrapper;
712 ss->end->next_pcr = eventWrapper;
713 ss->end = eventWrapper;
717 rc = OPENPTS_FSM_MIGRATE_EVENT;
719 eventWrapper = eventWrapper->next_pcr;
723 // TODO cut EW <-> event link
726 /* Target end EW -> end */
727 uss->ew_deputy_last->next_all = NULL;
728 uss->ew_deputy_last->next_pcr = NULL;
730 /* Update start->end */
731 uss->ew_start_update->next_all = uss->ew_end_update;
732 uss->ew_start_update->next_pcr = uss->ew_end_update;
734 /* Snapshot (Update, PCR11) event couner */
735 ss = uss->ew_start_update->snapshot;
736 ss->event_num = ss->event_num - count;
742 * Extend Collector Update Event
745 int extendEvCollectorUpdate(OPENPTS_CONFIG *conf) {
746 TSS_PCR_EVENT* event; // /usr/include/tss/tss_structs.h
747 OPENPTS_EVENT_COLLECTOR_UPDATE *collector_update;
748 BYTE pcr[SHA1_DIGEST_SIZE];
753 LOG(LOG_ERR, "null input\n");
756 if (conf->newrm_uuid == NULL) {
757 LOG(LOG_ERR, "null input\n");
760 if (conf->newrm_uuid->uuid == NULL) {
761 LOG(LOG_ERR, "null input\n");
765 /* malloc eventlog */
766 collector_update = xmalloc_assert(sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE));
767 if (collector_update == NULL) {
768 LOG(LOG_ERR, "no memory\n");
771 event = xmalloc_assert(sizeof(TSS_PCR_EVENT));
773 LOG(LOG_ERR, "no memory\n");
774 xfree(collector_update);
778 /* fill collector_start */
779 memcpy(&collector_update->pts_version, &conf->pts_version, 4);
780 memcpy(&collector_update->collector_uuid, conf->uuid->uuid, 16);
781 memcpy(&collector_update->new_manifest_uuid, conf->newrm_uuid->uuid, 16);
784 // memcpy(&collector_start->pcr_value;
785 // readPcr(conf->openpts_pcr_index, pcr);
792 sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE));
793 SHA1_Final(pcr, &sha_ctx);
796 // event->versionInfo // set by TSP?
797 event->ulPcrIndex = conf->openpts_pcr_index; // set by TSP?
798 event->eventType = EV_COLLECTOR_UPDATE; // openpts_tpm.h
799 event->ulPcrValueLength = SHA1_DIGEST_SIZE;
800 event->rgbPcrValue = pcr;
801 event->ulEventLength = sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE);
802 event->rgbEvent = (BYTE *) collector_update;
808 xfree(collector_update);
818 * Update events must be a simple event chain (atmic)
821 int updateSnapshots(OPENPTS_CONTEXT *ctx) {
823 OPENPTS_CONFIG *conf;
824 OPENPTS_UPDATE_CONTEXT *update;
825 OPENPTS_UPDATE_SNAPSHOT *uss;
828 DEBUG_CAL("updateSnapshots() - start\n");
832 LOG(LOG_ERR, "null input\n");
837 LOG(LOG_ERR, "null input\n");
842 if (conf->update_exist == 0) {
843 LOG(LOG_TODO, "updateSnapshots() - done, no update\n");
847 update = (OPENPTS_UPDATE_CONTEXT *)conf->update;
848 if (update == NULL) {
849 LOG(LOG_ERR, "null input\n");
853 for (i = 0; i < MAX_PCRNUM; i++) {
854 for (j = 0; j < MAX_SSLEVEL; j++) {
855 // DEBUG("updateSnapshots() - %d %d\n", i, j);
856 uss = update->snapshot[i][j];
858 // DEBUG("updateSnapshots() - %p\n", uss);
859 // DEBUG("updateSnapshots() - %p %d %d\n", uss, uss->event_count, uss->update_count);
860 if (uss->event_count > 0) {
861 updateSnapshot(ctx, uss, i, j);
862 DEBUG("free OPENPTS_UPDATE_SNAPSHOT\n");
864 freeUpdateSnapshot(update->snapshot[i][j]);
865 update->snapshot[i][j] = NULL;
877 * Automatically update the manifest by update events in the IML
879 * subset of collector.c, called by
882 * ptscd -u -m "OS update to X.X.X"
885 * killproc ptscd -HUP
889 OPENPTS_CONFIG *conf,
891 OPENPTS_PROPERTY *prop_start,
892 OPENPTS_PROPERTY *prop_end,
895 int rc = PTS_SUCCESS;
896 OPENPTS_CONTEXT *ctx;
898 DEBUG_CAL("update() - start\n");
902 LOG(LOG_ERR, "null input\n");
907 ctx = newPtsContext(conf);
909 LOG(LOG_ERR, "no memory");
914 if (prop_count > 0) {
916 if (prop_start == NULL) {
917 LOG(LOG_ERR, "null input\n");
920 if (prop_end == NULL) {
921 LOG(LOG_ERR, "null input\n");
924 ctx->prop_start = prop_start;
925 ctx->prop_end = prop_end;
926 ctx->prop_count = prop_count;
929 addPropertiesFromConfig(conf, ctx);
931 /* UUID of this platform */
932 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_PLATFORM_UUID,
933 "Platform UUID: %s\n"), conf->uuid->str);
934 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_RM_UUID,
935 "Reference manifest UUID: %s\n"), conf->rm_uuid->str);
936 // OUTPUT("RM UUID (for next boot) : %s\n", conf->newrm_uuid->str); // NULL
939 getRmList(conf, conf->config_dir); // uuid.c
941 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_RM_LIST,
942 "List of reference manifest sets: %d reference manifest sets in config dir\n"),
943 conf->rmsets->rmset_num);
944 printRmList(conf, " ");
948 /* delete old RM sets */
949 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_PURGE_RM, "Purge the renewed manifests\n"));
950 purgeRenewedRm(conf); // uuid.c
954 rc = readFsmFromPropFile(ctx, conf->config_file);
955 if (rc != PTS_SUCCESS) {
956 LOG(LOG_ERR, "update() - read FSM failed\n");
957 rc = PTS_INTERNAL_ERROR;
961 /* read IML to fill the BIOS binary measurement, and translate BHV->BIN FSM */
964 conf->enable_aru = 1;
965 conf->update_exist = 0;
967 if (conf->update != NULL) {
968 freeUpdateCtx((OPENPTS_UPDATE_CONTEXT*)conf->update);
970 conf->update = (void *) newUpdateCtx();
972 /* OK, now ready to read IML */
974 /* load current IML using FSMs */
975 if (conf->iml_mode == 0) { // TODO use def
977 LOG(LOG_ERR, "update() - Build with --without-tss. iml.mode=tss is not supported\n");
982 /* WORK NEEDED: The above return value could be a positive number for an error or
983 a positive number for the pcr or event number. There is no way to
984 discover success or failure. I will assume success and hope log files
985 contain some useful information! */
988 } else if (conf->iml_mode == 1) {
989 // TODO change to generic name? conf->iml_filename[0] conf->iml_filename[1]
990 /* from securityfs */
992 rc = readBiosImlFile(
994 conf->bios_iml_filename,
996 if (rc != PTS_SUCCESS) {
997 DEBUG("readBiosImlFile() was failed\n");
998 OUTPUT(NLS(MS_OPENPTS, OPENPTS_ARU_ERROR_READING_BIOS_IML,
999 "An error occured while reading the bios iml file.\n"));
1000 printReason(ctx, 0);
1004 /* RUNTIME IML (Linux-IMA) */
1005 if (conf->runtime_iml_filename != NULL) {
1006 /* count seems to be ignored in most places so we ignore it too */
1008 rc = readImaImlFile(
1010 conf->runtime_iml_filename,
1011 conf->runtime_iml_type, 0, &count); // TODO endian?
1013 LOG(LOG_ERR, "read IMA IML, %s has failed\n", conf->runtime_iml_filename);
1014 rc = PTS_INTERNAL_ERROR;
1019 LOG(LOG_ERR, "unknown IML mode, %d\n", conf->iml_mode);
1022 /* get SMBIOS data */
1025 // TODO change to good message
1026 if (conf->update_exist > 0) {
1029 /* Update the Manifests */
1030 rc = updateSnapshots(ctx);
1031 if (rc != PTS_SUCCESS) {
1032 LOG(LOG_ERR, "update() - updateSnapshots fail\n");
1036 /* new UUID for this RM set */
1037 if (conf->newrm_uuid == NULL) {
1038 LOG(LOG_INFO, "conf->newrm_uuid == NULL, generate new reference manifest UUID\n");
1039 conf->newrm_uuid = newOpenptsUuid(); // empty
1040 conf->newrm_uuid->filename = getFullpathName(conf->config_dir, "newrm_uuid");
1041 DEBUG("conf->newrm_uuid->filename %s\n", conf->newrm_uuid->filename);
1042 conf->newrm_uuid->status = OPENPTS_UUID_FILENAME_ONLY;
1043 rc = genOpenptsUuid(conf->newrm_uuid);
1045 // conf->str_newrm_uuid = getStringOfUuid(conf->newrm_uuid);
1046 // conf->time_newrm_uuid = getDateTimeOfUuid(conf->newrm_uuid);
1047 } else if (conf->newrm_uuid->status == OPENPTS_UUID_FILENAME_ONLY) {
1049 rc = genOpenptsUuid(conf->newrm_uuid);
1051 } else if (conf->newrm_uuid->status == OPENPTS_UUID_FILLED) {
1053 rc = genOpenptsUuid(conf->newrm_uuid);
1055 } else if (conf->newrm_uuid->status == OPENPTS_UUID_CHANGED) {
1056 /* change UUID again */
1057 rc = genOpenptsUuid(conf->newrm_uuid);
1060 LOG(LOG_ERR, "update() - conf->newrm_uuid->status %d\n", conf->newrm_uuid->status);
1061 LOG(LOG_ERR, "update() - use given reference manifest UUID %s (for test)\n", conf->rm_uuid->str);
1066 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_GENERATE_UUID,
1067 "Generate UUID (for new reference manifests): %s \n"), conf->newrm_uuid->str);
1068 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_DATE, " Date and Time: %04d-%02d-%02d-%02d:%02d:%02d\n"),
1069 conf->newrm_uuid->time->year + 1900,
1070 conf->newrm_uuid->time->mon + 1,
1071 conf->newrm_uuid->time->mday,
1072 conf->newrm_uuid->time->hour,
1073 conf->newrm_uuid->time->min,
1074 conf->newrm_uuid->time->sec);
1077 rc = makeNewRmSetDir(conf);
1078 if (rc != PTS_SUCCESS) {
1079 LOG(LOG_ERR, "mkdir of RM set dir was failed\n");
1083 /* save UUID for next boot */
1084 DEBUG("writeOpenptsUuidFile %s %s\n", conf->newrm_uuid->str, conf->newrm_uuid->filename);
1085 rc = writeOpenptsUuidFile(conf->newrm_uuid, 1); // overwrite
1089 /* check the snapshot level to be updated */
1090 for (i= 0;i < conf->newrm_num; i++) {
1091 /* check each RM level */
1092 if (ctx->ss_table->update_num[i] > 0) {
1094 for (j = 0; j < MAX_PCRNUM; j++) {
1095 OPENPTS_SNAPSHOT *ss;
1096 ss = getSnapshotFromTable(
1101 if (ss->update_num > 0) {
1102 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_RM_DETAIL,
1103 "Update RM%02d-PCR%02d (%d update(s) in update events)\n"), i, j, ss->update_num);
1108 DEBUG("update() - writeRm %s\n", conf->newrm_filename[i]);
1109 rc = writeRm(ctx, conf->newrm_filename[i], i);
1111 LOG(LOG_ERR, "write RM, %s was failed\n", conf->newrm_filename[i]);
1112 rc = PTS_INTERNAL_ERROR;
1116 /*no update, just copy the RM to new RM set dir*/
1118 DEBUG("update() - dowriteRm %s\n", conf->newrm_filename[i]);
1119 rc = writeRm(ctx, conf->newrm_filename[i], i);
1121 LOG(LOG_ERR, "write RM, %s was failed\n", conf->newrm_filename[i]);
1122 rc = PTS_INTERNAL_ERROR;
1128 /* Extend Collector Update event */
1129 rc = extendEvCollectorUpdate(conf);
1130 if (rc != PTS_SUCCESS) {
1131 LOG(LOG_ERR, "updateSnapshots() - extendEvCollectorUpdate fail\n");
1134 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_SUCCESS,
1135 "Successfully updated the reference manifests\n\n"));
1137 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_NONE,
1138 "There is no update.\n\n"));
1142 if ( rc != PTS_SUCCESS ) {
1143 ERROR(NLS(MS_OPENPTS, OPENPTS_UPDATE_FAILED,
1144 "Failed to update the reference manifests\n"));
1147 if ( NULL != ctx ) {
1149 freePtsContext(ctx);
1153 conf->enable_aru = 0;
1155 DEBUG("update() - done\n");
1163 static int diffFileAgainstCache(char *fileName, int len, BYTE *contents) {
1165 struct stat statBuf;
1166 int fd = open(fileName, O_RDONLY);
1169 LOG(LOG_ERR, "Failed to open '%s', errno %d\n", fileName, errno);
1170 } else if (fstat(fd, &statBuf) == -1) {
1171 LOG(LOG_ERR, "Failed to stat '%s' (fd %d), errno %d\n", fileName, fd, errno);
1172 } else if ( len != statBuf.st_size ) {
1173 DEBUG("File length for pending RM '%s' (%d) does not match cached length (%d) from collector.\n",
1174 fileName, (int)statBuf.st_size, len);
1176 int totalBytesRead = 0;
1179 ssize_t bytesRead = read(fd, page, 4096);
1180 if ( -1 == bytesRead ) {
1181 LOG(LOG_ERR, "Failed to read from fd %d, errno %d\n", fd, errno);
1183 } else if (bytesRead == 0) {
1184 if (totalBytesRead != len) {
1185 LOG(LOG_ERR, "Finished reading from file prematurely, still expecting data.");
1191 totalBytesRead += bytesRead;
1192 if (totalBytesRead > len) {
1193 LOG(LOG_ERR, "Read more data from RM file than expected.");
1196 DEBUG("Read %ld bytes, total = %d out of %d\n", bytesRead, totalBytesRead, len);
1198 if ( 0 != memcmp(page, contents, bytesRead) ) {
1202 contents += bytesRead;
1217 int isNewRmStillValid(OPENPTS_CONTEXT *ctx, char *conf_dir) {
1221 char *str_collector_uuid;
1223 char *str_newrm_uuid;
1225 char *str_verifier_uuid;
1229 char * collector_dir;
1231 OPENPTS_CONFIG *conf;
1233 // TODO get from list
1234 OPENPTS_CONFIG *target_conf = NULL;
1238 LOG(LOG_ERR, "null input\n");
1243 LOG(LOG_ERR, "null input\n");
1251 newRmSet = conf->newRmSet;
1252 if (newRmSet == NULL) {
1253 LOG(LOG_ERR, "null input\n");
1256 target_conf = ctx->target_conf;
1257 if (target_conf == NULL) {
1258 LOG(LOG_ERR, "null input\n");
1261 if (target_conf->uuid == NULL) {
1262 LOG(LOG_ERR, "null input\n");
1265 if (target_conf->rm_uuid == NULL) {
1266 LOG(LOG_ERR, "null input\n");
1271 str_collector_uuid = target_conf->uuid->str;
1272 str_rm_uuid = target_conf->rm_uuid->str;
1273 str_verifier_uuid = conf->uuid->str;
1274 if ((str_collector_uuid == NULL) ||
1275 (str_rm_uuid == NULL) ||
1276 (str_verifier_uuid == NULL)) {
1280 DEBUG("Verifier UUID %s\n", str_verifier_uuid);
1281 DEBUG("Collector UUID %s\n", str_collector_uuid);
1282 DEBUG("Collector RM UUID %s\n", str_rm_uuid);
1284 /* Setup the dir for the collector */
1285 collector_dir = getFullpathName(conf_dir, str_collector_uuid);
1287 DEBUG("conf_dir %s\n", conf_dir);
1288 DEBUG("collector_dir %s\n", collector_dir);
1294 PTS_UUID *newrm_uuid = (PTS_UUID *)newRmSet;
1296 newRmSet += 16; // TODO
1297 str_newrm_uuid = getStringOfUuid(newrm_uuid);
1298 DEBUG("Collector new RM UUID %s\n", str_newrm_uuid);
1302 rm_dir = getFullpathName(collector_dir, str_newrm_uuid);
1304 rc = checkDir(collector_dir);
1305 if (rc != PTS_SUCCESS) {
1306 /* unknwon collector */
1307 LOG(LOG_ERR, "isNewRmStillValid() - Unknown collector, UUID= %s dir=%s\n",
1308 str_collector_uuid, collector_dir);
1309 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_MISSING_COLLECTOR_CONFIG,
1310 "Missing collector configuration"));
1311 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_UUID,
1312 "Collector UUID = %s"), str_collector_uuid);
1316 rc = checkDir(rm_dir);
1317 if (rc != PTS_SUCCESS) {
1318 DEBUG("isNewRmStillValid() - New RM doesn't exist, UUID = %s\n", str_collector_uuid);
1322 DEBUG("conf dir : %s\n", collector_dir);
1323 DEBUG("rm dir : %s\n", rm_dir);
1324 DEBUG("New RM UUID file : %s\n", target_conf->newrm_uuid->filename);
1327 num = getUint32(newRmSet);
1328 DEBUG("RM num %d\n", num);
1331 if (num > MAX_RM_NUM) {
1332 LOG(LOG_ERR, "Bad NUM %d\n", num);
1337 for (i = 0; i < num; i++) {
1339 snprintf(buf, BUF_SIZE, "%s/%s/rm%d.xml",
1343 DEBUG("RM[%d] : %s\n", i, buf);
1345 len = getUint32(newRmSet);
1346 DEBUG("RM[%d] len %d -> %s\n", i, len, buf);
1350 rc = diffFileAgainstCache(buf, len, newRmSet);
1352 DEBUG("New RM file '%s' is now invalidated\n", buf);
1355 DEBUG("New RM file '%s' matches cached contents from collector\n", buf);
1361 rc = PTS_SUCCESS; // OK
1364 xfree(str_newrm_uuid);
1372 * get target NEW RMs before reboot :-)
1377 * ----------------------------------
1380 int updateNewRm(OPENPTS_CONTEXT *ctx, char *host, char *conf_dir) {
1384 char *rm_filename[MAX_RM_NUM];
1386 char *str_collector_uuid;
1389 OPENPTS_UUID *newrm_uuid;
1391 char *str_verifier_uuid;
1395 char * collector_dir;
1397 OPENPTS_CONFIG *conf;
1399 // TODO get from list
1400 char *target_conf_filename = NULL;
1401 OPENPTS_CONFIG *target_conf = NULL;
1405 LOG(LOG_ERR, "null input\n");
1410 LOG(LOG_ERR, "null input\n");
1417 newRmSet = conf->newRmSet;
1418 if (newRmSet == NULL) {
1419 LOG(LOG_ERR, "null input\n");
1422 if (ctx->target_conf == NULL) {
1423 LOG(LOG_ERR, "null input\n");
1426 if (ctx->target_conf->uuid == NULL) {
1427 LOG(LOG_ERR, "null input\n");
1430 if (ctx->target_conf->rm_uuid == NULL) {
1431 LOG(LOG_ERR, "null input\n");
1436 str_collector_uuid = ctx->target_conf->uuid->str;
1437 str_rm_uuid = ctx->target_conf->rm_uuid->str;
1438 str_verifier_uuid = getStringOfUuid(ctx->conf->uuid->uuid);
1439 if ((str_collector_uuid == NULL) ||
1440 (str_rm_uuid == NULL) ||
1441 (str_verifier_uuid == NULL)) {
1442 rc = PTS_INTERNAL_ERROR;
1446 DEBUG("Verifier UUID %s\n", str_verifier_uuid);
1447 DEBUG("Collector UUID %s\n", str_collector_uuid);
1448 DEBUG("Collector RM UUID %s\n", str_rm_uuid);
1450 /* Setup the dir for the collector */
1451 collector_dir = getFullpathName(conf_dir, str_collector_uuid);
1453 DEBUG("conf_dir %s\n", conf_dir);
1454 DEBUG("collector_dir %s\n", collector_dir);
1457 target_conf_filename = getFullpathName(collector_dir, "target.conf");
1458 target_conf = newPtsConfig();
1460 rc = readTargetConf(target_conf, target_conf_filename);
1461 if (rc != PTS_SUCCESS) {
1462 LOG(LOG_ERR, "updateNewRm() - readTargetConf failed\n");
1472 newrm_uuid = newOpenptsUuid2((PTS_UUID *)newRmSet);
1473 newRmSet += 16; // TODO
1474 DEBUG("Collector new RM UUID %s\n", newrm_uuid->str);
1478 rm_dir = getFullpathName(collector_dir, newrm_uuid->str);
1480 rc = checkDir(collector_dir);
1481 if (rc != PTS_SUCCESS) {
1482 /* unknwon collector */
1483 LOG(LOG_ERR, "updateNewRm() - Unknown collector, UUID= %s dir=%s\n",
1484 str_collector_uuid, collector_dir);
1485 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_MISSING_COLLECTOR_CONFIG,
1486 "Missing collector configuration"));
1487 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_HOSTNAME,
1488 "Collector hostname = %s"), host);
1489 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_UUID,
1490 "Collector UUID = %s"), str_collector_uuid);
1491 rc = PTS_NOT_INITIALIZED;
1495 rc = checkDir(rm_dir);
1496 if (rc == PTS_SUCCESS) {
1497 /* ??? Already Exist */
1498 DEBUG("updateNewRm() - Exist RM, UUID= %s\n", str_collector_uuid);
1499 /*addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_RM_ALREADY_EXISTS, "The Reference Manifest already exists"));
1500 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_HOSTNAME, "Collector hostname = %s"), host);
1501 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_UUID, "Collector UUID = %s"), str_collector_uuid);
1502 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_RM_UUID, "Collector RM UUID = %s"), str_rm_uuid);
1506 /* create new RM dir */
1507 rc = makeDir(rm_dir);
1508 if (rc != PTS_SUCCESS) {
1509 /* unknwon collector */
1510 LOG(LOG_ERR, "updateNewRm() - Create New RM dir failed, %s\n", rm_dir);
1511 rc = PTS_INTERNAL_ERROR;
1516 // TODO target.conf?
1517 // conf->property_filename = getFullpathName(collector_dir, "vr.properties");
1518 // conf->ir_filename = getFullpathName(collector_dir, "ir.xml");
1519 // conf->prop_filename = getFullpathName(collector_dir, "target.conf");
1520 // conf->newrm_uuid->filename = getFullpathName(collector_dir, "newrm_uuid");
1522 DEBUG("conf dir : %s\n", collector_dir);
1523 DEBUG("rm dir : %s\n", rm_dir);
1524 DEBUG("New RM UUID file : %s\n", target_conf->newrm_uuid->filename);
1527 num = getUint32(newRmSet);
1528 DEBUG("RM num %d\n", num);
1531 if (num > MAX_RM_NUM) {
1532 LOG(LOG_ERR, "Bad NUM %d\n", num);
1533 rc = PTS_INTERNAL_ERROR;
1538 DEBUG("get %d new RMs\n", num);
1539 target_conf->newrm_num = num;
1540 for (i = 0; i < num; i++) {
1542 snprintf(buf, BUF_SIZE, "%s/%s/rm%d.xml",
1546 rm_filename[i] = smalloc_assert(buf);
1547 DEBUG("RM[%d] : %s\n", i, rm_filename[i]);
1549 len = getUint32(newRmSet);
1550 DEBUG("RM[%d] len %d -> %s\n", i, len, rm_filename[i]);
1554 rc = saveToFile(rm_filename[i], len, newRmSet);
1555 if (rc != PTS_SUCCESS) {
1556 LOG(LOG_ERR, "updateNewRm() - save RM[%d], %s failed\n", i, rm_filename[i]);
1559 target_conf->rm_filename[i] = smalloc_assert(rm_filename[i]);
1564 /* New RM UUID file */
1565 /* save to newrm_uuid file */
1566 DEBUG("NEWRM %s => %s \n", newrm_uuid->str, target_conf->newrm_uuid->filename);
1567 newrm_uuid->filename = target_conf->newrm_uuid->filename;
1568 newrm_uuid->status = OPENPTS_UUID_FILLED;
1569 rc = writeOpenptsUuidFile(newrm_uuid, 1); // overwite
1572 /* save target conf */
1573 // TODO need to updade?
1574 // writeTargetConf(ctx->conf, collector_uuid, target_conf_filename); // ctx.c
1576 rc = PTS_SUCCESS; // OK
1580 if (target_conf_filename != NULL) xfree(target_conf_filename);
1581 if (target_conf != NULL) freePtsConfig(target_conf);