OSDN Git Service

aix feeadback
[openpts/openpts.git] / src / collector.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) 2010 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/collector.c
26  * \brief TCG IF-M collector functions
27  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
28  * @date 2011-01-06
29  * cleanup 2011-07-20 SM
30  *
31  * move from ptscd.c 
32  *
33  */
34
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <netdb.h>
40 #include <errno.h>
41
42 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>  // inet_ntoa
46 #include <unistd.h>
47 #include <grp.h>
48
49 #include <signal.h>
50
51 #include <sys/stat.h>
52 #include <fcntl.h>
53
54 #include <openssl/sha.h>
55
56 #include <openpts.h>
57
58 /**
59  * print FSM info
60  */
61 void printFsmInfo(OPENPTS_CONTEXT *ctx, char * indent) {
62     int i;
63     OPENPTS_SNAPSHOT *ss;
64
65     OUTPUT(NLS(MS_OPENPTS, OPENPTS_FSM_INFO_HEADER, "%sPCR lv  FSM files\n"), indent);
66     OUTPUT("%s-----------------------------------------------------\n", indent);
67
68     for (i = 0; i < MAX_PCRNUM; i++) {
69         ss = getSnapshotFromTable(ctx->ss_table, i, 0);
70
71         if (ss != NULL) {
72             if (ss->fsm_behavior != NULL) {
73                 OUTPUT("%s%2d  0  ", indent, i);
74                 OUTPUT("%s\n", ss->fsm_behavior->uml_file);
75             }
76         }
77
78         /* level 1 */
79         ss = getSnapshotFromTable(ctx->ss_table, i, 1);
80         if (ss != NULL) {
81             if (ss->fsm_behavior != NULL) {
82                 OUTPUT("%s%2d  1  ", indent, i);
83                 OUTPUT("%s\n", ss->fsm_behavior->uml_file);
84             }
85         }
86     }
87     OUTPUT("%s-----------------------------------------------------\n", indent);
88 }
89
90 /**
91  * EV_COLLECTOR_START
92  *
93  *
94  * ./src/iml2text
95  *  154  11 0x00000080 f7412718d74b9292d33dedc9d946aad7afa5c11b [Unknown Event:size=56] 
96  */
97 int extendEvCollectorStart(OPENPTS_CONFIG *conf) {
98     TSS_PCR_EVENT* event;  // /usr/include/tss/tss_structs.h
99     OPENPTS_EVENT_COLLECTOR_START *collector_start;
100     BYTE pcr[SHA1_DIGEST_SIZE];
101     SHA_CTX sha_ctx;
102
103
104     /* malloc eventlog */
105     collector_start = xmalloc_assert(sizeof(OPENPTS_EVENT_COLLECTOR_START));
106     event = xmalloc_assert(sizeof(TSS_PCR_EVENT));
107
108     /*fill collector_start */
109     memcpy(&collector_start->pts_version, &conf->pts_version, 4);
110     memcpy(&collector_start->collector_uuid, conf->uuid->uuid, 16);
111     memcpy(&collector_start->manifest_uuid, conf->rm_uuid->uuid, 16);
112
113
114     /* get PCR value*/
115     // memcpy(&collector_start->pcr_value;
116     readPcr(conf->openpts_pcr_index, pcr);
117     memcpy(&collector_start->pcr_value, pcr, SHA1_DIGEST_SIZE);
118
119
120     /* calc digest */
121     SHA1_Init(&sha_ctx);
122     SHA1_Update(
123         &sha_ctx,
124         collector_start,
125         sizeof(OPENPTS_EVENT_COLLECTOR_START));
126     SHA1_Final(pcr, &sha_ctx);
127
128     /* fill eventlog */
129     // event->versionInfo  // set by TSP?
130     event->ulPcrIndex = conf->openpts_pcr_index;  // set by TSP?
131     event->eventType = EV_COLLECTOR_START;  // openpts_tpm.h
132     event->ulPcrValueLength = SHA1_DIGEST_SIZE;
133     event->rgbPcrValue = pcr;
134     event->ulEventLength = sizeof(OPENPTS_EVENT_COLLECTOR_START);
135     event->rgbEvent = (BYTE *) collector_start;
136
137     /* extend */
138     extendEvent(event);
139
140     /* free */
141     xfree(collector_start);
142     xfree(event);
143
144     return PTS_SUCCESS;
145 }
146
147
148
149 /**
150  * initialize ptsc
151  *
152  * 1. generate UUID
153  * 2. generate Sign Key (NA)
154  * 3. get platform information, call dmidecode or BIOS IML? (NA)
155  * 4. generate RM
156  * 
157  *
158  * ./src/ptsc -i -c tests/data/Fedora12/ptscd.conf
159  *
160  * Return
161  *  PTS_SUCCESS
162  *  PTS_INTERNAL_ERROR
163  */
164
165 int init(
166     OPENPTS_CONFIG *conf,
167     int prop_count,
168     OPENPTS_PROPERTY *prop_start,
169     OPENPTS_PROPERTY *prop_end) {
170     int rc = PTS_SUCCESS;
171     UINT32 ps_type = TSS_PS_TYPE_SYSTEM;
172     OPENPTS_CONTEXT *ctx = NULL;
173     int i;
174     int keygen = 1;
175     TSS_VERSION tpm_version;
176
177     /* check */
178     if (conf == NULL) {
179         ERROR("FATAL");
180         return PTS_FATAL;
181     }
182     if (conf->uuid == NULL) {
183         ERROR("FATAL");
184         return PTS_FATAL;
185     }
186     if (conf->uuid->filename == NULL) {
187         ERROR("FATAL");
188         return PTS_FATAL;
189     }
190
191     /*
192      * Common misconfigulations
193      *
194      *  1) cannot access the IML through TSS.
195      *     default /etc/tcsd.conf does not configured to access the IML file at
196      *     securityfs.
197      *     => ERROR : OPENPTS_MISSING_IML
198      *
199      *  2) TPM not taken ownership.
200      *     in this case, Keygen was failed
201      *  3) Missing TCS Daemon
202      *     So ptsc can not access TPM/TSS, may got tspi 0x0311 error.
203      *  4) /etc/ptsc.conf did not configured for this platform yet
204      *     missing PCR - Model convination
205      */
206
207     /* Check the existing configulation */
208     rc = checkFile(conf->uuid->filename);
209     if (rc == OPENPTS_FILE_EXISTS) {
210         char *str_uuid;
211         PTS_DateTime *time;
212         /* if UUID file exist => exit, admin must delete the UUID file, then init again */
213         /* check existing UUID */
214         rc = readOpenptsUuidFile(conf->uuid);
215         str_uuid = getStringOfUuid(conf->uuid->uuid);
216         time = getDateTimeOfUuid(conf->uuid->uuid);
217
218         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_UUID_FILE_EXISTS,
219                 "The ptsc has been initialized. "
220                 "If you want to re-intialize the platform, please clear the collector. "
221                 "To see the detail of current ptsc, use ptsc -D. "
222                 "To clear the ptsc, use ptsc -e\n"));
223         OUTPUT("    existing uuid = %s\n", str_uuid);
224         OUTPUT("    creation date = %d-%d-%d\n",
225             time->year + 1900,
226             time->mon + 1,
227             time->mday);
228         /* free */
229         xfree(str_uuid);
230         xfree(time);
231         return PTS_FATAL;  // TODO assign error code
232     }
233
234
235     /* ctx for init */
236     ctx = newPtsContext(conf);
237     if (ctx == NULL) {
238         ERROR("no memory?");
239         return PTS_FATAL;
240     }
241
242     /* add property */
243     if (prop_count > 0) {
244         ctx->prop_start = prop_start;
245         ctx->prop_end = prop_end;
246         ctx->prop_count = prop_count;
247     }
248     addPropertiesFromConfig(conf, ctx);
249
250     /* get TPM and TSS version */
251     rc = getTpmVersion(&tpm_version);
252     if (rc != PTS_SUCCESS) {
253         addReason(ctx, -1,
254             "[PTSC-INIT] Couldn't get the TPM version. Check the TSS and TPM driver.");
255         rc = PTS_FATAL;
256         goto error;
257     }
258
259     /* read FSM */
260     rc = readFsmFromPropFile(ctx, conf->config_file);
261     if (rc != PTS_SUCCESS) {
262         addReason(ctx, -1,
263             "[PTSC-INIT] Couldn't load validation models. Check the ptsc configlation, %s.",
264             conf->config_file);
265         rc = PTS_FATAL;
266         goto error;
267     }
268
269     /* read IML to fill the BIOS binary measurement, and translate BHV->BIN FSM */
270     /* load current IML using FSMs */
271     if (conf->iml_mode == 0) {  // TODO use def
272         rc = getIml(ctx, 0);  // iml.c, return event num
273         if (rc == 0) {
274             addReason(ctx, -1,
275                 "[PTSC-INIT] Couldn't access IML through TSS. "
276                 "Check the TSS configuration /etc/tcsd.conf");
277             rc = OPENPTS_IML_MISSING;
278             goto error;
279         }
280
281         rc = getPcr(ctx);  // iml.c, return pcr num
282         if (rc == 0) {
283             addReason(ctx, -1,
284                 "[PTSC-INIT] Couldn't get the PCR value");
285             rc = PTS_FATAL;
286             goto error;
287         }
288     } else if (conf->iml_mode == 1) {
289         // TODO change to generic name?  conf->iml_filename[0]  conf->iml_filename[1]
290         /* from  securityfs */
291         /* BIOS IML */
292         rc = readBiosImlFile(
293                 ctx,
294                 conf->bios_iml_filename, conf->iml_endian);
295         if (rc != PTS_SUCCESS) {
296             addReason(ctx, -1,
297                 "[PTSC-INIT] Couldn't read the IML file, %s. Check the ptsc configuration, %s.",
298                 conf->bios_iml_filename, conf->config_file);
299             rc = PTS_FATAL;
300             goto error;
301         }
302
303         /* RUNTIME IML (Linux-IMA) */
304         if (ctx->conf->runtime_iml_filename != NULL) {
305             int count;
306             rc = readImaImlFile(
307                     ctx,
308                     conf->runtime_iml_filename,
309                     conf->runtime_iml_type, 0, &count);  // TODO endian?
310             if (rc != PTS_SUCCESS) {
311                 addReason(ctx, -1,
312                     "[PTSC-INIT] Couldn't read IML file, %s. Check the ptsc configuration, %s.",
313                     conf->runtime_iml_filename, conf->config_file);
314                 rc = PTS_INTERNAL_ERROR;
315                 goto error;
316             }
317         }
318     } else {
319         addReason(ctx, -1,
320             "[PTSC-INIT] Unknown IML mode, %d, Check the ptsc configuration (iml.mode), %s .",
321             conf->iml_mode, conf->config_file);
322         rc = PTS_FATAL;
323         goto error;
324     }
325
326     /* config dir, /var/lib/openpts */
327     if (conf->config_dir == NULL) {
328         addReason(ctx, -1,
329             NLS(MS_OPENPTS, OPENPTS_COLLECTOR_MISSING_CONFIG_DIR,
330             "[PTSC-INIT] Configuration directory is not defined. Check the ptsc configuration file, %s"),
331             conf->config_file);
332         rc = PTS_INTERNAL_ERROR;
333         goto error;
334     } else {
335         /* check */
336         rc = checkDir(conf->config_dir);
337         if (rc == PTS_SUCCESS) {
338             /* OK */
339         } else {
340             /* Missing */
341             struct group *ptsc_grp;
342             VERBOSE(1, NLS(MS_OPENPTS, OPENPTS_COLLECTOR_NEW_CONFIG_DIR,
343                 "Creating new configuration directory '%s'\n"), conf->config_dir);
344             makeDir(conf->config_dir);
345
346             // TODO Consider using getgrnam_r(...)
347             if ((ptsc_grp = getgrnam(PTSC_GROUP_NAME)) != NULL) {
348                 if (-1 == chown(conf->config_dir, 0, ptsc_grp->gr_gid)) {
349                     addReason(ctx, -1,
350                         NLS(MS_OPENPTS, OPENPTS_COLLECTOR_CHANGE_OWNSHIP_FAIL,
351                         "[PTSC-INIT] Could not change ownership of %s to " PTSC_GROUP_NAME "\n"),
352                         conf->config_dir);
353                     rc = PTS_FATAL;
354                     goto error;
355                 }
356                 if (-1 == chmod(conf->config_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP)) {
357                     addReason(ctx, -1,
358                         NLS(MS_OPENPTS, OPENPTS_COLLECTOR_CHANGE_MODE_FAIL,
359                         "[PTSC-INIT] Could not change file mode of %s (rwxr-w---)\n"), conf->config_dir);
360                     rc = PTS_FATAL;
361                     goto error;
362                 }
363             } else {
364                 addReason(ctx, -1,
365                     NLS(MS_OPENPTS, OPENPTS_COLLECTOR_FIND_GROUP_FAIL,
366                     "[PTSC-INIT] Failed to look up group '%s'\n"), PTSC_GROUP_NAME);
367                     rc = PTS_FATAL;
368                     goto error;
369             }
370         }
371     }
372
373     /* Generate UUID of this platform */
374     if (conf->uuid == NULL) {
375         // TODO UUID filename is missing
376         addReason(ctx, -1,
377             NLS(MS_OPENPTS, OPENPTS_COLLECTOR_BAD_CONFIG_FILE,
378             "[PTSC-INIT] Bad configuration file, %s"),
379             conf->config_file);
380         rc = PTS_INTERNAL_ERROR;
381         goto error;
382     } else if (conf->uuid->status == OPENPTS_UUID_FILENAME_ONLY) {
383         /* gen new UUID */
384         rc = genOpenptsUuid(conf->uuid);
385         if (rc != PTS_SUCCESS) {
386             addReason(ctx, -1,
387                 "[PTSC-INIT] Generation of UUID was failed");
388             rc = PTS_INTERNAL_ERROR;
389             goto error;
390         }
391     } else {
392         DEBUG("init() - use given UUID %s (for TEST)\n", conf->uuid->str);
393         keygen = 0;
394     }
395
396     /* Create TPM Sign Key */
397     // TODO we use single sign key for all verifiers
398     //      it depends on the onwer of key, now ptscd is the owner of sign key.
399     //      if verifier take the ownership of sign key, we needs the key for each verifier.
400     //      auth can be transferd by IF-M (DH excnage)
401     if (keygen == 1) {
402         rc = createTssSignKey(conf->uuid->uuid, ps_type, NULL, 0, conf->srk_password_mode);
403         if (rc == 0x0001) {  // 0x0001
404             addReason(ctx, -1,
405                 NLS(MS_OPENPTS, OPENPTS_COLLECTOR_SIGN_KEY_FAIL,
406                 "[PTSC-INIT] Failed to create the signed key. "
407                 "If you are using the well known SRK secret key (all zeroes) "
408                 "then please try again with the '-z' option\n"));
409             rc = PTS_INTERNAL_ERROR;
410             goto error;
411         } else if (rc != PTS_SUCCESS) {
412             addReason(ctx, -1,
413                 "[PTSC-INIT] Could not create the Key (rc = 0x%x).", rc);
414             rc = PTS_INTERNAL_ERROR;
415             goto error;
416         }
417         OUTPUT(NLS(MS_OPENPTS, OPENPTS_INIT_PTSCD, "Sign key  location: SYSTEM\n"));
418     } else {
419         DEBUG("init() - skip key gen for the given UUID\n");
420     }
421
422     /* print uuid */
423     OUTPUT(NLS(MS_OPENPTS, OPENPTS_INIT_GEN_UUID, "Generate uuid: %s \n"), conf->uuid->str);
424
425     /* UUID for RM */
426     if (conf->rm_uuid == NULL) {
427         // init/set by readPtsConf
428         // ERROR("conf->rm_uuid == NULL\n");
429         addReason(ctx, -1,
430             "[PTSC-INIT] RM_UUID file is not defined (rm.uuid.file) in the ptsc configulation, %s",
431             conf->config_file);
432         rc = PTS_INTERNAL_ERROR;
433         goto error;
434     } else if (conf->rm_uuid->status == OPENPTS_UUID_FILENAME_ONLY) {
435         rc = genOpenptsUuid(conf->rm_uuid);
436         if (rc != PTS_SUCCESS) {
437             addReason(ctx, -1,
438                 "[PTSC-INIT] Generation of RM UUID was failed");
439             rc = PTS_INTERNAL_ERROR;
440             goto error;
441         }
442
443     } else {
444         DEBUG("init() - use given RM UUID %s\n", conf->rm_uuid->str);
445     }
446
447     /* RM set DIR */
448     rc = makeRmSetDir(conf);
449     if (rc != PTS_SUCCESS) {
450         addReason(ctx, -1,
451             "[PTSC-INIT] Couldn't create Reference Maniferst directory");
452         rc = PTS_INTERNAL_ERROR;
453         goto error;
454     }
455
456     /* print rm uuid */
457     OUTPUT(NLS(MS_OPENPTS, OPENPTS_INIT_GEN_RM_UUID,
458         "Generate UUID (for RM): %s \n"), conf->rm_uuid->str);
459
460     /* get SMBIOS data */
461     // TODO Platform information - TBD
462     //      Use ptsc.conf to set the platform info, malually
463
464     /* create Reference Manifest */
465     for (i = 0; i < conf->rm_num; i++) {
466         if (conf->rm_filename[i] != NULL) {
467             rc = writeRm(ctx, conf->rm_filename[i], i);
468             if (rc != PTS_SUCCESS) {
469                 ERROR("ERROR, initialization was failed\n");
470                 // WORK NEEDED: Reason need putting in NLS
471                 addReason(ctx, -1,
472                     "[PTSC-INIT] Couldn't create the manifest file, %s",
473                     conf->rm_filename[i]);
474                 //printReason(ctx, 0);
475                 rc = PTS_FATAL;
476                 goto error;
477             }
478             OUTPUT(NLS(MS_OPENPTS, OPENPTS_INIT_RM,
479                 "level %d Reference Manifest  : %s\n"), i, conf->rm_filename[i]);
480         } else {
481             addReason(ctx, -1,
482                 NLS(MS_OPENPTS, OPENPTS_COLLECTOR_MISSING_RM_FILE,
483                 "[PTSC-INIT] Missing reference manifest file for level %d\n"), i);
484             rc = PTS_FATAL;
485             goto error;
486         }
487     }
488
489     /* Finaly wrote the UUID files */
490
491     /* Write UUID file */
492     rc = writeOpenptsUuidFile(conf->uuid, 0);
493     if (rc != PTS_SUCCESS) {
494         /* internal error */
495         addReason(ctx, -1,
496             "[PTSC-INIT] Couldn't write the uuid file, '%s'.\n",
497             conf->uuid->filename);
498         rc = PTS_INTERNAL_ERROR;
499         goto error;
500     }
501
502     /* save to rm_uuid file */
503     rc = writeOpenptsUuidFile(conf->rm_uuid, 0);
504     if (rc != PTS_SUCCESS) {
505         addReason(ctx, -1,
506             "[PTSC-INIT] Couldn't write the UUID file, %s",
507             conf->rm_uuid->filename);
508         rc = PTS_INTERNAL_ERROR;
509         goto error;
510     }
511
512     OUTPUT(NLS(MS_OPENPTS, OPENPTS_INIT_SUCCESS,
513         "\nptsc has successfully initialized!\n"));
514     goto free;
515
516  error:
517     /* initialization was faild */
518     OUTPUT(NLS(MS_OPENPTS, OPENPTS_INIT_FAIL,
519         "ptsc initialization was failed\n"));
520     printReason(ctx, 0);
521
522  free:
523     /* free */
524     if (ctx != NULL) freePtsContext(ctx);
525
526     return rc;
527 }
528
529
530
531 /**
532  *
533  * Selftest
534  * - Find right RM for this boot
535  *
536  * Check RM set by rm_uuid file 
537  *    OK-> OPENPTS_SELFTEST_SUCCESS
538  *    NG -> next
539  * Check RM set by newrm_uuid file 
540  *    OK -> OPENPTS_SELFTEST_RENEWED
541  *    NG -> next
542  * Check RM set by oldrm_uuid file 
543  *    OK -> OPENPTS_SELFTEST_FALLBACK
544  *    NG -> OPENPTS_SELFTEST_FAILED
545  *
546  *
547  * Return
548  *   OPENPTS_SELFTEST_SUCCESS   stable:-)
549  *   OPENPTS_SELFTEST_RENEWED   update/reboot -> success
550  *   OPENPTS_SELFTEST_FALLBACK
551  *   OPENPTS_SELFTEST_FAILED
552  *   PTS_INTERNAL_ERROR         something wrong:-(
553  */
554 int selftest(OPENPTS_CONFIG *conf, int prop_count, OPENPTS_PROPERTY *prop_start, OPENPTS_PROPERTY *prop_end) {
555     int rc = PTS_INTERNAL_ERROR;
556     int result;
557     OPENPTS_CONTEXT *ctx;
558     int i;
559     OPENPTS_PROPERTY *prop;
560     char * ir_filename;
561
562     DEBUG("selftest() start\n");
563
564     /* Step 1 - IR gen */
565
566     /* new */
567     ctx = newPtsContext(conf);
568     if (ctx == NULL) {
569         return PTS_INTERNAL_ERROR;
570     }
571
572     /* copy properties */
573     prop = prop_start;
574     for (i = 0; i < prop_count; i++) {
575         if (prop == NULL) {
576             ERROR("prop == NULL\n");
577             return PTS_INTERNAL_ERROR;  // TODO free
578         }
579         addProperty(ctx, prop->name, prop->value);
580         prop = prop->next;
581     }
582
583     /* additional properties from the pts config file */
584     addPropertiesFromConfig(conf, ctx);
585
586     /* set dummy nonce for IR gen */
587     ctx->nonce->nonce_length = 20;
588     ctx->nonce->nonce = xmalloc_assert(20);
589     memset(ctx->nonce->nonce, 0x5A, 20);
590     // dummy target uuid
591     ctx->str_uuid = smalloc("SELFTEST");
592
593     /* gen IR */
594     rc = genIr(ctx, NULL);
595     if (rc != PTS_SUCCESS) {
596         ERROR("selftest() - genIR failed\n");
597         rc = PTS_INTERNAL_ERROR;
598         goto free;
599     }
600
601     /* hold the IR filename */
602     ir_filename = ctx->ir_filename;
603     ctx->ir_filename = NULL;
604
605     /* free */
606     freePtsContext(ctx);
607
608     // DEBUG("selftest() - generate IR file => %s\n", conf->ir_filename);
609     DEBUG("selftest() - generate IR - done\n");
610
611     /* Step 2 - Validate IR */
612
613     /* Keep conf but reset some flags in conf */
614     // conf->aru_count = 0;
615     // conf->enable_aru;
616 #ifdef CONFIG_AUTO_RM_UPDATE
617     conf->update_exist = 0;
618 #endif
619     /* new */
620     ctx = newPtsContext(conf);
621     if (ctx == NULL) {
622         return PTS_INTERNAL_ERROR;
623     }
624     ctx->ir_filename = ir_filename;
625
626     /* setup RMs */
627     rc = getRmSetDir(conf);
628     if (rc != PTS_SUCCESS) {
629         ERROR("selftest() - getRmSetDir() failed\n");
630         TODO("conf->rm_uuid->filename %s\n", conf->rm_uuid->filename);
631         TODO("conf->rm_uuid->str      %s\n", conf->rm_uuid->str);
632         rc = PTS_INTERNAL_ERROR;
633         goto free;
634     }
635
636     /* load RMs */
637     for (i = 0; i <  conf->rm_num; i++) {
638         rc = readRmFile(ctx, conf->rm_filename[i], i);
639         if (rc < 0) {
640             ERROR("readRmFile fail\n");
641             rc = PTS_INTERNAL_ERROR;
642             goto free;
643         }
644     }
645
646
647     /* verify */
648     DEBUG("selftest() - validate IR - start\n");
649
650     // TODO 2011-01-21 SM just use same conf
651     ctx->target_conf = ctx->conf;
652
653     // Disable Quote
654     // 2011-01-28 SM, If FSM did not covers all PCRs Quote validation will fail?
655     // iml_mode = ctx->conf->iml_mode;
656     // ir_without_quote = ctx->conf->ir_without_quote;
657     // ctx->conf->iml_mode = 1;
658     // ctx->conf->ir_without_quote = 1;
659
660
661
662     //result = validateIr(ctx, conf->ir_filename);  /* ir.c */
663     // TODO 
664     result = validateIr(ctx);  /* ir.c */
665
666
667     /* check RM integrity status */
668     DEBUG("selftest() - validate IR - done (rc = %d)\n", result);
669     if ((rc != OPENPTS_RESULT_VALID) && isDebugFlagSet(DEBUG_FLAG)) {
670         printReason(ctx, 0);
671     }
672
673     if (result != OPENPTS_RESULT_VALID) {
674         addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_COLLECTOR_SELFTEST_FAILED, "[SELFTEST] The self test failed"));
675         if ((conf->newrm_uuid != NULL) && (conf->newrm_uuid->uuid != NULL)) {
676             /* New RM exist (for reboot after the update), Try the new RM */
677
678             /* chenge the UUID */  // TODO add exchange func
679             conf->rm_uuid->uuid = conf->newrm_uuid->uuid;
680             conf->rm_uuid->str  = conf->newrm_uuid->str;
681             conf->rm_uuid->time = conf->newrm_uuid->time;
682
683             // del newrm
684             conf->newrm_uuid->uuid = NULL;
685             conf->newrm_uuid->str  = NULL;
686             conf->newrm_uuid->time = NULL;
687
688             // TODO free
689
690             /* try selftest again */
691             DEBUG("selftest again UUID=%s\n", conf->rm_uuid->str);
692             rc = selftest(conf, prop_count, prop_start, prop_end);
693             if (rc == OPENPTS_SELFTEST_SUCCESS) {
694                 /* Update the RM UUID by NEWRM_UUID */
695                 DEBUG("use UUID=%s\n", conf->rm_uuid->str);
696                 /* update rm_uuid */
697                 rc = writeOpenptsUuidFile(conf->rm_uuid, 1);
698                 if (rc != PTS_SUCCESS) {
699                     ERROR("writeOpenptsUuidFile fail\n");
700                 }
701
702                 // TODO check rc
703                 /* delete newrm_uuid */
704                 rc = remove(conf->newrm_uuid->filename);
705                 // TODO check rc
706                 rc = OPENPTS_SELFTEST_RENEWED;
707             } else {
708                 /* fail */
709                 TODO("\n");
710                 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_COLLECTOR_SELFTEST_FAILED_2,
711                                "[SELFTEST] The self test using both current and new UUIDs has failed"));
712                 printReason(ctx, 0);
713                 rc = OPENPTS_SELFTEST_FAILED;
714             }
715         } else {
716             printReason(ctx, 0);
717             rc = OPENPTS_SELFTEST_FAILED;
718         }
719     } else {
720         /* valid :-) */
721         rc = OPENPTS_SELFTEST_SUCCESS;
722     }
723
724     /* leaving lots of temp 100K+ files lying around quickly fills up certain
725        filesystems, i.e. on AIX /tmp is typically small, so we 
726        unlink them after use */
727     if (NULL != conf->ir_filename) {
728         unlink(conf->ir_filename);
729     }
730
731  free:
732     /* free */
733     freePtsContext(ctx);
734
735     return rc;
736 }
737
738
739
740 /**
741  * New RM
742  *
743  * 4. generate RM
744  * 
745  *
746  * ./src/ptsc -i -c tests/data/Fedora12/ptscd.conf
747  *
748  * Return
749  *  PTS_SUCCESS
750  *  PTS_INTERNAL_ERROR
751  */
752
753 int newrm(OPENPTS_CONFIG *conf, int prop_count, OPENPTS_PROPERTY *prop_start, OPENPTS_PROPERTY *prop_end) {
754     int rc = PTS_SUCCESS;
755     OPENPTS_CONTEXT *ctx;
756     int i;
757     OPENPTS_PROPERTY *prop;
758
759     /* ctx for init */
760     ctx = newPtsContext(conf);
761     if (ctx == NULL) {
762         return PTS_INTERNAL_ERROR;
763     }
764
765 #if 1
766     /* copy properties */
767     prop = prop_start;
768     for (i = 0; i < prop_count; i++) {
769         if (prop == NULL) {
770             ERROR("prop == NULL\n");
771             return PTS_INTERNAL_ERROR;  // TODO free
772         }
773         addProperty(ctx, prop->name, prop->value);
774         prop = prop->next;
775     }
776 #else
777     /* add property */
778     if (prop_count > 0) {
779         ctx->prop_start = prop_start;
780         ctx->prop_end = prop_end;
781         ctx->prop_count = prop_count;
782     }
783 #endif
784
785     addPropertiesFromConfig(conf, ctx);
786
787     /* read FSM */
788     rc = readFsmFromPropFile(ctx, conf->config_file);
789     if (rc != PTS_SUCCESS) {
790         fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_COLLECTOR_FAILED_READ_FSM, "Failed to read the FSM file\n"));
791         rc = PTS_INTERNAL_ERROR;
792         goto free;
793     }
794
795     /* UUID for RM */
796     if (conf->rm_uuid == NULL) {
797         ERROR("conf->rm_uuid == NULL");
798     } else if (conf->rm_uuid->status == OPENPTS_UUID_FILENAME_ONLY) {
799         rc = genOpenptsUuid(conf->rm_uuid);
800         // TODO
801     } else {
802         DEBUG("init() - use given RM UUID %s\n", conf->rm_uuid->str);
803     }
804
805     /* save/update rm_uuid file */
806     rc = writeOpenptsUuidFile(conf->rm_uuid, 1);  // TODO overwite?
807     if (rc != PTS_SUCCESS) {
808         ERROR("writeOpenptsUuidFile fail\n");
809     }
810
811     /* RM set DIR */
812     rc = makeRmSetDir(conf);
813     if (rc != PTS_SUCCESS) {
814         fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_COLLECTOR_MKDIR_RM_SET_FAILED,
815             "Failed to create the reference manifest set directory\n"));
816         goto free;
817     }
818
819     /* print rm uuid */
820     OUTPUT(NLS(MS_OPENPTS, OPENPTS_NEW_RM_UUID, "Generate UUID (for RM): %s \n"), conf->rm_uuid->str);
821
822     /* read IML to fill the BIOS binary measurement, and translate BHV->BIN FSM */
823
824     /* load current IML using FSMs */
825     if (conf->iml_mode == 0) {  // TODO use def
826 #ifdef CONFIG_NO_TSS
827         ERROR("Build with --without-tss. iml.mode=tss is not supported\n");
828 #else
829         rc = getIml(ctx, 0);
830         rc = getPcr(ctx);
831 #endif
832     } else if (conf->iml_mode == 1) {
833         // TODO change to generic name?  conf->iml_filename[0]  conf->iml_filename[1]
834         /* from  securityfs */
835         /* BIOS IML */
836         rc = readBiosImlFile(
837                 ctx,
838                 conf->bios_iml_filename, conf->iml_endian);
839         if (rc != PTS_SUCCESS) {
840             DEBUG("getBiosImlFile() was failed\n");
841             ERROR("Oops! Something is wrong. Please see the reason below\n");
842             printReason(ctx, 0);
843             goto free;
844         }
845
846         /* RUNTIME IML (Linux-IMA) */
847         if (ctx->conf->runtime_iml_filename != NULL) {
848             int count;
849             rc = readImaImlFile(
850                     ctx,
851                     conf->runtime_iml_filename,
852                     conf->runtime_iml_type, 0, &count);  // TODO endian?
853             if (rc != PTS_SUCCESS) {
854                 ERROR("read IMA IML, %s was failed\n", conf->runtime_iml_filename);
855                 rc = PTS_INTERNAL_ERROR;
856                 goto free;
857             }
858         }
859     } else {
860         ERROR("unknown IML mode, %d\n", conf->iml_mode);
861     }
862
863     /* get SMBIOS data */
864     // TODO
865
866     /* create Reference Manifest */
867     for (i = 0; i < conf->rm_num; i++) {
868         if (conf->rm_filename[i] != NULL) {
869             rc = writeRm(ctx, conf->rm_filename[i], i);
870             if (rc != PTS_SUCCESS) {
871                 ERROR("write RM, %s was failed\n", conf->rm_filename[i]);
872                 rc = PTS_INTERNAL_ERROR;
873                 goto free;
874             }
875             OUTPUT(NLS(MS_OPENPTS, OPENPTS_NEW_RM_RM, "level %d Reference Manifest: %s\n"), i, conf->rm_filename[i]);
876         } else {
877             ERROR("missing RM file for level %d\n", i);
878         }
879     }
880     // OUTPUT("\nptsc is successfully initialized!\n");
881
882  free:
883
884     if ( rc == PTS_INTERNAL_ERROR ) {
885         OUTPUT(NLS(MS_OPENPTS, OPENPTS_NEW_RM_FAILED, "Failed to generate Reference Manifest\n"));
886     }
887
888     /* free */
889     freePtsContext(ctx);
890
891     return rc;
892 }
893
894
895 /**
896  * Print the configuration of PTS collector
897  *
898  * Return
899  *   PTS_SUCCESS
900  */
901 int printCollectorStatus(OPENPTS_CONFIG *conf) {
902     int rc = PTS_SUCCESS;
903     OPENPTS_CONTEXT *ctx;
904
905     ctx = newPtsContext(conf);
906
907     OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_HEADER,
908                "%s version %s\n\n"
909                "config file: %s\n"
910                "UUID: %s (%s)\n"),
911            PACKAGE, VERSION, conf->config_file, ctx->conf->uuid->str, conf->uuid->filename);
912
913     /* IML */
914     if (conf->iml_mode == 0) {
915         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_IML_1, "IML access mode             : TSS\n"));
916     } else if (conf->iml_mode == 1) {
917         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_IML_2,
918                "IML access: SecurityFS\n"
919                "  BIOS IML file: %s\n"
920                "  Runtime IML file: %s\n"
921                "  PCR file: %s\n"), conf->bios_iml_filename, conf->runtime_iml_filename, conf->pcrs_filename);
922     } else {
923         ERROR("unknown IML mode, %d\n", conf->iml_mode);
924     }
925
926     /* Linux IMA mode */
927     switch (conf->runtime_iml_type) {
928     case BINARY_IML_TYPE_IMA_ORIGINAL:
929         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_KERN_1,
930             "  Runtime IML type: Linux-IMA patch (kernel 2.6.18-2.6.29)\n"));
931         break;
932     case BINARY_IML_TYPE_IMA_31:
933         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_KERN_2,
934             "  Runtime IML type: IMA (kernel 2.6.30-31)\n"));
935         break;
936     case BINARY_IML_TYPE_IMA:
937         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_KERN_3,
938             "  Runtime IML type: IMA (kernel 2.6.32)\n"));
939         break;
940     case BINARY_IML_TYPE_IMA_NG:
941         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_KERN_4,
942             "  Runtime IML type: IMA NG (kernel 2.6.XX)\n"));
943         break;
944     case BINARY_IML_TYPE_IMA_NGLONG:
945         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_KERN_5,
946             "  Runtime IML type: IMA NG LONG (kernel 2.6.XX)\n"));
947         break;
948     default:
949         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_KERN_6,
950             "  Runtime IML type: unknown type 0x%x\n"), conf->runtime_iml_type);
951         break;
952     }  // switch
953
954     /* Reference Manifest */
955
956     /* UUID of this platform */
957     OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_RM_UUID_CUR,
958         "RM UUID (current): %s\n"), conf->rm_uuid->str);
959     OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_RM_UUID_NEXT,
960         "RM UUID (for next boot): %s\n"), conf->newrm_uuid->str);
961
962     /* List RMs */
963     getRmList(conf, conf->config_dir);
964     OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_LIST_RM,
965         "List of RM set: %d RM set in config dir\n"), conf->rmsets->rmset_num);
966     printRmList(conf, "  ");
967     // OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_IR, "Integrity Report: %s\n"), conf->ir_filename);
968     OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_IR, "Integrity Report dir: %s\n"), conf->ir_dir);
969
970
971     // TODO remove ctx from readFsmFromPropFile
972     /* Models */
973     rc = readFsmFromPropFile(ctx, conf->config_file);
974     if (rc != PTS_SUCCESS) {
975         ERROR("read FSM failed\n");
976         goto free;
977     }
978
979     OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_MODEL_DIR, "Model dir: %s\n"), conf->model_dir);
980     OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_STATUS_BEHAVIOUR_MODELS, "Behavior Models\n"));
981     printFsmInfo(ctx, "  ");
982
983     /* Manifest */
984
985
986     /* Servers */
987
988  free:
989     /* free */
990     freePtsContext(ctx);
991
992     return rc;
993 }
994
995 /**
996  * Clear PTS collector
997  * delete /var/lib/openpts
998  *
999  */
1000 int clear(
1001     OPENPTS_CONFIG *conf,
1002     int force) {
1003     char ans[32];
1004     int ansIsYes = 0, ansIsNo = 1;
1005     int rc;
1006
1007     /* check */
1008     if (conf == NULL) {
1009         ERROR("conf == NULL");
1010         return PTS_FATAL;
1011     }
1012     if (conf->config_dir == NULL) {
1013         ERROR("conf->config_dir == NULL");
1014         return PTS_FATAL;
1015     }
1016
1017 #if 0
1018     // lock file exist
1019     /* check */
1020     rc = checkDir(conf->config_dir);
1021     if (rc == PTS_INTERNAL_ERROR) {
1022         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_CLEAR_FAIL_NODIR,
1023             "%s is missing"), conf->config_dir);
1024         return PTS_FATAL;
1025     } else {
1026 TODO("HOGE DDD %s\n",conf->config_dir);
1027     }
1028
1029 TODO("HOGE %s\n",conf->config_dir);
1030 #endif
1031
1032     if (isatty(STDIN_FILENO) && (force == 0) ) {
1033         char *lineFeed;
1034         printf(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_CLEAR,
1035             "Clear the PTS collector [y/N]\n"));
1036         if ( NULL != fgets(ans, 32, stdin) ) {
1037             // strip the ending line-feed
1038             if ((lineFeed = strrchr(ans, '\n')) != NULL) {
1039                 *lineFeed = '\0';
1040             }
1041
1042             ansIsYes = (strcasecmp(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_CLEAR_YES, "y"), ans) == 0);
1043             ansIsNo = (strcasecmp(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_CLEAR_NO, "n"), ans) == 0);
1044             ansIsNo |= (strlen(ans) == 0);  // default answer case
1045         } else {
1046             ansIsYes = 0;
1047             ansIsNo  = 1;
1048         }
1049     } else {
1050         ansIsYes = force;
1051         ansIsNo  = !force;
1052     }
1053
1054     if (ansIsYes) {
1055
1056         rc = unlinkDir(conf->config_dir);
1057         if (rc != PTS_SUCCESS) {
1058             ERROR("unlinkDir(%s) fail", conf->config_dir);
1059         }
1060         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_CLEAR_YES_DONE,
1061             "%s has been cleared\n") , conf->config_dir);
1062     } else {
1063         OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_CLEAR_NO_DONE, "keep\n"));
1064     }
1065
1066
1067     return PTS_SUCCESS;
1068 }