OSDN Git Service

cleanup
[openpts/openpts.git] / src / aru.c
1 /*
2  * This file is part of the OpenPTS project.
3  *
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.
8  *
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)
12  * any later version.
13  *
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.
18  *
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.
22  */
23
24 /**
25  * \file src/aru.c
26  * \brief FSM action for Auto RM Update (ARU)
27  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
28  * @date 2011-01-11
29  * cleanup 2012-01-05 SM
30  *
31  * 2011-02-28 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 
34  *   attestation.
35  *   Thus, we have to maintain the ARU info in the conf. e.g reset ARU info
36  *   before used within other ctx.
37  *
38  *   ARU Cycle
39  *     IML -> FSM -> ARU info -> update operation -> IML
40  *
41  *   So. The test is not easy.
42  *
43  */
44
45
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49
50 #include <netdb.h>
51 #include <errno.h>
52
53 #define __USE_GNU
54 #include <search.h>  // hash table
55
56 #include <sys/types.h>
57 #include <sys/socket.h>
58 #include <sys/stat.h>
59 #include <netinet/in.h>
60 #include <unistd.h>
61 #include <fcntl.h>
62
63 #include <sys/wait.h>  // Linux waitpid
64
65 #include <openssl/sha.h>
66
67 #include <openpts.h>
68
69 /**
70  * New 
71  */
72 OPENPTS_UPDATE_CONTEXT *newUpdateCtx() {
73     OPENPTS_UPDATE_CONTEXT *ctx;
74     int i, j;
75
76     ctx = xmalloc(sizeof(OPENPTS_UPDATE_CONTEXT));
77     if (ctx == NULL) {
78         LOG(LOG_ERR, "no memory");
79         return NULL;
80     }
81     memset(ctx, 0, sizeof(OPENPTS_UPDATE_CONTEXT));
82
83     for (i = 0; i < MAX_PCRNUM; i++) {
84         for (j = 0; j < MAX_SSLEVEL; j++) {
85             ctx->snapshot[i][j] = NULL;
86         }
87     }
88
89     return ctx;
90 }
91
92 /**
93  * New
94  */
95 OPENPTS_UPDATE_SNAPSHOT *newUpdateSnapshot() {
96     OPENPTS_UPDATE_SNAPSHOT *uss;
97
98     uss = xmalloc(sizeof(OPENPTS_UPDATE_SNAPSHOT));
99     if (uss == NULL) {
100         LOG(LOG_ERR, "no memory");
101         return NULL;
102     }
103     memset(uss, 0, sizeof(OPENPTS_UPDATE_SNAPSHOT));
104
105     return uss;
106 }
107
108 /**
109  * Free
110  */
111 void freeUpdateSnapshot(OPENPTS_UPDATE_SNAPSHOT *uss) {
112     xfree(uss);
113 }
114
115 /**
116  * Free
117  */
118 void freeUpdateCtx(OPENPTS_UPDATE_CONTEXT* ctx) {
119     xfree(ctx);
120 }
121
122
123 /* subset of action.c */
124
125
126 /**
127  * reset FSM in snapshot for FSM update
128  *  BHV -> init
129  *  BIN -> Free
130  */
131 int resetFsm(OPENPTS_SNAPSHOT *ss) {
132     /* check */
133     if (ss == NULL) {
134         LOG(LOG_ERR, "null input");
135         return PTS_FATAL;
136     }
137
138     /* free event wrapper chain */
139     if (ss->start != NULL) {
140         freeEventWrapperChain(ss->start);
141         ss->start = NULL;
142     }
143
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;
148
149         /* just reset the FSM to initial state */
150         fsm_behaviour->curr_state = NULL;
151         fsm_behaviour->status = 0;
152
153         while (fsm_trans != NULL) {
154             fsm_trans->event_num = 0;
155             fsm_trans = fsm_trans->next;
156         }
157     }
158
159     if (ss->fsm_binary != NULL) {
160         /* free FSM-BIN */
161         freeFsmContext(ss->fsm_binary);
162         ss->fsm_binary = NULL;
163     }
164
165     /* reset PCR */
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);
169
170     ss->event_num = 0;
171
172
173     return PTS_SUCCESS;
174 }
175
176 /**
177  * doAction - startUpdate
178  *
179  * allocate OPENPTS_UPDATE_SNAPSHOT
180  */
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;
189     int event_num;
190     int update_type;
191     int data_length;
192
193     DEBUG_CAL("startUpdate() - start\n");
194
195     /* check input */
196     if (ctx == NULL) {
197         LOG(LOG_ERR, "null input\n");
198         return PTS_FATAL;
199     }
200     conf = ctx->conf;
201     if (conf == NULL) {
202         LOG(LOG_ERR, "null input\n");
203         return PTS_FATAL;
204     }
205     /* check conf */
206     if (conf->enable_aru == 0) {
207         /* disabled */
208         return PTS_SUCCESS;
209     }
210     /* clear flag */
211     conf->target_newrm_exist = 0;
212
213     /* check */
214     if (eventWrapper == NULL) {
215         LOG(LOG_ERR, "null input");
216         return PTS_FATAL;
217     }
218     event = eventWrapper->event;
219     if (event == NULL) {
220         LOG(LOG_ERR, "null input");
221         return PTS_FATAL;
222     }
223
224     if (event->ulEventLength <= 20) {  // TODO sizeof
225         LOG(LOG_ERR, "startUpdate() - bad eventdata\n");
226         return PTS_FATAL;
227     }
228     if (event->rgbEvent == NULL) {
229         LOG(LOG_ERR, "null input");
230         return PTS_FATAL;
231     }
232     if (conf->update == NULL) {
233         LOG(LOG_ERR, "null input");
234         return PTS_FATAL;
235     }
236
237     update = (OPENPTS_UPDATE_CONTEXT *) conf->update;
238     start = (OPENPTS_EVENT_UPDATE_START *) event->rgbEvent;
239
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);
247     } else {
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;
253     }
254
255     DEBUG("Update pcr=%08x level=%08x count=%d endian=%d",
256         target_pcr_index,
257         target_snapshot_level,
258         event_num,
259         ctx->conf->iml_endian);
260
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;
265     }
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;
270     }
271
272     /* set current target to OPENPTS_UPDATE_CONTEXT */
273     update->target_pcr_index = target_pcr_index;
274     update->target_snapshot_level = target_snapshot_level;
275
276     /* setup OPENPTS_UPDATE_SNAPSHOT */
277     if (update->snapshot
278             [target_pcr_index]
279             [target_snapshot_level] == NULL) {
280         /* 1st update of this PCR/Level */
281         /* malloc OPENPTS_UPDATE_SNAPSHOT */
282         uss = newUpdateSnapshot();
283         if (uss == NULL) {
284             LOG(LOG_ERR, "newUpdateSnapshot() fail");
285             return PTS_FATAL;
286         }
287     } else {
288         /* already exist => replace  */
289         /* free Old SS */
290         // TODO reset  previous OPENPTS_UPDATE_SNAPSHOT
291         DEBUG("OPENPTS_UPDATE_SNAPSHOT exist, reset this\n");
292         uss = update->snapshot
293                 [target_pcr_index]
294                 [target_snapshot_level];
295     }
296
297     uss->start = start;
298     uss->event_count = 0;
299     uss->update_count++;
300     uss->ew_start_update = eventWrapper;
301
302     update->snapshot
303         [target_pcr_index]
304         [target_snapshot_level] = uss;
305
306     conf->update_exist = 1;
307     DEBUG_CAL("startUpdate() - update exit\n");
308
309     return PTS_SUCCESS;
310 }
311
312 /**
313  * doAction - deputyEvent
314  */
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;
321
322     DEBUG_CAL("deputyEvent() - start\n");
323
324     /* check input */
325     if (ctx == NULL) {
326         LOG(LOG_ERR, "null input\n");
327         return PTS_FATAL;
328     }
329     conf = ctx->conf;
330     if (conf == NULL) {
331         LOG(LOG_ERR, "null input\n");
332         return PTS_FATAL;
333     }
334
335     /* check conf */
336     if (ctx->conf->enable_aru == 0) {
337         /* SKIP */
338         return PTS_SUCCESS;
339     }
340
341     /* check */
342     if (eventWrapper == NULL) {
343         LOG(LOG_ERR, "null input");
344         return PTS_FATAL;
345     }
346     event = eventWrapper->event;
347     if (event == NULL) {
348         LOG(LOG_ERR, "null input");
349         return PTS_FATAL;
350     }
351     update = conf->update;
352     if (update == NULL) {
353         LOG(LOG_ERR, "null input");
354         return PTS_FATAL;
355     }
356
357     /* OPENPTS_UPDATE_SNAPSHOT */
358     uss = update->snapshot
359             [update->target_pcr_index]
360             [update->target_snapshot_level];
361     if (uss == NULL) {
362         LOG(LOG_ERR, "null input");
363         return PTS_FATAL;
364     }
365
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;
371     } else {
372         /* other events */
373         uss->ew_deputy_last = eventWrapper;
374     }
375     uss->event_count++;
376
377     return rc;
378 }
379
380 /**
381  * doAction - endUpdate
382  */
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;
389     int event_num;
390
391     DEBUG_CAL("endUpdate() - start\n");
392
393     /* check input */
394     if (ctx == NULL) {
395         LOG(LOG_ERR, "null input\n");
396         return PTS_FATAL;
397     }
398     conf = ctx->conf;
399     if (conf == NULL) {
400         LOG(LOG_ERR, "null input\n");
401         return PTS_FATAL;
402     }
403
404     /* check conf */
405     if (conf->enable_aru == 0) {
406         /* SKIP */
407         DEBUG("endUpdate() - done(skip), conf->enable_aru == 0\n");
408         return PTS_SUCCESS;
409     }
410
411     // TODO find the last aru event set
412     /* Set flag for Update */
413     conf->update_exist = 1;
414     DEBUG("endUpdate() - update exist\n");
415
416     /* check */
417     if (eventWrapper == NULL) {
418         LOG(LOG_ERR, "null input");
419         return PTS_FATAL;
420     }
421     event = eventWrapper->event;
422     if (event == NULL) {
423         LOG(LOG_ERR, "null input");
424         return PTS_FATAL;
425     }
426     update = conf->update;
427     if (update == NULL) {
428         LOG(LOG_ERR, "null input");
429         return PTS_FATAL;
430     }
431
432     uss = update->snapshot
433             [update->target_pcr_index]
434             [update->target_snapshot_level];
435     if (uss == NULL) {
436         LOG(LOG_ERR, "null input");
437         return PTS_FATAL;
438     }
439
440     /* start structure */
441     start = uss->start;
442     if (start == NULL) {
443         LOG(LOG_ERR, "null input");
444         return PTS_FATAL;
445     }
446
447     // Convert the Endian
448     if (ctx->conf->iml_endian != 0) {
449         event_num = b2l(start->event_num);
450     } else {
451         event_num = start->event_num;
452     }
453
454     uss->ew_end_update = eventWrapper;
455
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;
462     }
463
464     return PTS_SUCCESS;
465 }
466
467 /**
468  * doAction - updateCollector
469  */
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;
474
475     DEBUG("updateCollector() - start\n");
476
477     /* check input */
478     if (ctx == NULL) {
479         LOG(LOG_ERR, "null input\n");
480         return PTS_FATAL;
481     }
482     conf = ctx->conf;
483     if (conf == NULL) {
484         LOG(LOG_ERR, "null input\n");
485         return PTS_FATAL;
486     }
487
488     /* check */
489     if (eventWrapper == NULL) {
490         LOG(LOG_ERR, "null input");
491         return PTS_FATAL;
492     }
493     event = eventWrapper->event;
494     if (event == NULL) {
495         LOG(LOG_ERR, "null input");
496         return PTS_FATAL;
497     }
498
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;
504     }
505
506     /* Event Data */
507     update = (OPENPTS_EVENT_COLLECTOR_UPDATE *)event->rgbEvent;
508
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");
514             return PTS_FATAL;
515         }
516     }
517     memcpy(conf->target_newrm_uuid, &update->new_manifest_uuid, sizeof(PTS_UUID));
518
519     /* Already processed => Clear Update FLag  */
520     conf->update_exist = 0;
521
522     /* Notification for Verifier side */
523     conf->target_newrm_exist = 1;
524
525     /* re-set PCR */
526     // TODO if TCDS was restart, the eventlog used by PTSCD was gone.
527
528     DEBUG("updateCollector() - done, clear update_exist flag\n");
529
530     return PTS_SUCCESS;
531 }
532
533
534 /**
535  *  updateSnapshot
536  *
537  *
538  * Before
539  *         E    E    E
540  *         |    |    |
541  *   SS -> W -> W -> W          - Original PCR4
542  *
543  *    W -> W -> W -> W -> W     - Update PCR11
544  *    |    |    |    |    |
545  *    E    E    E    E    E
546  *    S    1    2    3    E
547  *
548  * Delete target chain
549  *
550  *   SS ->                      - Original PCR4
551  *
552  *    W -> W -> W -> W -> W     - Update PCR11
553  *    |    |    |    |    |
554  *    E    E    E    E    E
555  *    S    1    2    3    E
556  *
557  * Move update to target location
558  *
559  *         E    E    E
560  *         |    |    |
561  *   SS -> W -> W -> W          - Original PCR4
562  *
563  *    W ----------------> W     - Update PCR11
564  *    |                   |
565  *    E                   E
566  *    S                   E
567  *
568  *
569  *
570  */
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;
575     int count = 0;
576     int rc = 0;
577     int target_pcr_index;
578     int target_snapshot_level;
579     int event_num;
580     int update_type;
581     int data_length;
582
583     DEBUG_CAL("updateSnapshot() - start, pcr=%d level=%d  %d events exist!!!\n", i, j, uss->event_count);
584
585     /* check input */
586     if (ctx == NULL) {
587         LOG(LOG_ERR, "null input");
588         return PTS_FATAL;
589     }
590     if (uss == NULL) {
591         LOG(LOG_ERR, "null input");
592         return PTS_FATAL;
593     }
594
595
596     /* start structure */
597     start = uss->start;
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);
605     } else {
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;
611     }
612
613     /* update target snaposhot */
614     ss =  getSnapshotFromTable(ctx->ss_table, i, j);
615     if (NULL == ss) {
616         LOG(LOG_ERR, "null snapshot\n");
617         return PTS_FATAL;
618     }
619
620     // TODO remove fillowing counters
621     ss->update_num++;
622     ctx->ss_table->update_num[ss->level]++;
623     ctx->update_num++;
624
625     // DEBUG("Update by FSM %s\n", ss->fsm_behavior->uml_file);
626     // verbose |= DEBUG_FSM_FLAG;
627
628     // Step 1. getIml() - IML --> BHV-FSM --> SS->eventWrapper chain
629     // Step 2. writeAllCoreValue() in rm.c -  SS->eventWrapper chain -> BIN-FSM is generated
630
631     /* reset/free target snapshot */
632     // delete EW chain, delete BIN-FSM
633     resetFsm(ss);  // fsm.c
634
635     /* update type */
636     if (update_type == UPDATE_IPL_IMAGE) {
637         /* get iml.ipl.maxcount value from eventdata */
638         UINT32 *pnum;
639         UINT32 num;
640         char buf[BUF_SIZE];
641
642         pnum = (UINT32 *)start->data;
643         num = *pnum;
644         if (ctx->conf->iml_endian != 0) {
645             num = b2l(num);
646         }
647 #ifdef AIX
648         /* WORK NEEDED: I guess that bosrenew should really pass in all IPL events including the final one */
649         num++;
650 #endif
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);
654     }
655
656     /* IML -> BHV-FSM */
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,
670                 target_pcr_index,
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;
678             rc = PTS_SUCCESS;
679
680             /* Move to next level (0->1) */
681             incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
682         } else if (rc == OPENPTS_FSM_SUCCESS) {
683             /* OK */
684             rc = PTS_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;
689
690             /* Move to next level (0->1) */
691             incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
692             break;
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;
697
698             /* Move to next level (0->1) */
699             incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
700             break;
701         } else {
702             LOG(LOG_ERR, "updateFsm rc=%d\n", rc);
703         }
704
705         /* update SS chain */
706         if (ss->event_num == 0) {
707             /* First event */
708             ss->start = eventWrapper;
709             ss->end = eventWrapper;
710         } else {
711             /* else - last */
712             ss->end->next_pcr = eventWrapper;
713             ss->end = eventWrapper;
714         }
715
716         ss->event_num++;
717         rc = OPENPTS_FSM_MIGRATE_EVENT;
718
719         eventWrapper = eventWrapper->next_pcr;
720         count++;
721     }
722     // TODO check count
723     // TODO cut EW <-> event link
724
725     /* EW link */
726     /* Target end EW -> end */
727     uss->ew_deputy_last->next_all = NULL;
728     uss->ew_deputy_last->next_pcr = NULL;
729
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;
733
734     /* Snapshot (Update, PCR11) event couner */
735     ss = uss->ew_start_update->snapshot;
736     ss->event_num = ss->event_num - count;
737
738     return rc;
739 }
740
741 /**
742  * Extend Collector Update Event
743  * type 0x85 (133)
744  */
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];
749     SHA_CTX sha_ctx;
750
751     /*check */
752     if (conf == NULL) {
753         LOG(LOG_ERR, "null input\n");
754         return PTS_FATAL;
755     }
756     if (conf->newrm_uuid == NULL) {
757         LOG(LOG_ERR, "null input\n");
758         return PTS_FATAL;
759     }
760     if (conf->newrm_uuid->uuid == NULL) {
761         LOG(LOG_ERR, "null input\n");
762         return PTS_FATAL;
763     }
764
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");
769         return PTS_FATAL;
770     }
771     event = xmalloc_assert(sizeof(TSS_PCR_EVENT));
772     if (event == NULL) {
773         LOG(LOG_ERR, "no memory\n");
774         xfree(collector_update);
775         return PTS_FATAL;
776     }
777
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);
782
783     /* get PCR value*/
784     // memcpy(&collector_start->pcr_value;
785     // readPcr(conf->openpts_pcr_index, pcr);
786
787     /* calc digest */
788     SHA1_Init(&sha_ctx);
789     SHA1_Update(
790         &sha_ctx,
791         collector_update,
792         sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE));
793     SHA1_Final(pcr, &sha_ctx);
794
795     /* fill eventlog */
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;
803
804     /* extend */
805     extendEvent(event);
806
807     /* free */
808     xfree(collector_update);
809     xfree(event);
810
811     return PTS_SUCCESS;
812 }
813
814
815 /**
816  * Update Manifest
817  *
818  *  Update events must be a simple event chain (atmic)
819  *
820  */
821 int updateSnapshots(OPENPTS_CONTEXT *ctx) {
822     int rc = 0;
823     OPENPTS_CONFIG *conf;
824     OPENPTS_UPDATE_CONTEXT *update;
825     OPENPTS_UPDATE_SNAPSHOT *uss;
826     int i, j;
827
828     DEBUG_CAL("updateSnapshots() - start\n");
829
830     /* check input */
831     if (ctx == NULL) {
832         LOG(LOG_ERR, "null input\n");
833         return PTS_FATAL;
834     }
835     conf = ctx->conf;
836     if (conf == NULL) {
837         LOG(LOG_ERR, "null input\n");
838         return PTS_FATAL;
839     }
840
841
842     if (conf->update_exist == 0) {
843         LOG(LOG_TODO, "updateSnapshots() - done, no update\n");
844         return PTS_SUCCESS;
845     }
846
847     update = (OPENPTS_UPDATE_CONTEXT *)conf->update;
848     if (update == NULL) {
849         LOG(LOG_ERR, "null input\n");
850         return PTS_FATAL;
851     }
852
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];
857             if (uss != NULL) {
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");
863                     // TODO free
864                     freeUpdateSnapshot(update->snapshot[i][j]);
865                     update->snapshot[i][j] = NULL;
866                 }  // uss count > 0
867             }  // uss
868         }  // level
869     }  // pcr
870
871     return rc;
872 }
873
874 /**
875  * main function
876  *
877  * Automatically update the manifest by update events in the IML 
878  *
879  * subset of collector.c, called by
880  *
881  *  command
882  *    ptscd -u -m "OS update to X.X.X"
883  *
884  *  init.d
885  *    killproc ptscd  -HUP
886  *
887  */
888 int update(
889     OPENPTS_CONFIG *conf,
890     int prop_count,
891     OPENPTS_PROPERTY *prop_start,
892     OPENPTS_PROPERTY *prop_end,
893     int remove) {
894
895     int rc = PTS_SUCCESS;
896     OPENPTS_CONTEXT *ctx;
897
898     DEBUG_CAL("update() - start\n");
899
900     /* check */
901     if (conf == NULL) {
902         LOG(LOG_ERR, "null input\n");
903         return PTS_FATAL;
904     }
905
906     /* ctx for init */
907     ctx = newPtsContext(conf);
908     if (ctx == NULL) {
909         LOG(LOG_ERR, "no memory");
910         return PTS_FATAL;
911     }
912
913     /* add property */
914     if (prop_count > 0) {
915         /* check */
916         if (prop_start == NULL) {
917             LOG(LOG_ERR, "null input\n");
918             return PTS_FATAL;
919         }
920         if (prop_end == NULL) {
921             LOG(LOG_ERR, "null input\n");
922             return PTS_FATAL;
923         }
924         ctx->prop_start = prop_start;
925         ctx->prop_end   = prop_end;
926         ctx->prop_count = prop_count;
927     }
928
929     addPropertiesFromConfig(conf, ctx);
930
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
937
938     /* List RMs */
939     getRmList(conf, conf->config_dir);  // uuid.c
940
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, "                          ");
945
946
947     if (remove == 1) {
948         /* delete old RM sets */
949         OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_PURGE_RM, "Purge the renewed manifests\n"));
950         purgeRenewedRm(conf);  // uuid.c
951     }
952
953     /* read FSM */
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;
958         goto free;
959     }
960
961     /* read IML to fill the BIOS binary measurement, and translate BHV->BIN FSM */
962
963     /* enable aru */
964     conf->enable_aru = 1;
965     conf->update_exist = 0;
966     /* prepare Update */
967     if (conf->update != NULL) {
968         freeUpdateCtx((OPENPTS_UPDATE_CONTEXT*)conf->update);
969     }
970     conf->update = (void *) newUpdateCtx();
971
972     /* OK, now ready to read IML */
973
974     /* load current IML using FSMs */
975     if (conf->iml_mode == 0) {  // TODO use def
976 #ifdef CONFIG_NO_TSS
977         LOG(LOG_ERR, "update() - Build with --without-tss. iml.mode=tss is not supported\n");
978 #else
979         rc = getIml(ctx, 0);
980         rc = getPcr(ctx);
981
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! */
986         rc = PTS_SUCCESS;
987 #endif
988     } else if (conf->iml_mode == 1) {
989         // TODO change to generic name?  conf->iml_filename[0]  conf->iml_filename[1]
990         /* from  securityfs */
991         /* BIOS IML */
992         rc = readBiosImlFile(
993                 ctx,
994                 conf->bios_iml_filename,
995                 conf->iml_endian);
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);
1001             goto free;
1002         }
1003
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 */
1007             int count;
1008             rc = readImaImlFile(
1009                     ctx,
1010                     conf->runtime_iml_filename,
1011                     conf->runtime_iml_type, 0, &count);  // TODO endian?
1012             if (rc < 0) {
1013                 LOG(LOG_ERR, "read IMA IML, %s has failed\n", conf->runtime_iml_filename);
1014                 rc = PTS_INTERNAL_ERROR;
1015                 goto free;
1016             }
1017         }
1018     } else {
1019         LOG(LOG_ERR, "unknown IML mode, %d\n", conf->iml_mode);
1020     }
1021
1022     /* get SMBIOS data */
1023
1024     /* update exist */
1025     // TODO change to good message
1026     if (conf->update_exist > 0) {
1027         int i, j;
1028
1029         /* Update the Manifests */
1030         rc = updateSnapshots(ctx);
1031         if (rc != PTS_SUCCESS) {
1032             LOG(LOG_ERR, "update() - updateSnapshots fail\n");
1033             goto free;
1034         }
1035
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);
1044             // TODO
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) {
1048             /* gen new UUID */
1049             rc = genOpenptsUuid(conf->newrm_uuid);
1050             // TODO
1051         } else if (conf->newrm_uuid->status == OPENPTS_UUID_FILLED) {
1052             /* change UUID */
1053             rc = genOpenptsUuid(conf->newrm_uuid);
1054             // TODO
1055         } else if (conf->newrm_uuid->status == OPENPTS_UUID_CHANGED) {
1056             /* change UUID again */
1057             rc = genOpenptsUuid(conf->newrm_uuid);
1058             // TODO
1059         } else {
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);
1062             rc = PTS_FATAL;
1063             goto free;
1064         }
1065
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);
1075
1076         /* RM set DIR */
1077         rc = makeNewRmSetDir(conf);
1078         if (rc != PTS_SUCCESS) {
1079             LOG(LOG_ERR, "mkdir of RM set dir was failed\n");
1080             goto free;
1081         }
1082
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
1086         // TODO check
1087
1088
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) {
1093                 /* update exist */
1094                 for (j = 0; j < MAX_PCRNUM; j++) {
1095                     OPENPTS_SNAPSHOT *ss;
1096                         ss =  getSnapshotFromTable(
1097                                 ctx->ss_table,
1098                                 j,
1099                                 i);
1100                     if (ss != NULL) {
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);
1104                         }
1105                     }
1106                 }
1107                 /* create new RM */
1108                 DEBUG("update() - writeRm %s\n", conf->newrm_filename[i]);
1109                 rc = writeRm(ctx, conf->newrm_filename[i], i);
1110                 if (rc < 0) {
1111                     LOG(LOG_ERR, "write RM, %s was failed\n", conf->newrm_filename[i]);
1112                     rc = PTS_INTERNAL_ERROR;
1113                     goto free;
1114                 }
1115             } else {
1116                 /*no update, just copy the RM to new RM set dir*/
1117                 // TODO just copy
1118                 DEBUG("update() - dowriteRm %s\n", conf->newrm_filename[i]);
1119                 rc = writeRm(ctx, conf->newrm_filename[i], i);
1120                 if (rc < 0) {
1121                     LOG(LOG_ERR, "write RM, %s was failed\n", conf->newrm_filename[i]);
1122                     rc = PTS_INTERNAL_ERROR;
1123                     goto free;
1124                 }
1125             }
1126         }
1127
1128         /* Extend Collector Update event */
1129         rc = extendEvCollectorUpdate(conf);
1130         if (rc != PTS_SUCCESS) {
1131             LOG(LOG_ERR, "updateSnapshots() - extendEvCollectorUpdate fail\n");
1132             goto free;
1133         }
1134         OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_SUCCESS,
1135             "Successfully updated the reference manifests\n\n"));
1136     } else {
1137         OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_NONE,
1138             "There is no update.\n\n"));
1139     }
1140
1141   free:
1142     if ( rc != PTS_SUCCESS ) {
1143         ERROR(NLS(MS_OPENPTS, OPENPTS_UPDATE_FAILED,
1144             "Failed to update the reference manifests\n"));
1145     }
1146
1147     if ( NULL != ctx ) {
1148         /* free */
1149         freePtsContext(ctx);
1150     }
1151
1152     /* disable aru */
1153     conf->enable_aru = 0;
1154
1155     DEBUG("update() - done\n");
1156
1157     return rc;
1158 }
1159
1160 /**
1161  *
1162  */
1163 static int diffFileAgainstCache(char *fileName, int len, BYTE *contents) {
1164     int rc = PTS_FATAL;
1165     struct stat statBuf;
1166     int fd = open(fileName, O_RDONLY);
1167
1168     if (fd == -1) {
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);
1175     } else {
1176         int totalBytesRead = 0;
1177         while (1) {
1178             char page[4096];
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);
1182                 break;
1183             } else if (bytesRead == 0) {
1184                 if (totalBytesRead != len) {
1185                     LOG(LOG_ERR, "Finished reading from file prematurely, still expecting data.");
1186                     return PTS_FATAL;
1187                 }
1188                 rc = PTS_SUCCESS;
1189                 break;
1190             } else {
1191                 totalBytesRead += bytesRead;
1192                 if (totalBytesRead > len) {
1193                     LOG(LOG_ERR, "Read more data from RM file than expected.");
1194                     return PTS_FATAL;
1195                 }
1196                 DEBUG("Read %ld bytes, total = %d out of %d\n", bytesRead, totalBytesRead, len);
1197
1198                 if ( 0 != memcmp(page, contents, bytesRead) ) {
1199                     break;
1200                 }
1201
1202                 contents += bytesRead;
1203             }
1204         }
1205     }
1206
1207     if (fd != -1) {
1208         close(fd);
1209     }
1210
1211     return rc;
1212 }
1213
1214 /**
1215  *
1216  */
1217 int isNewRmStillValid(OPENPTS_CONTEXT *ctx, char *conf_dir) {
1218     int rc = PTS_FATAL;
1219     BYTE *newRmSet;
1220
1221     char *str_collector_uuid;
1222     char *str_rm_uuid;
1223     char *str_newrm_uuid;
1224
1225     char *str_verifier_uuid;
1226     char buf[BUF_SIZE];
1227     int i;
1228
1229     char * collector_dir;
1230     char * rm_dir;
1231     OPENPTS_CONFIG *conf;
1232
1233     // TODO get from list
1234     OPENPTS_CONFIG *target_conf = NULL;
1235
1236     /* check */
1237     if (ctx == NULL) {
1238         LOG(LOG_ERR, "null input\n");
1239         return PTS_FATAL;
1240     }
1241     conf = ctx->conf;
1242     if (conf == NULL) {
1243         LOG(LOG_ERR, "null input\n");
1244         return PTS_FATAL;
1245     }
1246
1247
1248     /* version */
1249     // TODO
1250
1251     newRmSet = conf->newRmSet;
1252     if (newRmSet == NULL) {
1253         LOG(LOG_ERR, "null input\n");
1254         return PTS_FATAL;
1255     }
1256     target_conf = ctx->target_conf;
1257     if (target_conf == NULL) {
1258         LOG(LOG_ERR, "null input\n");
1259         return PTS_FATAL;
1260     }
1261     if (target_conf->uuid == NULL) {
1262         LOG(LOG_ERR, "null input\n");
1263         return PTS_FATAL;
1264     }
1265     if (target_conf->rm_uuid == NULL) {
1266         LOG(LOG_ERR, "null input\n");
1267         return PTS_FATAL;
1268     }
1269
1270     /* UUID strings */
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)) {
1277         return -1;
1278     }
1279
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);
1283
1284     /* Setup the dir for the collector */
1285     collector_dir = getFullpathName(conf_dir, str_collector_uuid);
1286
1287     DEBUG("conf_dir %s\n", conf_dir);
1288     DEBUG("collector_dir %s\n", collector_dir);
1289
1290     /* RIMM -> CTX */
1291     {
1292         int num;
1293         int len;
1294         PTS_UUID *newrm_uuid = (PTS_UUID *)newRmSet;
1295
1296         newRmSet += 16;  // TODO
1297         str_newrm_uuid = getStringOfUuid(newrm_uuid);
1298         DEBUG("Collector new RM UUID %s\n", str_newrm_uuid);
1299
1300         /* Setup DIR */
1301
1302         rm_dir = getFullpathName(collector_dir, str_newrm_uuid);
1303
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);
1313             goto out;
1314         }
1315
1316         rc = checkDir(rm_dir);
1317         if (rc != PTS_SUCCESS) {
1318             DEBUG("isNewRmStillValid() - New RM doesn't exist, UUID = %s\n", str_collector_uuid);
1319             goto out;
1320         }
1321
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);
1325
1326         /* num */
1327         num = getUint32(newRmSet);
1328         DEBUG("RM num %d\n", num);
1329         newRmSet += 4;
1330
1331         if (num > MAX_RM_NUM) {
1332             LOG(LOG_ERR, "Bad NUM %d\n", num);
1333             goto out;
1334         }
1335
1336         /* Get RMs  */
1337         for (i = 0; i < num; i++) {
1338             /* RM file*/
1339             snprintf(buf, BUF_SIZE, "%s/%s/rm%d.xml",
1340                 collector_dir,
1341                 str_newrm_uuid,
1342                 i);
1343             DEBUG("RM[%d]          : %s\n", i, buf);
1344
1345             len = getUint32(newRmSet);
1346             DEBUG("RM[%d] len %d -> %s\n", i, len, buf);
1347
1348             newRmSet += 4;
1349
1350             rc = diffFileAgainstCache(buf, len, newRmSet);
1351             if (0 != rc) {
1352                 DEBUG("New RM file '%s' is now invalidated\n", buf);
1353                 goto out;
1354             }
1355             DEBUG("New RM file '%s' matches cached contents from collector\n", buf);
1356
1357             newRmSet += len;
1358         }
1359     }
1360
1361     rc = PTS_SUCCESS;  // OK
1362
1363   out:
1364     xfree(str_newrm_uuid);
1365
1366     return rc;
1367 }
1368
1369 /**
1370  * updateNewRm
1371  *
1372  * get target NEW RMs before reboot :-)
1373  *
1374  * Function Test
1375  *
1376  *   file         test
1377  *   ----------------------------------
1378  *   
1379  */
1380 int updateNewRm(OPENPTS_CONTEXT *ctx, char *host, char *conf_dir) {
1381     int rc;
1382
1383     BYTE *newRmSet;
1384     char *rm_filename[MAX_RM_NUM];
1385
1386     char *str_collector_uuid;
1387     char *str_rm_uuid;
1388
1389     OPENPTS_UUID *newrm_uuid;
1390
1391     char *str_verifier_uuid;
1392     char buf[BUF_SIZE];
1393     int i;
1394
1395     char * collector_dir;
1396     char * rm_dir;
1397     OPENPTS_CONFIG *conf;
1398
1399     // TODO get from list
1400     char *target_conf_filename = NULL;
1401     OPENPTS_CONFIG *target_conf = NULL;
1402
1403     /* check */
1404     if (ctx == NULL) {
1405         LOG(LOG_ERR, "null input\n");
1406         return PTS_FATAL;
1407     }
1408     conf = ctx->conf;
1409     if (conf == NULL) {
1410         LOG(LOG_ERR, "null input\n");
1411         return PTS_FATAL;
1412     }
1413
1414     /* version */
1415     // TODO
1416
1417     newRmSet = conf->newRmSet;
1418     if (newRmSet == NULL) {
1419         LOG(LOG_ERR, "null input\n");
1420         return PTS_FATAL;
1421     }
1422     if (ctx->target_conf == NULL) {
1423         LOG(LOG_ERR, "null input\n");
1424         return PTS_FATAL;
1425     }
1426     if (ctx->target_conf->uuid == NULL) {
1427         LOG(LOG_ERR, "null input\n");
1428         return PTS_FATAL;
1429     }
1430     if (ctx->target_conf->rm_uuid == NULL) {
1431         LOG(LOG_ERR, "null input\n");
1432         return PTS_FATAL;
1433     }
1434
1435     /* UUID strings */
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;
1443         goto out;
1444     }
1445
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);
1449
1450     /* Setup the dir for the collector */
1451     collector_dir = getFullpathName(conf_dir, str_collector_uuid);
1452
1453     DEBUG("conf_dir %s\n", conf_dir);
1454     DEBUG("collector_dir %s\n", collector_dir);
1455
1456     /* target conf */
1457     target_conf_filename = getFullpathName(collector_dir, "target.conf");
1458     target_conf = newPtsConfig();
1459     // TODO check
1460     rc = readTargetConf(target_conf, target_conf_filename);
1461     if (rc != PTS_SUCCESS) {
1462         LOG(LOG_ERR, "updateNewRm() - readTargetConf failed\n");
1463         // TODO so?
1464     }
1465
1466     /* RIMM -> CTX */
1467     {
1468         int num;
1469         int len;
1470
1471         /* UUID */
1472         newrm_uuid = newOpenptsUuid2((PTS_UUID *)newRmSet);
1473         newRmSet += 16;  // TODO
1474         DEBUG("Collector new RM UUID %s\n", newrm_uuid->str);
1475
1476         /* Setup DIR */
1477
1478         rm_dir = getFullpathName(collector_dir, newrm_uuid->str);
1479
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;
1492             goto out;
1493         }
1494
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);
1503             rc = PTS_FATAL;
1504             goto out;*/
1505         } else {
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;
1512                 goto out;
1513             }
1514         }
1515
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");
1521
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);
1525
1526         /* num */
1527         num = getUint32(newRmSet);
1528         DEBUG("RM num %d\n", num);
1529         newRmSet += 4;
1530
1531         if (num >  MAX_RM_NUM) {
1532             LOG(LOG_ERR, "Bad NUM %d\n", num);
1533             rc = PTS_INTERNAL_ERROR;
1534             goto out;
1535         }
1536
1537         /* Get RMs  */
1538         DEBUG("get %d new RMs\n", num);
1539         target_conf->newrm_num = num;
1540         for (i = 0; i < num; i++) {
1541             /* RM file*/
1542             snprintf(buf, BUF_SIZE, "%s/%s/rm%d.xml",
1543                 collector_dir,
1544                 newrm_uuid->str,
1545                 i);
1546             rm_filename[i] = smalloc_assert(buf);
1547             DEBUG("RM[%d]          : %s\n", i, rm_filename[i]);
1548
1549             len = getUint32(newRmSet);
1550             DEBUG("RM[%d] len %d -> %s\n", i, len, rm_filename[i]);
1551
1552             newRmSet += 4;
1553
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]);
1557                 goto out;
1558             }
1559             target_conf->rm_filename[i] = smalloc_assert(rm_filename[i]);
1560
1561             newRmSet += len;
1562         }
1563
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
1570     }
1571
1572     /* save target conf */
1573     // TODO need to updade?
1574     // writeTargetConf(ctx->conf, collector_uuid, target_conf_filename);  // ctx.c
1575
1576     rc = PTS_SUCCESS;  // OK
1577
1578   out:
1579     /* free */
1580     if (target_conf_filename != NULL) xfree(target_conf_filename);
1581     if (target_conf != NULL) freePtsConfig(target_conf);
1582
1583     return rc;
1584 }
1585
1586