OSDN Git Service

fixed for Ubuntu 12.04
[openpts/openpts.git] / src / ctx.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/ctx.c
26  * \brief PTS context
27  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
28  * @date 2010-04-01
29  * cleanup 2012-01-05 SM
30  *
31  * OpenPTS main context
32  *
33  */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <ctype.h>
39
40 #include <openssl/sha.h>
41
42 #include <openpts.h>
43
44 /**
45  * New OpenPTS context (New)
46  */
47 OPENPTS_CONTEXT  * newPtsContext(OPENPTS_CONFIG *conf) {
48     OPENPTS_CONTEXT *ctx = NULL;
49
50     DEBUG_CAL("newPtsContext - start\n");
51
52     ctx = (OPENPTS_CONTEXT *) xmalloc(sizeof(OPENPTS_CONTEXT));
53     if (ctx == NULL) {
54         LOG(LOG_ERR, "no memory");
55         return NULL;
56     }
57     memset(ctx, 0, sizeof(OPENPTS_CONTEXT));
58
59     /* config - use given config */
60     ctx->conf = conf;
61
62     /* TPM emu - reset */
63     resetTpm(&ctx->tpm, ctx->drtm);
64
65     /* IF-M nonce */
66     ctx->nonce = newNonceContext();
67     if (ctx->nonce == NULL) {
68         LOG(LOG_ERR, "newNonceContext() fail. no memory");
69         goto error;
70     }
71
72     DEBUG_CAL("newPtsContext - done\n");
73
74     return ctx;
75
76   error:
77     xfree(ctx);
78     return NULL;
79 }
80
81
82 /**
83  * free OpenPTS context, but keep conf (shared) 
84  * 
85  * TODO(munetoh) check memory leak
86  */
87 int freePtsContext(OPENPTS_CONTEXT *ctx) {
88     int i;
89     DEBUG_CAL("freePtsContext - start\n");
90
91     /* check */
92     if (ctx == NULL) {
93         LOG(LOG_ERR, "null input");
94         return PTS_FATAL;
95     }
96
97     /* TPM emu - reset */
98     // just free with CTX
99
100     /* PCRs - free, malloc at ifm.c */
101     if (ctx->pcrs != NULL) {
102         if (ctx->pcrs->pcr_select_byte != NULL) {
103             xfree(ctx->pcrs->pcr_select_byte);
104         }
105         xfree(ctx->pcrs);
106     }
107
108     /* Quote - free, malloc at ifm.c, ir.c */
109     if (ctx->validation_data != NULL) {
110         if (ctx->validation_data->rgbExternalData != NULL) {
111             xfree(ctx->validation_data->rgbExternalData);
112         }
113         if (ctx->validation_data->rgbData != NULL) {
114             xfree(ctx->validation_data->rgbData);
115         }
116         if (ctx->validation_data->rgbValidationData != NULL) {
117             xfree(ctx->validation_data->rgbValidationData);
118         }
119         xfree(ctx->validation_data);
120     }
121
122     /* UUIDs */
123     if (ctx->uuid != NULL) {
124         xfree(ctx->uuid);
125     }
126     if (ctx->str_uuid != NULL) {
127         xfree(ctx->str_uuid);
128     }
129
130     /* IML - reset & free */
131     if (ctx->ss_table != NULL) {
132         freeSnapshotTable(ctx->ss_table);
133     }
134
135     /* Properties - free */
136     freePropertyChain(ctx->prop_start);
137
138     /* Policy - free */
139     if (ctx->policy_start != NULL) {
140         freePolicyChain(ctx->policy_start);
141     }
142
143     /* Reason - free */
144     if (ctx->reason_start != NULL) {
145         freeReasonChain(ctx->reason_start);
146     }
147
148     /* RM - free malloc at rm.c  */
149     if (ctx->rm_ctx != NULL) {
150         freeRmContext(ctx->rm_ctx);
151     }
152
153     /* IR - free, malloc at ir.c */
154     if (ctx->ir_ctx != NULL) {
155         freeIrContext(ctx->ir_ctx);
156     }
157
158     /* Runtime Validation - free */
159
160     /* IF-M - free */
161     if (ctx->read_msg != NULL) {
162         xfree(ctx->read_msg);
163     }
164
165     if (ctx->nonce != NULL) {
166         freeNonceContext(ctx->nonce);
167     }
168
169     if (ctx->target_conf_filename != NULL) {
170         xfree(ctx->target_conf_filename);
171     }
172
173     for (i = 0; i < MAX_RM_NUM; i++) {
174         if (ctx->compIDs[i].SimpleName != NULL) xfree(ctx->compIDs[i].SimpleName);
175         if (ctx->compIDs[i].ModelName != NULL) xfree(ctx->compIDs[i].ModelName);
176         if (ctx->compIDs[i].ModelNumber != NULL) xfree(ctx->compIDs[i].ModelNumber);
177         if (ctx->compIDs[i].ModelSerialNumber != NULL) xfree(ctx->compIDs[i].ModelSerialNumber);
178         if (ctx->compIDs[i].ModelSystemClass != NULL) xfree(ctx->compIDs[i].ModelSystemClass);
179         if (ctx->compIDs[i].VersionMajor != NULL) xfree(ctx->compIDs[i].VersionMajor);
180         if (ctx->compIDs[i].VersionMinor != NULL) xfree(ctx->compIDs[i].VersionMinor);
181         if (ctx->compIDs[i].VersionBuild != NULL) xfree(ctx->compIDs[i].VersionBuild);
182         if (ctx->compIDs[i].VersionString != NULL) xfree(ctx->compIDs[i].VersionString);
183         if (ctx->compIDs[i].MfgDate != NULL) xfree(ctx->compIDs[i].MfgDate);
184         if (ctx->compIDs[i].PatchLevel != NULL) xfree(ctx->compIDs[i].PatchLevel);
185         if (ctx->compIDs[i].DiscretePatches != NULL) xfree(ctx->compIDs[i].DiscretePatches);
186         if (ctx->compIDs[i].VendorID_Name != NULL) xfree(ctx->compIDs[i].VendorID_Name);
187         if (ctx->compIDs[i].VendorID_Value != NULL) xfree(ctx->compIDs[i].VendorID_Value);
188     }
189
190     /* free */
191     xfree(ctx);
192
193     DEBUG_CAL("freePtsContext - done\n");
194
195     return PTS_SUCCESS;
196 }
197
198
199 /**
200  * get Hash Alg string by ID
201  *
202  * TODO table?
203  */
204 char * getAlgString(int type) {
205     if (type == ALGTYPE_SHA1) {
206         return "sha1";
207     } else if (type == ALGTYPE_MD5) {
208         return "md5";
209     } else {
210         LOG(LOG_ERR, "unknown type %d\n", type);
211         return NULL;
212     }
213 }
214
215 /**
216  * properties
217  *  rm.model.0.pcr.1=bios_pcr1.uml
218  *  rm.model.0.pcr.4=grub_pcr4.uml
219  *
220  * snapshots
221  *   level 0 = Platform(BIOS)
222  *   level 1 = Runtime(IPL,OS,IMA)
223  *   level 2 = apps (TBD)
224  *
225  * Return
226  *    0 OK
227  *   -1 ERROR
228  *    PTS_SUCCESS
229  *    PTS_OS_ERROR
230  *    PTS_INTERNAL_ERROR
231  *
232  */
233 int readFsmFromPropFile(OPENPTS_CONTEXT *ctx, char * filename) {
234     int rc = PTS_SUCCESS;
235     FILE *fp;
236     char buf[FSM_BUF_SIZE];
237     char buf2[FSM_BUF_SIZE];
238     char *eqp = NULL;
239     int pcr_index;
240     int level;
241     char *model_filename = NULL;
242     int len;
243     OPENPTS_CONFIG *conf;
244     OPENPTS_FSM_CONTEXT *fsm = NULL;
245     OPENPTS_SNAPSHOT *ss = NULL;
246
247     /* check */
248     if (ctx == NULL) {
249         LOG(LOG_ERR, "null input");
250         return PTS_FATAL;
251     }
252     conf = ctx->conf;
253     if (conf == NULL) {
254         LOG(LOG_ERR, "null input");
255         return PTS_FATAL;
256     }
257     if (filename == NULL) {
258         LOG(LOG_ERR, "null input");
259         return PTS_FATAL;
260     }
261
262     /* new snapshot table */
263     if (ctx->ss_table == NULL) {
264         ctx->ss_table = newSnapshotTable();
265     }
266
267     /* Open prop file */
268     if ((fp = fopen(filename, "r")) == NULL) {
269         OUTPUT(NLS(MS_OPENPTS, OPENPTS_CONFIG_MISSING, "Cannot open config file '%s'\n"), filename);
270         return PTS_OS_ERROR;
271     }
272
273     /* parse */
274     while (fgets(buf, FSM_BUF_SIZE, fp) != NULL) {  // read line
275         len = strlen(buf);
276
277         /* check for line length */
278         if (len == FSM_BUF_SIZE) {
279             LOG(LOG_ERR, "Line too long in %s\n", filename);
280             OUTPUT(NLS(MS_OPENPTS, OPENPTS_CONFIG_BAD_CONFIG_FILE, "Bad configuration file\n"));
281             rc = PTS_FATAL;
282             goto error;
283         }
284
285         /* ignore comment, null line */
286         if (buf[0] == '#') {
287             // comment
288         } else if ((eqp = strstr(buf, "=")) != NULL) {
289             /* this is property line */
290
291             /* remove CR */
292             if (buf[len-1] == '\n') buf[len-1] = '\0';
293
294             model_filename = NULL;
295
296 #if 1
297             // Using config file <= version 0.2.3
298             if (strstr(buf, "platform.model.") != NULL) {
299                 LOG(LOG_ERR, "ptsc.conf has old format <=v0.2.3 %s\n", filename);
300                 LOG(LOG_ERR, "change platform.model to rm.model.0\n");
301                 OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_BAD_CONFIG_FILE, "Bad configuration file (v0.2.3)\n"));
302                 rc = PTS_FATAL;
303                 goto error;
304             }
305
306             if (strstr(buf, "runtime.model.") != NULL) {
307                 LOG(LOG_ERR, "ptsc.conf has old format <=v0.2.3 %s\n", filename);
308                 LOG(LOG_ERR, "change runtime.model to rm.model.1\n");
309                 OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_BAD_CONFIG_FILE, "Bad configuration file (v0.2.3)\n"));
310                 rc = PTS_FATAL;
311                 goto error;
312             }
313 #endif
314
315             //           1111111
316             // 01234567890123456
317             // rm.model.0.pcr.7
318             if (!strncmp(buf, "rm.model.", 9)) {
319                 level = (int) strtol(&buf[9], NULL, 10);
320                 pcr_index = (int) strtol(&buf[15], NULL, 10);
321                 model_filename = eqp + 1;
322
323                 setModelFile(conf, pcr_index, level, model_filename);
324
325                 /* new FSM */
326                 fsm = newFsmContext();
327                 fsm->level = level;
328                 fsm->pcr_index = pcr_index;
329
330                 /* read Model */
331                 snprintf(
332                     buf2, sizeof(buf2),
333                     "%s/%s",
334                     conf->model_dir, model_filename);
335                 rc = readUmlModel(fsm, buf2);
336                 if (rc != PTS_SUCCESS) {
337                     LOG(LOG_ERR, "addFsmByPropFile -  [%s] / [%s] -> [%s] fail rc=%d, pwd = %s\n",
338                         conf->model_dir, model_filename, buf2, rc,
339                         getenv("PWD"));
340                     goto error;  // return -1;
341                 }
342
343                 /* setup the NEW snapshots, BIOS, GRUB */
344                 ss = getNewSnapshotFromTable(ctx->ss_table, pcr_index, level);
345                 if (ss == NULL) {
346                     LOG(LOG_ERR, "FSM has been assigned at lvl=%d pcr=%d  %s. check the config file\n",
347                         level, pcr_index, buf);
348                     rc = PTS_FATAL;
349                     goto error;
350                 }
351
352                 ss->fsm_behavior = fsm;
353
354                 // TODO set by getNewSnapshotFromTable
355                 // s s->level = level;
356                 // ss->pcrIndex = pcr_index;
357
358                 // 2011-02-07 SM added
359                 if (ctx->pcrs != NULL && OPENPTS_PCR_INDEX != pcr_index) {
360                     ctx->pcrs->pcr_select[pcr_index] = 1;
361                 }
362
363                 DEBUG_FSM("platform(level%d) pcr[%d] [%s] ss=%p\n",
364                     level,
365                     pcr_index,
366                     conf->model_filename[level][pcr_index],
367                     ss);
368             }
369         } else {
370             /* accept only blank lines */
371             char *ptr;
372
373             ptr = buf;
374             while (*ptr != '\0') {
375                 if (!isspace(*ptr)) {
376                     LOG(LOG_ERR, "Syntax error in %s\n", filename);
377                     OUTPUT(NLS(MS_OPENPTS, OPENPTS_COLLECTOR_BAD_CONFIG_FILE, "Bad configuration file\n"));
378                     rc =  PTS_FATAL;
379                     goto error;
380                 }
381                 ptr++;
382             }
383         }
384     }
385
386   error:
387     fclose(fp);
388
389     return rc;
390 }
391