OSDN Git Service

3adae64e68f83a767911ad8c644f1f3d8ec6ce81
[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 2011-01-22 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("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     // DEBUG("StartUpdate\n");
241     // printHex("UpdateEvent ", (BYTE*) start, sizeof(OPENPTS_EVENT_UPDATE_START), "\n");
242
243     // Convert the Endian
244     if (ctx->conf->iml_endian != 0) {
245         target_pcr_index = b2l(start->target_pcr_index);
246         target_snapshot_level = b2l(start->target_snapshot_level);
247         event_num = b2l(start->event_num);
248         update_type = b2l(start->update_type);
249         data_length = b2l(start->data_length);
250     } else {
251         target_pcr_index = start->target_pcr_index;
252         target_snapshot_level = start->target_snapshot_level;
253         event_num = start->event_num;
254         update_type = start->update_type;
255         data_length = start->data_length;
256     }
257
258     DEBUG("Update pcr=%08x level=%08x count=%d endian=%d",
259         target_pcr_index,
260         target_snapshot_level,
261         event_num,
262         ctx->conf->iml_endian);
263
264     if (target_pcr_index >= MAX_PCRNUM) {
265         LOG(LOG_ERR, "startUpdate() - Bad PCR index %d 0x%08x\n",
266             target_pcr_index, target_pcr_index);
267         return PTS_INTERNAL_ERROR;
268     }
269     if (target_snapshot_level >= MAX_SSLEVEL) {
270         LOG(LOG_ERR, "startUpdate() - Bad SS Level %d 0x%08x\n",
271             target_snapshot_level, target_snapshot_level);
272         return PTS_INTERNAL_ERROR;
273     }
274
275     /* set current target to OPENPTS_UPDATE_CONTEXT */
276     update->target_pcr_index = target_pcr_index;
277     update->target_snapshot_level = target_snapshot_level;
278
279
280     /* setup OPENPTS_UPDATE_SNAPSHOT */
281     if (update->snapshot
282             [target_pcr_index]
283             [target_snapshot_level] == NULL) {
284         /* 1st update of this PCR/Level */
285         // OPENPTS_UPDATE_SNAPSHOT
286         /* malloc OPENPTS_UPDATE_SNAPSHOT */
287         // uss = xmalloc(sizeof(OPENPTS_UPDATE_SNAPSHOT));
288         uss = newUpdateSnapshot();
289         if (uss == NULL) {
290             return PTS_INTERNAL_ERROR;
291         }
292         // memset(uss, 0, sizeof(OPENPTS_UPDATE_SNAPSHOT));
293     } else {
294         /* already exist => replace  */
295         /* free Old SS */
296         // TODO reset  previous OPENPTS_UPDATE_SNAPSHOT
297         DEBUG("OPENPTS_UPDATE_SNAPSHOT exist, reset this\n");
298         uss = update->snapshot
299                 [target_pcr_index]
300                 [target_snapshot_level];
301     }
302
303     uss->start = start;
304     uss->event_count = 0;
305     uss->update_count++;
306     uss->ew_start_update = eventWrapper;
307
308     update->snapshot
309         [target_pcr_index]
310         [target_snapshot_level] = uss;
311
312     conf->update_exist = 1;
313     DEBUG("startUpdate() - update exit\n");
314
315     return PTS_SUCCESS;
316 }
317
318 /**
319  * doAction - deputyEvent
320  */
321 int deputyEvent(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
322     TSS_PCR_EVENT *event;
323     OPENPTS_UPDATE_CONTEXT *update;
324     int rc = PTS_SUCCESS;
325     OPENPTS_CONFIG *conf;
326     OPENPTS_UPDATE_SNAPSHOT *uss;
327
328     DEBUG_CAL("deputyEvent() - start\n");
329
330     /* check input */
331     if (ctx == NULL) {
332         LOG(LOG_ERR, "null input\n");
333         return PTS_FATAL;
334     }
335     conf = ctx->conf;
336     if (conf == NULL) {
337         LOG(LOG_ERR, "null input\n");
338         return PTS_FATAL;
339     }
340
341     /* check conf */
342     if (ctx->conf->enable_aru == 0) {
343         /* SKIP */
344         return PTS_SUCCESS;
345     }
346
347     /* check */
348     if (eventWrapper == NULL) {
349         LOG(LOG_ERR, "null input");
350         return PTS_FATAL;
351     }
352     event = eventWrapper->event;
353     if (event == NULL) {
354         LOG(LOG_ERR, "null input");
355         return PTS_FATAL;
356     }
357     update = conf->update;
358     if (update == NULL) {
359         LOG(LOG_ERR, "null input");
360         return PTS_FATAL;
361     }
362
363     /* OPENPTS_UPDATE_SNAPSHOT */
364     uss = update->snapshot
365             [update->target_pcr_index]
366             [update->target_snapshot_level];
367     if (uss == NULL) {
368         LOG(LOG_ERR, "null input");
369         return PTS_FATAL;
370     }
371
372     /* copy to update[] */
373     if (uss->event_count == 0) {
374         /* link to 1st event */
375         uss->ew_deputy_first = eventWrapper;
376         uss->ew_deputy_last = eventWrapper;
377     } else {
378         /* other events */
379         uss->ew_deputy_last = eventWrapper;
380     }
381     uss->event_count++;
382
383     return rc;
384 }
385
386 /**
387  * doAction - endUpdate
388  */
389 int endUpdate(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
390     TSS_PCR_EVENT *event;
391     OPENPTS_UPDATE_CONTEXT *update;
392     OPENPTS_UPDATE_SNAPSHOT *uss;
393     OPENPTS_CONFIG *conf;
394     OPENPTS_EVENT_UPDATE_START *start;
395     int event_num;
396
397     DEBUG("endUpdate() - start\n");
398
399     /* check input */
400     if (ctx == NULL) {
401         LOG(LOG_ERR, "null input\n");
402         return PTS_FATAL;
403     }
404     conf = ctx->conf;
405     if (conf == NULL) {
406         LOG(LOG_ERR, "null input\n");
407         return PTS_FATAL;
408     }
409
410     /* check conf */
411     if (conf->enable_aru == 0) {
412         /* SKIP */
413         DEBUG("endUpdate() - done(skip), conf->enable_aru == 0\n");
414         return PTS_SUCCESS;
415     }
416
417     // TODO find the last aru event set
418     /* Set flag for Update */
419     conf->update_exist = 1;
420     DEBUG("endUpdate() - update exist\n");
421
422     /* check */
423     if (eventWrapper == NULL) {
424         LOG(LOG_ERR, "null input");
425         return PTS_FATAL;
426     }
427     event = eventWrapper->event;
428     if (event == NULL) {
429         LOG(LOG_ERR, "null input");
430         return PTS_FATAL;
431     }
432     update = conf->update;
433     if (update == NULL) {
434         LOG(LOG_ERR, "null input");
435         return PTS_FATAL;
436     }
437
438     uss = update->snapshot
439             [update->target_pcr_index]
440             [update->target_snapshot_level];
441     if (uss == NULL) {
442         LOG(LOG_ERR, "null input");
443         return PTS_FATAL;
444     }
445
446     /* start structure */
447     start = uss->start;
448     if (start == NULL) {
449         LOG(LOG_ERR, "null input");
450         return PTS_FATAL;
451     }
452
453     // Convert the Endian
454     if (ctx->conf->iml_endian != 0) {
455         event_num = b2l(start->event_num);
456     } else {
457         event_num = start->event_num;
458     }
459
460     uss->ew_end_update = eventWrapper;
461
462     /* check the event num */
463     if (uss->event_count != event_num) {
464         /* actual event number is different with the number in start event */
465         LOG(LOG_ERR, "number of events (%08x) are not same with definition at start (%08x), BAD eventlog?\n",
466             uss->event_count, event_num);
467         return PTS_INVALID_SNAPSHOT;
468     }
469
470     return PTS_SUCCESS;
471 }
472
473 /**
474  * doAction - updateCollector
475  */
476 int updateCollector(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
477     // int rc = PTS_SUCCESS;
478     TSS_PCR_EVENT *event;
479     OPENPTS_EVENT_COLLECTOR_UPDATE *update = NULL;
480     OPENPTS_CONFIG *conf;
481
482     DEBUG("updateCollector() - start\n");
483
484     /* check input */
485     if (ctx == NULL) {
486         LOG(LOG_ERR, "null input\n");
487         return PTS_FATAL;
488     }
489     conf = ctx->conf;
490     if (conf == NULL) {
491         LOG(LOG_ERR, "null input\n");
492         return PTS_FATAL;
493     }
494
495     /* check */
496     if (eventWrapper == NULL) {
497         LOG(LOG_ERR, "null input");
498         return PTS_FATAL;
499     }
500     event = eventWrapper->event;
501     if (event == NULL) {
502         LOG(LOG_ERR, "null input");
503         return PTS_FATAL;
504     }
505
506     if (event->ulEventLength != sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE)) {
507         LOG(LOG_ERR, "updateCollector() - Bad eventData size %d != %d\n",
508             event->ulEventLength,
509             sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE));
510         return PTS_INVALID_SNAPSHOT;
511     }
512
513     /* Event Data */
514     update = (OPENPTS_EVENT_COLLECTOR_UPDATE *)event->rgbEvent;
515
516     /* save RM_UUID to conf */
517     if (conf->target_newrm_uuid == NULL) {
518         conf->target_newrm_uuid = xmalloc(sizeof(PTS_UUID));
519         if (NULL == conf->target_newrm_uuid) {
520             LOG(LOG_ERR, "no memory");
521             return PTS_FATAL;
522         }
523     }
524     memcpy(conf->target_newrm_uuid, &update->new_manifest_uuid, sizeof(PTS_UUID));
525
526     /* Already processed => Clear Update FLag  */
527     conf->update_exist = 0;
528
529     /* Notification for Verifier side */
530     conf->target_newrm_exist = 1;
531
532     /* re-set PCR */
533     // TODO if TCDS was restart, the eventlog used by PTSCD was gone.
534
535     DEBUG("updateCollector() - done, clear update_exist flag\n");
536
537     return PTS_SUCCESS;
538 }
539
540
541 /**
542  *  updateSnapshot
543  *
544  *
545  * Before
546  *         E    E    E
547  *         |    |    |
548  *   SS -> W -> W -> W          - Original PCR4
549  *
550  *    W -> W -> W -> W -> W     - Update PCR11
551  *    |    |    |    |    |
552  *    E    E    E    E    E
553  *    S    1    2    3    E
554  *
555  * Delete target chain
556  *
557  *   SS ->                      - Original PCR4
558  *
559  *    W -> W -> W -> W -> W     - Update PCR11
560  *    |    |    |    |    |
561  *    E    E    E    E    E
562  *    S    1    2    3    E
563  *
564  * Move update to target location
565  *
566  *         E    E    E
567  *         |    |    |
568  *   SS -> W -> W -> W          - Original PCR4
569  *
570  *    W ----------------> W     - Update PCR11
571  *    |                   |
572  *    E                   E
573  *    S                   E
574  *
575  *
576  *
577  */
578 int updateSnapshot(OPENPTS_CONTEXT *ctx, OPENPTS_UPDATE_SNAPSHOT *uss, int i, int j) {
579     OPENPTS_SNAPSHOT *ss;
580     OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
581     OPENPTS_EVENT_UPDATE_START *start;
582     int count = 0;
583     int rc = 0;
584     int target_pcr_index;
585     int target_snapshot_level;
586     int event_num;
587     int update_type;
588     int data_length;
589
590     DEBUG_CAL("updateSnapshot() - start, pcr=%d level=%d  %d events exist!!!\n", i, j, uss->event_count);
591
592     /* check input */
593     if (ctx == NULL) {
594         LOG(LOG_ERR, "null input");
595         return PTS_FATAL;
596     }
597     if (uss == NULL) {
598         LOG(LOG_ERR, "null input");
599         return PTS_FATAL;
600     }
601
602
603     /* start structure */
604     start = uss->start;
605     // Convert the Endian
606     if (ctx->conf->iml_endian != 0) {
607         target_pcr_index = b2l(start->target_pcr_index);
608         target_snapshot_level = b2l(start->target_snapshot_level);
609         event_num = b2l(start->event_num);
610         update_type = b2l(start->update_type);
611         data_length = b2l(start->data_length);
612     } else {
613         target_pcr_index = start->target_pcr_index;
614         target_snapshot_level = start->target_snapshot_level;
615         event_num = start->event_num;
616         update_type = start->update_type;
617         data_length = start->data_length;
618     }
619
620     /* update target snaposhot */
621     ss =  getSnapshotFromTable(ctx->ss_table, i, j);
622     if (NULL == ss) {
623         LOG(LOG_ERR, "null snapshot\n");
624         return PTS_FATAL;
625     }
626
627     // TODO remove fillowing counters
628     ss->update_num++;
629     ctx->ss_table->update_num[ss->level]++;
630     ctx->update_num++;
631
632     // DEBUG("Update by FSM %s\n", ss->fsm_behavior->uml_file);
633     // verbose |= DEBUG_FSM_FLAG;
634
635     // Step 1. getIml() - IML --> BHV-FSM --> SS->eventWrapper chain
636     // Step 2. writeAllCoreValue() in rm.c -  SS->eventWrapper chain -> BIN-FSM is generated
637
638     /* reset/free target snapshot */
639     // delete EW chain, delete BIN-FSM
640     resetFsm(ss);  // fsm.c
641
642     /* update type */
643     if (update_type == UPDATE_IPL_IMAGE) {
644         /* get iml.ipl.maxcount value from eventdata */
645         UINT32 *pnum;
646         UINT32 num;
647         char buf[BUF_SIZE];
648
649         pnum = (UINT32 *)start->data;
650         num = *pnum;
651         if (ctx->conf->iml_endian != 0) {
652             num = b2l(num);
653         }
654 #ifdef AIX
655         /* WORK NEEDED: I guess that bosrenew should really pass in all IPL events including the final one */
656         num++;
657 #endif
658         LOG(LOG_INFO, "UPDATE_IPL_IMAGE  iml.ipl.maxcount=%d (0x%x)\n", num, num);
659         snprintf(buf, BUF_SIZE, "%d", num);
660         setProperty(ctx, "iml.ipl.maxcount", buf);
661     }
662
663     /* IML -> BHV-FSM */
664     eventWrapper = uss->ew_deputy_first;
665     while ((eventWrapper != NULL) && (count < uss->event_count)) {
666         /*Change PCR index */
667         eventWrapper->event->ulPcrIndex = i;
668         /* set sw->ss link */
669         rc = updateFsm(ctx, ss->fsm_behavior, eventWrapper);  // TODO ignore the pcr_index
670         if (rc == OPENPTS_FSM_ERROR) {
671             /* FSM detect invalid IML, or bad FSM for this IML */
672             DEBUG("[RM%02d-PCR%02d] updateFsm() => OPENPTS_FSM_ERROR   ===>  rc=PTS_INVALID_SNAPSHOT, added Reason\n",
673                 target_snapshot_level, target_pcr_index);
674             addReason(ctx, target_pcr_index, NLS(MS_OPENPTS, OPENPTS_ARU_IML_VALIDATION_FAILED,
675                            "[RM%02d-PCR%02d] IML validation by FSM has failed. State='%s' at the FSM is '%s'"),
676                 target_snapshot_level,
677                 target_pcr_index,
678                 ss->fsm_behavior->curr_state->name,
679                 ss->fsm_behavior->uml_file);
680             ctx->ss_table->error[start->target_pcr_index] = PTS_INVALID_SNAPSHOT;
681             rc = PTS_INVALID_SNAPSHOT;
682         } else if (rc == OPENPTS_FSM_FINISH) {
683             /* OK, FSM finish successfly */
684             ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
685             rc = PTS_SUCCESS;
686
687             /* Move to next level (0->1) */
688             incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
689         } else if (rc == OPENPTS_FSM_SUCCESS) {
690             /* OK */
691             rc = PTS_SUCCESS;
692         } else if (rc == OPENPTS_FSM_TRANSIT) {
693             // TRANSIT, Skip update SS chain
694             // TODO set by updateFsm
695             ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
696
697             /* Move to next level (0->1) */
698             incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
699             // goto end;
700             break;
701         } else if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
702             // TRANSIT, Skip update SS chain
703             // TODO set by updateFsm
704             ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
705
706             /* Move to next level (0->1) */
707             incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
708             // goto end;
709             break;
710         } else {
711             LOG(LOG_ERR, "updateFsm rc=%d\n", rc);
712         }
713
714         /* update SS chain */
715         if (ss->event_num == 0) {
716             /* First event */
717             ss->start = eventWrapper;
718             ss->end = eventWrapper;
719         } else {
720             /* else - last */
721             ss->end->next_pcr = eventWrapper;
722             ss->end = eventWrapper;
723         }
724
725         ss->event_num++;
726         // update->event_count++;
727         rc = OPENPTS_FSM_MIGRATE_EVENT;
728
729         eventWrapper = eventWrapper->next_pcr;
730         count++;
731         // TODO count
732     }
733     // TODO check count
734     // TODO cut EW <-> event link
735
736     /* EW link */
737     /* Target end EW -> end */
738     uss->ew_deputy_last->next_all = NULL;
739     uss->ew_deputy_last->next_pcr = NULL;
740
741     /* Update start->end */
742     uss->ew_start_update->next_all = uss->ew_end_update;
743     uss->ew_start_update->next_pcr = uss->ew_end_update;
744
745     /* Snapshot (Update, PCR11) event couner */
746     ss = uss->ew_start_update->snapshot;
747     ss->event_num = ss->event_num - count;
748
749     return rc;
750 }
751
752 /**
753  * Extend Collector Update Event
754  * type 0x85 (133)
755  */
756 int extendEvCollectorUpdate(OPENPTS_CONFIG *conf) {
757     TSS_PCR_EVENT* event;  // /usr/include/tss/tss_structs.h
758     OPENPTS_EVENT_COLLECTOR_UPDATE *collector_update;
759     BYTE pcr[SHA1_DIGEST_SIZE];
760     SHA_CTX sha_ctx;
761
762     /*check */
763     if (conf == NULL) {
764         LOG(LOG_ERR, "null input\n");
765         return PTS_FATAL;
766     }
767     if (conf->newrm_uuid == NULL) {
768         LOG(LOG_ERR, "null input\n");
769         return PTS_FATAL;
770     }
771     if (conf->newrm_uuid->uuid == NULL) {
772         LOG(LOG_ERR, "null input\n");
773         return PTS_FATAL;
774     }
775
776     /* malloc eventlog */
777     collector_update = xmalloc_assert(sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE));
778     event = xmalloc_assert(sizeof(TSS_PCR_EVENT));
779
780     /* fill collector_start */
781     memcpy(&collector_update->pts_version, &conf->pts_version, 4);
782     memcpy(&collector_update->collector_uuid, conf->uuid->uuid, 16);
783     memcpy(&collector_update->new_manifest_uuid, conf->newrm_uuid->uuid, 16);
784
785     /* get PCR value*/
786     // memcpy(&collector_start->pcr_value;
787     // readPcr(conf->openpts_pcr_index, pcr);
788
789     /* calc digest */
790     SHA1_Init(&sha_ctx);
791     SHA1_Update(
792         &sha_ctx,
793         collector_update,
794         sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE));
795     SHA1_Final(pcr, &sha_ctx);
796
797     /* fill eventlog */
798     // event->versionInfo  // set by TSP?
799     event->ulPcrIndex       = conf->openpts_pcr_index;  // set by TSP?
800     event->eventType        = EV_COLLECTOR_UPDATE;  // openpts_tpm.h
801     event->ulPcrValueLength = SHA1_DIGEST_SIZE;
802     event->rgbPcrValue      = pcr;
803     event->ulEventLength    = sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE);
804     event->rgbEvent         = (BYTE *) collector_update;
805
806     /* extend */
807     extendEvent(event);
808
809     /* free */
810     xfree(collector_update);
811     xfree(event);
812
813     return PTS_SUCCESS;
814 }
815
816
817 /**
818  * Update Manifest
819  *
820  *  Update events must be a simple event chain (atmic)
821  *
822  */
823 int updateSnapshots(OPENPTS_CONTEXT *ctx) {
824     int rc = 0;
825     OPENPTS_CONFIG *conf;
826     OPENPTS_UPDATE_CONTEXT *update;
827     OPENPTS_UPDATE_SNAPSHOT *uss;
828     int i, j;
829
830     DEBUG_CAL("updateSnapshots() - start\n");
831
832     /* check input */
833     if (ctx == NULL) {
834         LOG(LOG_ERR, "null input\n");
835         return PTS_FATAL;
836     }
837     conf = ctx->conf;
838     if (conf == NULL) {
839         LOG(LOG_ERR, "null input\n");
840         return PTS_FATAL;
841     }
842
843
844     if (conf->update_exist == 0) {
845         LOG(LOG_TODO, "updateSnapshots() - done, no update\n");
846         return PTS_SUCCESS;
847     }
848
849     update = (OPENPTS_UPDATE_CONTEXT *)conf->update;
850     if (update == NULL) {
851         LOG(LOG_ERR, "null input\n");
852         return PTS_FATAL;
853     }
854
855     for (i = 0; i < MAX_PCRNUM; i++) {
856         for (j = 0; j < MAX_SSLEVEL; j++) {
857             // DEBUG("updateSnapshots() - %d %d\n", i, j);
858             uss = update->snapshot[i][j];
859             if (uss != NULL) {
860                 // DEBUG("updateSnapshots() - %p\n", uss);
861                 // DEBUG("updateSnapshots() - %p %d %d\n", uss, uss->event_count, uss->update_count);
862                 if (uss->event_count > 0) {
863                     updateSnapshot(ctx, uss, i, j);
864                     DEBUG("free OPENPTS_UPDATE_SNAPSHOT\n");
865                     // TODO free
866                     freeUpdateSnapshot(update->snapshot[i][j]);
867                     update->snapshot[i][j] = NULL;
868                 }  // uss count > 0
869             }  // uss
870         }  // level
871     }  // pcr
872
873     return rc;
874 }
875
876 /**
877  * main function
878  *
879  * Automatically update the manifest by update events in the IML 
880  *
881  * subset of collector.c, called by
882  *
883  *  command
884  *    ptscd -u -m "OS update to X.X.X"
885  *
886  *  init.d
887  *    killproc ptscd  -HUP
888  *
889  */
890 int update(
891     OPENPTS_CONFIG *conf,
892     int prop_count,
893     OPENPTS_PROPERTY *prop_start,
894     OPENPTS_PROPERTY *prop_end,
895     int remove) {
896
897     int rc = PTS_SUCCESS;
898     OPENPTS_CONTEXT *ctx;
899
900     DEBUG_CAL("update() - start\n");
901
902     /* check */
903     if (conf == NULL) {
904         LOG(LOG_ERR, "null input\n");
905         return PTS_FATAL;
906     }
907
908     /* ctx for init */
909     ctx = newPtsContext(conf);
910     if (ctx == NULL) {
911         LOG(LOG_ERR, "no memory");
912         return PTS_FATAL;
913     }
914
915     /* add property */
916     if (prop_count > 0) {
917         /* check */
918         if (prop_start == NULL) {
919             LOG(LOG_ERR, "null input\n");
920             return PTS_FATAL;
921         }
922         if (prop_end == NULL) {
923             LOG(LOG_ERR, "null input\n");
924             return PTS_FATAL;
925         }
926         ctx->prop_start = prop_start;
927         ctx->prop_end   = prop_end;
928         ctx->prop_count = prop_count;
929     }
930
931     addPropertiesFromConfig(conf, ctx);
932
933     /* UUID of this platform */
934     OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_PLATFORM_UUID,
935         "Platform UUID: %s\n"), conf->uuid->str);
936     OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_RM_UUID,
937         "Reference manifest UUID: %s\n"), conf->rm_uuid->str);
938     // OUTPUT("RM UUID (for next boot)     : %s\n", conf->newrm_uuid->str);  // NULL
939
940     /* List RMs */
941     getRmList(conf, conf->config_dir);  // uuid.c
942
943     OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_RM_LIST,
944         "List of reference manifest sets: %d reference manifest sets in config dir\n"),
945         conf->rmsets->rmset_num);
946     printRmList(conf, "                          ");
947
948
949     if (remove == 1) {
950         /* delete old RM sets */
951         OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_PURGE_RM, "Purge the renewed manifests\n"));
952         purgeRenewedRm(conf);  // uuid.c
953     }
954
955     /* read FSM */
956     rc = readFsmFromPropFile(ctx, conf->config_file);
957     if (rc != PTS_SUCCESS) {
958         LOG(LOG_ERR, "update() - read FSM failed\n");
959         rc = PTS_INTERNAL_ERROR;
960         goto free;
961     }
962
963     /* read IML to fill the BIOS binary measurement, and translate BHV->BIN FSM */
964
965     /* enable aru */
966     conf->enable_aru = 1;
967     conf->update_exist = 0;
968     /* prepare Update */
969     if (conf->update != NULL) {
970         freeUpdateCtx((OPENPTS_UPDATE_CONTEXT*)conf->update);
971     }
972     conf->update = (void *) newUpdateCtx();
973
974     /* OK, now ready to read IML */
975
976     /* load current IML using FSMs */
977     if (conf->iml_mode == 0) {  // TODO use def
978 #ifdef CONFIG_NO_TSS
979         LOG(LOG_ERR, "update() - Build with --without-tss. iml.mode=tss is not supported\n");
980 #else
981         rc = getIml(ctx, 0);
982         rc = getPcr(ctx);
983
984         /* WORK NEEDED: The above return value could be a positive number for an error or
985                         a positive number for the pcr or event number. There is no way to
986                         discover success or failure. I will assume success and hope log files
987                         contain some useful information! */
988         rc = PTS_SUCCESS;
989 #endif
990     } else if (conf->iml_mode == 1) {
991         // TODO change to generic name?  conf->iml_filename[0]  conf->iml_filename[1]
992         /* from  securityfs */
993         /* BIOS IML */
994         rc = readBiosImlFile(
995                 ctx,
996                 conf->bios_iml_filename,
997                 conf->iml_endian);
998         if (rc != PTS_SUCCESS) {
999             DEBUG("readBiosImlFile() was failed\n");
1000             OUTPUT(NLS(MS_OPENPTS, OPENPTS_ARU_ERROR_READING_BIOS_IML,
1001                 "An error occured while reading the bios iml file.\n"));
1002             printReason(ctx, 0);
1003             goto free;
1004         }
1005
1006         /* RUNTIME IML (Linux-IMA) */
1007         if (conf->runtime_iml_filename != NULL) {
1008             /* count seems to be ignored in most places so we ignore it too */
1009             int count;
1010             rc = readImaImlFile(
1011                     ctx,
1012                     conf->runtime_iml_filename,
1013                     conf->runtime_iml_type, 0, &count);  // TODO endian?
1014             if (rc < 0) {
1015                 LOG(LOG_ERR, "read IMA IML, %s has failed\n", conf->runtime_iml_filename);
1016                 rc = PTS_INTERNAL_ERROR;
1017                 goto free;
1018             }
1019         }
1020     } else {
1021         LOG(LOG_ERR, "unknown IML mode, %d\n", conf->iml_mode);
1022     }
1023
1024     /* get SMBIOS data */
1025
1026     /* update exist */
1027     // TODO change to good message
1028     if (conf->update_exist > 0) {
1029         int i, j;
1030
1031         /* Update the Manifests */
1032         rc = updateSnapshots(ctx);
1033         if (rc != PTS_SUCCESS) {
1034             LOG(LOG_ERR, "update() - updateSnapshots fail\n");
1035             goto free;
1036         }
1037
1038         /* new UUID for this RM set */
1039         if (conf->newrm_uuid == NULL) {
1040             LOG(LOG_INFO, "conf->newrm_uuid == NULL, generate new reference manifest UUID\n");
1041             conf->newrm_uuid = newOpenptsUuid();  // empty
1042             conf->newrm_uuid->filename =  getFullpathName(conf->config_dir, "newrm_uuid");
1043             DEBUG("conf->newrm_uuid->filename %s\n", conf->newrm_uuid->filename);
1044             conf->newrm_uuid->status = OPENPTS_UUID_FILENAME_ONLY;
1045             rc = genOpenptsUuid(conf->newrm_uuid);
1046             // TODO
1047             // conf->str_newrm_uuid = getStringOfUuid(conf->newrm_uuid);
1048             // conf->time_newrm_uuid = getDateTimeOfUuid(conf->newrm_uuid);
1049         } else if (conf->newrm_uuid->status == OPENPTS_UUID_FILENAME_ONLY) {
1050             /* gen new UUID */
1051             rc = genOpenptsUuid(conf->newrm_uuid);
1052             // TODO
1053         } else if (conf->newrm_uuid->status == OPENPTS_UUID_FILLED) {
1054             /* change UUID */
1055             rc = genOpenptsUuid(conf->newrm_uuid);
1056             // TODO
1057         } else if (conf->newrm_uuid->status == OPENPTS_UUID_CHANGED) {
1058             /* change UUID again */
1059             rc = genOpenptsUuid(conf->newrm_uuid);
1060             // TODO
1061         } else {
1062             LOG(LOG_ERR, "update() - conf->newrm_uuid->status %d\n", conf->newrm_uuid->status);
1063             LOG(LOG_ERR, "update() - use given reference manifest UUID %s (for test)\n", conf->rm_uuid->str);
1064             rc = PTS_FATAL;
1065             goto free;
1066         }
1067
1068         OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_GENERATE_UUID,
1069             "Generate UUID (for new reference manifests): %s \n"), conf->newrm_uuid->str);
1070         OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_DATE, "   Date and Time: %04d-%02d-%02d-%02d:%02d:%02d\n"),
1071             conf->newrm_uuid->time->year + 1900,
1072             conf->newrm_uuid->time->mon + 1,
1073             conf->newrm_uuid->time->mday,
1074             conf->newrm_uuid->time->hour,
1075             conf->newrm_uuid->time->min,
1076             conf->newrm_uuid->time->sec);
1077
1078         /* RM set DIR */
1079         rc = makeNewRmSetDir(conf);
1080         if (rc != PTS_SUCCESS) {
1081             LOG(LOG_ERR, "mkdir of RM set dir was failed\n");
1082             goto free;
1083         }
1084
1085         /* save UUID for next boot */
1086         DEBUG("writeOpenptsUuidFile %s %s\n", conf->newrm_uuid->str, conf->newrm_uuid->filename);
1087         rc = writeOpenptsUuidFile(conf->newrm_uuid, 1);  // overwrite
1088         // TODO check
1089
1090
1091         /* check the snapshot level to be updated */
1092         for (i= 0;i < conf->newrm_num; i++) {
1093             /* check each RM level */
1094             if (ctx->ss_table->update_num[i] > 0) {
1095                 /* update exist */
1096                 for (j = 0; j < MAX_PCRNUM; j++) {
1097                     OPENPTS_SNAPSHOT *ss;
1098                         ss =  getSnapshotFromTable(
1099                                 ctx->ss_table,
1100                                 j,
1101                                 i);
1102                     if (ss != NULL) {
1103                         if (ss->update_num > 0) {
1104                             OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_RM_DETAIL,
1105                                    "Update RM%02d-PCR%02d (%d update(s) in update events)\n"), i, j, ss->update_num);
1106                         }
1107                     }
1108                 }
1109                 /* create new RM */
1110                 DEBUG("update() - writeRm %s\n", conf->newrm_filename[i]);
1111                 rc = writeRm(ctx, conf->newrm_filename[i], i);
1112                 if (rc < 0) {
1113                     LOG(LOG_ERR, "write RM, %s was failed\n", conf->newrm_filename[i]);
1114                     rc = PTS_INTERNAL_ERROR;
1115                     goto free;
1116                 }
1117             } else {
1118                 /*no update, just copy the RM to new RM set dir*/
1119                 // TODO just copy
1120                 DEBUG("update() - dowriteRm %s\n", conf->newrm_filename[i]);
1121                 rc = writeRm(ctx, conf->newrm_filename[i], i);
1122                 if (rc < 0) {
1123                     LOG(LOG_ERR, "write RM, %s was failed\n", conf->newrm_filename[i]);
1124                     rc = PTS_INTERNAL_ERROR;
1125                     goto free;
1126                 }
1127             }
1128         }
1129
1130         /* Extend Collector Update event */
1131         rc = extendEvCollectorUpdate(conf);
1132         if (rc != PTS_SUCCESS) {
1133             LOG(LOG_ERR, "updateSnapshots() - extendEvCollectorUpdate fail\n");
1134             goto free;
1135         }
1136         OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_SUCCESS,
1137             "Successfully updated the reference manifests\n\n"));
1138     } else {
1139         OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_NONE,
1140             "There is no update.\n\n"));
1141     }
1142
1143   free:
1144     if ( rc != PTS_SUCCESS ) {
1145         ERROR(NLS(MS_OPENPTS, OPENPTS_UPDATE_FAILED,
1146             "Failed to update the reference manifests\n"));
1147     }
1148
1149     if ( NULL != ctx ) {
1150         /* free */
1151         freePtsContext(ctx);
1152     }
1153
1154     /* disable aru */
1155     conf->enable_aru = 0;
1156
1157     DEBUG("update() - done\n");
1158
1159     return rc;
1160 }
1161
1162 /**
1163  *
1164  */
1165 static int diffFileAgainstCache(char *fileName, int len, BYTE *contents) {
1166     int rc = PTS_FATAL;
1167     struct stat statBuf;
1168     int fd = open(fileName, O_RDONLY);
1169
1170     if (fd == -1) {
1171         LOG(LOG_ERR, "Failed to open '%s', errno %d\n", fileName, errno);
1172     } else if (fstat(fd, &statBuf) == -1) {
1173         LOG(LOG_ERR, "Failed to stat '%s' (fd %d), errno %d\n", fileName, fd, errno);
1174     } else if ( len != statBuf.st_size ) {
1175         DEBUG("File length for pending RM '%s' (%d) does not match cached length (%d) from collector.\n",
1176               fileName, (int)statBuf.st_size, len);
1177     } else {
1178         int totalBytesRead = 0;
1179         while (1) {
1180             char page[4096];
1181             ssize_t bytesRead = read(fd, page, 4096);
1182             if ( -1 == bytesRead ) {
1183                 LOG(LOG_ERR, "Failed to read from fd %d, errno %d\n", fd, errno);
1184                 break;
1185             } else if ( bytesRead == 0) {
1186                 if (totalBytesRead != len) {
1187                     LOG(LOG_ERR, "Finished reading from file prematurely, still expecting data.");
1188                     return PTS_FATAL;
1189                 }
1190                 rc = PTS_SUCCESS;
1191                 break;
1192             } else {
1193                 totalBytesRead += bytesRead;
1194                 if (totalBytesRead > len) {
1195                     LOG(LOG_ERR, "Read more data from RM file than expected.");
1196                     return PTS_FATAL;
1197                 }
1198                 DEBUG("Read %ld bytes, total = %d out of %d\n", bytesRead, totalBytesRead, len);
1199
1200                 if ( 0 != memcmp(page, contents, bytesRead) ) {
1201                     break;
1202                 }
1203
1204                 contents += bytesRead;
1205             }
1206         }
1207     }
1208
1209     if ( fd != -1) {
1210         close(fd);
1211     }
1212
1213     return rc;
1214 }
1215
1216 /**
1217  *
1218  */
1219 int isNewRmStillValid(OPENPTS_CONTEXT *ctx, char *conf_dir) {
1220     int rc = PTS_FATAL;
1221     BYTE *newRmSet;
1222
1223     char *str_collector_uuid;
1224     char *str_rm_uuid;
1225     char *str_newrm_uuid;
1226
1227     char *str_verifier_uuid;
1228     char buf[BUF_SIZE];
1229     int i;
1230
1231     char * collector_dir;
1232     char * rm_dir;
1233     OPENPTS_CONFIG *conf;
1234
1235     // TODO get from list
1236     OPENPTS_CONFIG *target_conf = NULL;
1237
1238     /* check */
1239     if (ctx == NULL) {
1240         LOG(LOG_ERR, "null input\n");
1241         return PTS_FATAL;
1242     }
1243     conf = ctx->conf;
1244     if (conf == NULL) {
1245         LOG(LOG_ERR, "null input\n");
1246         return PTS_FATAL;
1247     }
1248
1249
1250     /* version */
1251     // TODO
1252
1253     newRmSet = conf->newRmSet;
1254     if (newRmSet == NULL) {
1255         LOG(LOG_ERR, "null input\n");
1256         return PTS_FATAL;
1257     }
1258     target_conf = ctx->target_conf;
1259     if (target_conf == NULL) {
1260         LOG(LOG_ERR, "null input\n");
1261         return PTS_FATAL;
1262     }
1263     if (target_conf->uuid == NULL) {
1264         LOG(LOG_ERR, "null input\n");
1265         return PTS_FATAL;
1266     }
1267     if (target_conf->rm_uuid == NULL) {
1268         LOG(LOG_ERR, "null input\n");
1269         return PTS_FATAL;
1270     }
1271
1272     /* UUID strings */
1273     str_collector_uuid = target_conf->uuid->str;
1274     str_rm_uuid = target_conf->rm_uuid->str;
1275     str_verifier_uuid = conf->uuid->str;
1276     if ((str_collector_uuid == NULL) ||
1277         (str_rm_uuid == NULL) ||
1278         (str_verifier_uuid == NULL)) {
1279         return -1;
1280     }
1281
1282     DEBUG("Verifier  UUID    %s\n", str_verifier_uuid);
1283     DEBUG("Collector UUID    %s\n", str_collector_uuid);
1284     DEBUG("Collector RM UUID %s\n", str_rm_uuid);
1285
1286     /* Setup the dir for the collector */
1287     collector_dir = getFullpathName(conf_dir, str_collector_uuid);
1288
1289     DEBUG("conf_dir %s\n", conf_dir);
1290     DEBUG("collector_dir %s\n", collector_dir);
1291
1292     /* RIMM -> CTX */
1293     {
1294         int num;
1295         int len;
1296         PTS_UUID *newrm_uuid = (PTS_UUID *)newRmSet;
1297
1298         newRmSet += 16;  // TODO
1299         str_newrm_uuid = getStringOfUuid(newrm_uuid);
1300         DEBUG("Collector new RM UUID %s\n", str_newrm_uuid);
1301
1302         /* Setup DIR */
1303
1304         rm_dir = getFullpathName(collector_dir, str_newrm_uuid);
1305
1306         rc = checkDir(collector_dir);
1307         if (rc != PTS_SUCCESS) {
1308             /* unknwon collector */
1309             LOG(LOG_ERR, "isNewRmStillValid() - Unknown collector, UUID= %s dir=%s\n",
1310                 str_collector_uuid, collector_dir);
1311             addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_MISSING_COLLECTOR_CONFIG,
1312                 "Missing collector configuration"));
1313             addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_UUID,
1314                 "Collector UUID = %s"), str_collector_uuid);
1315             goto out;
1316         }
1317
1318         rc = checkDir(rm_dir);
1319         if (rc != PTS_SUCCESS) {
1320             DEBUG("isNewRmStillValid() - New RM doesn't exist, UUID = %s\n", str_collector_uuid);
1321             goto out;
1322         }
1323
1324         DEBUG("conf dir         : %s\n", collector_dir);
1325         DEBUG("rm dir           : %s\n", rm_dir);
1326         DEBUG("New RM UUID file : %s\n", target_conf->newrm_uuid->filename);
1327
1328         /* num */
1329         num = getUint32(newRmSet);
1330         DEBUG("RM num %d\n", num);
1331         newRmSet += 4;
1332
1333         if (num > MAX_RM_NUM) {
1334             LOG(LOG_ERR, "Bad NUM %d\n", num);
1335             goto out;
1336         }
1337
1338         /* Get RMs  */
1339         for (i = 0; i < num; i++) {
1340             /* RM file*/
1341             snprintf(buf, BUF_SIZE, "%s/%s/rm%d.xml",
1342                 collector_dir,
1343                 str_newrm_uuid,
1344                 i);
1345             DEBUG("RM[%d]          : %s\n", i, buf);
1346
1347             len = getUint32(newRmSet);
1348             DEBUG("RM[%d] len %d -> %s\n", i, len, buf);
1349
1350             newRmSet += 4;
1351
1352             rc = diffFileAgainstCache(buf, len, newRmSet);
1353             if (0 != rc) {
1354                 DEBUG("New RM file '%s' is now invalidated\n", buf);
1355                 goto out;
1356             }
1357             DEBUG("New RM file '%s' matches cached contents from collector\n", buf);
1358
1359             newRmSet += len;
1360         }
1361     }
1362
1363     rc = PTS_SUCCESS;  // OK
1364
1365   out:
1366     xfree(str_newrm_uuid);
1367
1368     return rc;
1369 }
1370
1371 /**
1372  * updateNewRm
1373  *
1374  * get target NEW RMs before reboot :-)
1375  *
1376  * Function Test
1377  *
1378  *   file         test
1379  *   ----------------------------------
1380  *   
1381  */
1382 int updateNewRm(OPENPTS_CONTEXT *ctx, char *host, char *conf_dir) {
1383     int rc;
1384
1385     BYTE *newRmSet;
1386     char *rm_filename[MAX_RM_NUM];
1387
1388     char *str_collector_uuid;
1389     char *str_rm_uuid;
1390
1391     OPENPTS_UUID *newrm_uuid;
1392
1393     char *str_verifier_uuid;
1394     char buf[BUF_SIZE];
1395     int i;
1396
1397     char * collector_dir;
1398     char * rm_dir;
1399     OPENPTS_CONFIG *conf;
1400
1401     // TODO get from list
1402     char *target_conf_filename = NULL;
1403     OPENPTS_CONFIG *target_conf = NULL;
1404
1405     /* check */
1406     if (ctx == NULL) {
1407         LOG(LOG_ERR, "null input\n");
1408         return PTS_FATAL;
1409     }
1410     conf = ctx->conf;
1411     if (conf == NULL) {
1412         LOG(LOG_ERR, "null input\n");
1413         return PTS_FATAL;
1414     }
1415
1416     /* version */
1417     // TODO
1418
1419     newRmSet = conf->newRmSet;
1420     if (newRmSet == NULL) {
1421         LOG(LOG_ERR, "null input\n");
1422         return PTS_FATAL;
1423     }
1424     if (ctx->target_conf == NULL) {
1425         LOG(LOG_ERR, "null input\n");
1426         return PTS_FATAL;
1427     }
1428     if (ctx->target_conf->uuid == NULL) {
1429         LOG(LOG_ERR, "null input\n");
1430         return PTS_FATAL;
1431     }
1432     if (ctx->target_conf->rm_uuid == NULL) {
1433         LOG(LOG_ERR, "null input\n");
1434         return PTS_FATAL;
1435     }
1436
1437     /* UUID strings */
1438     str_collector_uuid = ctx->target_conf->uuid->str;
1439     str_rm_uuid = ctx->target_conf->rm_uuid->str;
1440     str_verifier_uuid = getStringOfUuid(ctx->conf->uuid->uuid);
1441     if ((str_collector_uuid == NULL) ||
1442         (str_rm_uuid == NULL) ||
1443         (str_verifier_uuid == NULL)) {
1444         rc = PTS_INTERNAL_ERROR;
1445         goto out;
1446     }
1447
1448     DEBUG("Verifier  UUID    %s\n", str_verifier_uuid);
1449     DEBUG("Collector UUID    %s\n", str_collector_uuid);
1450     DEBUG("Collector RM UUID %s\n", str_rm_uuid);
1451
1452     /* Setup the dir for the collector */
1453     collector_dir = getFullpathName(conf_dir, str_collector_uuid);
1454
1455     DEBUG("conf_dir %s\n", conf_dir);
1456     DEBUG("collector_dir %s\n", collector_dir);
1457
1458     /* target conf */
1459     target_conf_filename = getFullpathName(collector_dir, "target.conf");
1460     target_conf = newPtsConfig();
1461     // TODO check
1462     rc = readTargetConf(target_conf, target_conf_filename);
1463     if (rc != PTS_SUCCESS) {
1464         LOG(LOG_ERR, "updateNewRm() - readTargetConf failed\n");
1465         // TODO so?
1466     }
1467
1468     /* RIMM -> CTX */
1469     {
1470         int num;
1471         int len;
1472
1473         /* UUID */
1474         newrm_uuid = newOpenptsUuid2((PTS_UUID *)newRmSet);
1475         newRmSet += 16;  // TODO
1476         DEBUG("Collector new RM UUID %s\n", newrm_uuid->str);
1477
1478         /* Setup DIR */
1479
1480         rm_dir = getFullpathName(collector_dir, newrm_uuid->str);
1481
1482         rc = checkDir(collector_dir);
1483         if (rc != PTS_SUCCESS) {
1484             /* unknwon collector */
1485             LOG(LOG_ERR, "updateNewRm() - Unknown collector, UUID= %s dir=%s\n",
1486                 str_collector_uuid, collector_dir);
1487             addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_MISSING_COLLECTOR_CONFIG,
1488                 "Missing collector configuration"));
1489             addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_HOSTNAME,
1490                 "Collector hostname = %s"), host);
1491             addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_UUID,
1492                 "Collector UUID = %s"), str_collector_uuid);
1493             rc = PTS_NOT_INITIALIZED;
1494             goto out;
1495         }
1496
1497         rc = checkDir(rm_dir);
1498         if (rc == PTS_SUCCESS) {
1499             /* ??? Already Exist */
1500             DEBUG("updateNewRm() - Exist RM, UUID= %s\n", str_collector_uuid);
1501             /*addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_RM_ALREADY_EXISTS, "The Reference Manifest already exists"));
1502             addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_HOSTNAME, "Collector hostname = %s"), host);
1503             addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_UUID, "Collector UUID = %s"), str_collector_uuid);
1504             addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_RM_UUID, "Collector RM UUID = %s"), str_rm_uuid);
1505             rc = PTS_FATAL;
1506             goto out;*/
1507         } else {
1508             /* create new RM dir */
1509             rc = makeDir(rm_dir);
1510             if (rc != PTS_SUCCESS) {
1511                 /* unknwon collector */
1512                 LOG(LOG_ERR, "updateNewRm() - Create New RM dir failed, %s\n", rm_dir);
1513                 rc = PTS_INTERNAL_ERROR;
1514                 goto out;
1515             }
1516         }
1517
1518         // TODO target.conf?
1519         // conf->property_filename = getFullpathName(collector_dir, "vr.properties");
1520         // conf->ir_filename = getFullpathName(collector_dir, "ir.xml");
1521         // conf->prop_filename = getFullpathName(collector_dir, "target.conf");
1522         // conf->newrm_uuid->filename = getFullpathName(collector_dir, "newrm_uuid");
1523
1524         DEBUG("conf dir         : %s\n", collector_dir);
1525         DEBUG("rm dir           : %s\n", rm_dir);
1526         DEBUG("New RM UUID file : %s\n", target_conf->newrm_uuid->filename);
1527
1528         /* num */
1529         num = getUint32(newRmSet);
1530         DEBUG("RM num %d\n", num);
1531         newRmSet += 4;
1532
1533         if (num >  MAX_RM_NUM) {
1534             LOG(LOG_ERR, "Bad NUM %d\n", num);
1535             rc = PTS_INTERNAL_ERROR;
1536             goto out;
1537         }
1538
1539         /* Get RMs  */
1540         DEBUG("get %d new RMs\n", num);
1541         target_conf->newrm_num = num;
1542         for (i = 0; i < num; i++) {
1543             /* RM file*/
1544             snprintf(buf, BUF_SIZE, "%s/%s/rm%d.xml",
1545                 collector_dir,
1546                 newrm_uuid->str,
1547                 i);
1548             rm_filename[i] = smalloc_assert(buf);
1549             DEBUG("RM[%d]          : %s\n", i, rm_filename[i]);
1550
1551             len = getUint32(newRmSet);
1552             DEBUG("RM[%d] len %d -> %s\n", i, len, rm_filename[i]);
1553
1554             newRmSet += 4;
1555
1556             rc = saveToFile(rm_filename[i], len, newRmSet);
1557             if (rc != PTS_SUCCESS) {
1558                 LOG(LOG_ERR, "updateNewRm() - save RM[%d], %s failed\n", i, rm_filename[i]);
1559                 goto out;
1560             }
1561             target_conf->rm_filename[i] = smalloc_assert(rm_filename[i]);
1562
1563             newRmSet += len;
1564         }
1565
1566         /* New RM UUID file */
1567         /* save to newrm_uuid file */
1568         DEBUG("NEWRM %s => %s \n", newrm_uuid->str, target_conf->newrm_uuid->filename);
1569         newrm_uuid->filename = target_conf->newrm_uuid->filename;
1570         newrm_uuid->status = OPENPTS_UUID_FILLED;
1571         rc = writeOpenptsUuidFile(newrm_uuid, 1);  // overwite
1572     }
1573
1574     /* save target conf */
1575     // TODO need to updade?
1576     // writeTargetConf(ctx->conf, collector_uuid, target_conf_filename);  // ctx.c
1577
1578     rc = PTS_SUCCESS;  // OK
1579
1580   out:
1581     /* free */
1582     if (target_conf_filename != NULL) xfree(target_conf_filename);
1583     if (target_conf != NULL) freePtsConfig(target_conf);
1584
1585     // DEBUG("error at verifier\n");
1586     return rc;
1587 }
1588
1589