2 * This file is part of the OpenPTS project.
4 * The Initial Developer of the Original Code is International
5 * Business Machines Corporation. Portions created by IBM
6 * Corporation are Copyright (C) 2010 International Business
7 * Machines Corporation. All Rights Reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the Common Public License as published by
11 * IBM Corporation; either version 1 of the License, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * Common Public License for more details.
19 * You should have received a copy of the Common Public License
20 * along with this program; if not, a copy can be viewed at
21 * http://www.opensource.org/licenses/cpl1.0.php.
26 * \brief AIDE I/F APIs
27 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
29 * cleanup 2012-01-05 SM
31 * 1) Integrity check with AIDE
33 * $ ./configure --with-aide
36 * 2) Integrity check with AIDE and SQLite (fast?)
38 * # yum install sqlite-devel
40 * $ ./configure --with-aide --with-sqlite
49 * PostgreSQL XXsec (TBD)
52 * http://www.gnu.org/s/libc/manual/html_node/Hash-Search-Function.html
54 * binary digest did not work well, thus try base64 string in stead binary blob.
65 #include <search.h> // hash table
79 * TODO(munetoh) new -> add?
81 AIDE_METADATA * newAideMetadata() {
82 AIDE_METADATA *metadata;
83 metadata = (AIDE_METADATA *) xmalloc(sizeof(AIDE_METADATA));
84 if (metadata == NULL) {
85 // LOG(LOG_ERR, "no memory\n");
88 memset(metadata, 0, sizeof(AIDE_METADATA));
98 * TODO(munetoh) sep. all and single
100 void freeAideMetadata(AIDE_METADATA *md) {
103 LOG(LOG_ERR, "null input");
107 if (md->next != NULL) {
108 freeAideMetadata(md->next);
112 if (md->name != NULL) xfree(md->name);
113 if (md->lname != NULL) xfree(md->lname);
114 if (md->sha1 != NULL) xfree(md->sha1);
115 if (md->sha256 != NULL) xfree(md->sha256);
116 if (md->ima_name != NULL) xfree(md->ima_name);
117 if (md->hash_key != NULL) xfree(md->hash_key);
128 int addAideMetadata(AIDE_CONTEXT *ctx, AIDE_METADATA *md) {
133 LOG(LOG_ERR, "null input");
137 LOG(LOG_ERR, "null input");
142 if (ctx->start == NULL) {
156 // #define AIDE_CHBY_LIST 1
157 #define AIDE_CHBY_LIST 0
159 #define AIDE_HASH_TABLE_SIZE 16000
165 #define AIDE_HASH_CHECK_SIZE SHA1_DIGEST_SIZE
166 // #define AIDE_HASH_CHECK_SIZE 20
171 AIDE_CONTEXT * newAideContext() {
175 ctx = xmalloc(sizeof(AIDE_CONTEXT));
177 LOG(LOG_ERR, "no memory");
180 memset(ctx, 0, sizeof(AIDE_CONTEXT));
183 // TODO set the size in openpts.h
184 ctx->aide_md_table = xmalloc(sizeof(struct hsearch_data));
186 memset(ctx->aide_md_table, 0, sizeof(struct hsearch_data));
187 rc = hcreate_r(AIDE_HASH_TABLE_SIZE, ctx->aide_md_table); // hash table for metadata
189 LOG(LOG_ERR, "hcreate faild, errno=%x\n", errno);
192 ctx->aide_md_table_size = 0;
194 ctx->aide_in_table = xmalloc(sizeof(struct hsearch_data));
195 if (ctx->aide_in_table == NULL) {
196 LOG(LOG_ERR, "no memory");
199 memset(ctx->aide_in_table, 0, sizeof(struct hsearch_data));
201 rc = hcreate_r(AIDE_HASH_TABLE_SIZE, ctx->aide_in_table); // hash table for ignore name
203 LOG(LOG_ERR, "hcreate faild\n");
206 ctx->aide_in_table_size = 0;
208 DEBUG("newAideContext %p\n", ctx);
212 if (ctx != NULL) xfree(ctx);
219 void freeAideIgnoreList(AIDE_LIST *list) {
222 LOG(LOG_ERR, "null input");
226 if (list->next != NULL) {
227 freeAideIgnoreList(list->next);
232 if (list->name != NULL) {
244 void freeAideContext(AIDE_CONTEXT *ctx) {
247 LOG(LOG_ERR, "ctx is NULL\n");
250 DEBUG("freeAideContext %p \n", ctx);
252 // DEBUG("aide_md_table_size = %d\n", ctx->aide_md_table_size);
253 // DEBUG("aide_in_table_size = %d\n", ctx->aide_in_table_size);
256 hdestroy_r(ctx->aide_md_table);
257 hdestroy_r(ctx->aide_in_table);
259 xfree(ctx->aide_md_table);
260 xfree(ctx->aide_in_table);
263 if (ctx->sqlite_db != NULL) {
265 sqlite3_close(ctx->sqlite_db);
269 /* free metadata chain */
270 if (ctx->start != NULL) {
271 freeAideMetadata(ctx->start);
274 /* free ignore list */
275 if (ctx->ignore_name_start != NULL) {
276 // DEBUG("free tx->ignore_name_start\n");
277 freeAideIgnoreList(ctx->ignore_name_start);
286 * load AIDE db file (giped)
288 name lname attr sha1 sha256
289 /bin/vi 0 1073750017 C9ID19uSxnrv/Bt0uYbloaVO1SQ= VTYuAxsuG4pmWHP9ZCTO1KUsYk2uwTvwiCJ/OxzsVd0=
291 /bin/dnsdomainname hostname 3 0 0
295 #define AIDE_SPEC_BUF_SIZE 1024
296 #define AIDE_MAX_ITEM_NUM 20
297 #define AIDE_MAX_ITEM_SIZE 10
299 // TODO(munetoh) add more...
300 #define AIDE_ITEM_NAME 0 // char
301 #define AIDE_ITEM_LNAME 1 // int
302 #define AIDE_ITEM_ATTR 2 // int
303 #define AIDE_ITEM_SHA1 3 // base64
304 #define AIDE_ITEM_SHA256 4 // base64
305 #define AIDE_ITEM_SHA512 5 // base64
306 #define AIDE_ITEM_PERM 6 //
307 #define AIDE_ITEM_UID 7 //
308 #define AIDE_ITEM_GID 8 //
309 #define AIDE_ITEM_ACL 9 //
310 #define AIDE_ITEM_XATTRS 10 //
312 int getAideItemIndex(char *buf) {
313 if (!strncmp(buf, "name", 4)) {
314 return AIDE_ITEM_NAME;
315 } else if (!strncmp(buf, "lname", 5)) {
316 return AIDE_ITEM_LNAME;
317 } else if (!strncmp(buf, "attr", 4)) {
318 return AIDE_ITEM_ATTR;
319 } else if (!strncmp(buf, "sha1", 4)) {
320 return AIDE_ITEM_SHA1;
321 } else if (!strncmp(buf, "sha256", 6)) {
322 return AIDE_ITEM_SHA256;
323 } else if (!strncmp(buf, "sha512", 6)) {
324 return AIDE_ITEM_SHA512;
325 } else if (!strncmp(buf, "perm", 4)) {
326 return AIDE_ITEM_PERM;
327 } else if (!strncmp(buf, "acl", 4)) {
328 return AIDE_ITEM_ACL;
329 } else if (!strncmp(buf, "uid", 4)) {
330 return AIDE_ITEM_UID;
331 } else if (!strncmp(buf, "gid", 4)) {
332 return AIDE_ITEM_GID;
333 } else if (!strncmp(buf, "xattrs", 6)) {
334 return AIDE_ITEM_XATTRS;
336 LOG(LOG_ERR, "Unknown AIDE item [%s]\n", buf);
343 * load AIDE database from file
345 * filename base64(digest)
353 int loadAideDatabaseFile(AIDE_CONTEXT *ctx, char *filename) {
355 char buf[AIDE_SPEC_BUF_SIZE];
356 int items[AIDE_MAX_ITEM_NUM];
371 DEBUG_CAL("loadAideDatabaseFile - start, filename=[%s]\n", filename);
375 LOG(LOG_ERR, "null input");
378 if (filename == NULL) {
379 LOG(LOG_ERR, "null input");
383 fp = gzopen(filename, "r");
385 LOG(LOG_ERR, "%s missing\n", filename);
389 while (gzgets(fp, buf, sizeof(buf)) != NULL) {
390 if (!strncmp(buf, "#", 1)) {
391 } else if (!strncmp(buf, "@@begin_db", 10)) {
393 } else if (!strncmp(buf, "@@end_db", 8)) {
395 } else if (!strncmp(buf, "@@db_spec", 9)) {
398 end = buf + strlen(buf);
404 while ((ptr < end) && (*ptr == 0x20)) {
410 sep = strstr(ptr, " ");
412 LOG(LOG_ERR, "bad data, %s\n", buf);
419 items[item_num] = getAideItemIndex(ptr);
421 if (items[item_num] < 0) {
422 LOG(LOG_ERR, "Bad spec\n");
427 if (sep + 3 > end) break; // TODO(munetoh)
432 if (item_num > AIDE_MAX_ITEM_NUM) {
433 LOG(LOG_ERR, "loadAideDatabaseFile - %d items > %d \n", item_num, AIDE_MAX_ITEM_NUM);
436 DEBUG("loadAideDatabaseFile - has %d items\n", item_num);
437 } else if (body == 2) { /* DB items */
439 md = newAideMetadata();
443 end = buf + strlen(buf);
446 // *end = 0; // TODO(munetoh) remove \n
451 for (i = 0; i < item_num; i++) {
453 if (i != item_num - 1) {
454 sep = strstr(ptr, " ");
456 LOG(LOG_ERR, "bad data, %s\n", buf);
457 freeAideMetadata(md);
464 /* check the null string*/
465 if (!strncmp(ptr, "0", strlen(ptr))) {
467 } else if (!strncmp(ptr, "0\n", strlen(ptr))) {
474 case AIDE_ITEM_NAME: // char
476 md->name = smalloc_assert(ptr);
479 case AIDE_ITEM_LNAME: // char
481 md->lname = smalloc_assert(ptr);
484 case AIDE_ITEM_ATTR: // int
485 md->attr = atoi(ptr);
487 case AIDE_ITEM_SHA1: // base64
490 md->sha1 = decodeBase64(
492 SHA1_BASE64_DIGEST_SIZE,
494 if (md->sha1 == NULL) {
495 LOG(LOG_ERR, "decodeBase64 fail");
498 if (len != SHA1_DIGEST_SIZE) {
499 LOG(LOG_ERR, "bad SHA1 size %d %s\n", len, ptr);
500 printHex("digest", md->sha1, len, "\n");
504 case AIDE_ITEM_SHA256: // base64
506 md->sha256 = decodeBase64(
508 SHA256_BASE64_DIGEST_SIZE,
510 if (md->sha256 == NULL) {
511 LOG(LOG_ERR, "decodeBase64 fail");
514 if (len != SHA256_DIGEST_SIZE) {
515 LOG(LOG_ERR, "bad SHA256 size %d\n", len);
516 OUTPUT("base64 [%s] => [", ptr);
517 printHex("", (BYTE *)ptr, 2, " ");
519 printHex("", md->sha256, len, " ");
524 case AIDE_ITEM_SHA512: // base64
526 md->sha512 = decodeBase64(
528 SHA512_BASE64_DIGEST_SIZE,
530 if (md->sha512 == NULL) {
531 LOG(LOG_ERR, "decodeBase64 fail");
534 if (len != SHA512_DIGEST_SIZE) {
535 LOG(LOG_ERR, "bad SHA512 size %d\n", len);
536 OUTPUT("base64 [%s] => [", ptr);
537 printHex("", (BYTE *)ptr, 2, "");
539 printHex("", md->sha512, len, "");
544 case AIDE_ITEM_XATTRS:
545 // DEBUG("AIDE_ITEM_XATTRS\n");
548 // DEBUG("Unknown item[%d] %d\n", i, items[i]);
555 md->status = OPENPTS_AIDE_MD_STATUS_NEW;
556 addAideMetadata(ctx, md);
558 /* save to the hash table */
559 if (sha1_b64_ptr != NULL) {
560 // TODO SHA1 only, add hash agility later
562 sha1_b64_ptr[SHA1_BASE64_DIGEST_SIZE] = 0; // jXgiZyt0yUbP4QhAq9WFsLF/FL4= 28
563 md->hash_key = xmalloc(strlen(sha1_b64_ptr) +1);
565 memcpy(md->hash_key, sha1_b64_ptr, strlen(sha1_b64_ptr) + 1);
567 e.key = (char *)md->hash_key;
569 rc = hsearch_r(e, ENTER, &ep, ctx->aide_md_table);
572 if (errno == ENOMEM) {
573 LOG(LOG_ERR, " hsearch_r failed, table is full, errno=%x\n", errno);
575 LOG(LOG_ERR, " hsearch_r failed, errno=%x\n", errno);
578 // CAUTION too many messages, use for debugging the unit test
579 // DEBUG("Hash Table <- %4d [%s] %s\n", ctx->aide_md_table_size, md->hash_key, md->name);
580 ctx->aide_md_table_size++;
583 if (ctx->start == NULL) {
599 DEBUG("loadAideDatabaseFile - has %d entries\n", ctx->metadata_num);
600 DEBUG_CAL("loadAideDatabaseFile - done\n");
602 return ctx->metadata_num;
607 * read AIDE ignore name
615 int readAideIgnoreNameFile(AIDE_CONTEXT *ctx, char *filename) {
616 int rc = PTS_SUCCESS;
625 DEBUG_CAL("readAideIgnoreNameFile - start, filename=[%s]\n", filename);
629 LOG(LOG_ERR, "null input");
632 if (filename == NULL) {
633 LOG(LOG_ERR, "null input");
637 /* Open file for read */
638 fp = fopen(filename, "r");
640 DEBUG("%s missing\n", filename);
645 while (fgets(line, BUF_SIZE, fp) != NULL) { // read line
646 /* ignore comment, null line */
647 if (line[0] == '#') {
653 if (line[len-1] == 0x0a) line[len-1] = 0;
655 DEBUG("%4d [%s]\n", cnt, line);
658 list = xmalloc(sizeof(AIDE_LIST));
660 LOG(LOG_ERR, "no mem\n");
662 goto error; // return -1;
664 memset(list, 0, sizeof(AIDE_LIST));
665 list->name = smalloc_assert(line);
668 if (ctx->ignore_name_start == NULL) {
670 ctx->ignore_name_start = list;
671 ctx->ignore_name_end = list;
675 ctx->ignore_name_end->next = list;
676 ctx->ignore_name_end = list;
682 e.data = (void *)list;
683 rc = hsearch_r(e, ENTER, &ep, ctx->aide_in_table);
685 if (errno == ENOMEM) {
686 LOG(LOG_ERR, " hsearch_r failed, ignore name table is full, errno=%x\n", errno);
688 LOG(LOG_ERR, " hsearch_r failed, errno=%x\n", errno);
691 ctx->aide_in_table_size++;
700 DEBUG_CAL("readAideIgnoreNameFile - done, num = %d\n", cnt);
707 * print all AIDE data, for TEST and DEBUG
709 int printAideData(AIDE_CONTEXT *ctx) {
713 DEBUG_CAL("printAideData - start\n");
714 DEBUG("printAideData - num = %d\n", ctx->metadata_num);
718 LOG(LOG_ERR, "null input");
724 for (i = 0; i < ctx->metadata_num; i++) {
726 if ( md->name != NULL) OUTPUT("%30s ", md->name);
727 if ( md->lname != NULL) OUTPUT("%20s ", md->lname);
728 if ( md->attr != 0) OUTPUT("%08X ", md->attr);
729 if (md->sha1 != NULL)
730 printHex("", md->sha1, 20, " ");
734 if (md->sha256 != NULL)
735 printHex("", md->sha256, 32, " ");
743 DEBUG_CAL("printAideData - end\n");
749 int hexcmp(BYTE *d1, BYTE *d2, int len) {
752 for (i = 0; i < len; i++) {
753 if (d1[i] != d2[i]) {
762 // TODO(munetoh) how this work?
763 void copyAideMetadata(AIDE_METADATA *dst, AIDE_METADATA *src) {
764 if (dst->name == NULL) {
765 dst->name = xmalloc(strlen(src->name) + 1);
766 memcpy(dst->name, src->name, strlen(src->name) + 1);
772 * check AIDE MD vs given MD (SHA1)
774 * TODO(munetoh) obsolute use checkEventByAide()
776 int checkFileByAide(AIDE_CONTEXT *ctx, AIDE_METADATA *metadata) {
784 if (metadata == NULL) {
790 for (i = 0; i < ctx->metadata_num; i++) {
794 if ((metadata->sha1 != NULL) && (md->sha1 != NULL)) {
795 if (!hexcmp(metadata->sha1, md->sha1, SHA1_DIGEST_SIZE)) {
797 DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
798 md->status = OPENPTS_AIDE_MD_STATUS_HIT;
799 copyAideMetadata(metadata, md);
805 DEBUG_FSM("checkFileByAide - MISS\n");
817 int checkIgnoreList(AIDE_CONTEXT *ctx, char *name) {
823 LOG(LOG_ERR, "null input");
827 LOG(LOG_ERR, "checkIgnoreList() - name is null\n");
831 list = ctx->ignore_name_start;
832 while (list != NULL) {
833 // TODO(munetoh) not check the all string
834 if (list->name != NULL) {
835 len = strlen(list->name);
836 if (!strncmp(name, list->name, len)) {
838 DEBUG("HIT %s\n", name);
842 LOG(LOG_ERR, "checkIgnoreList() - list->name is null\n");
854 * check Eventlog with AIDE DB
857 * event->rgbEvent[0] - [20] <= SHA1 digest of the File
865 * skip this check 33sec -> 2sec
868 int checkEventByAide(AIDE_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
869 TSS_PCR_EVENT *event;
882 #endif // AIDE_CHBY_LIST
883 #endif // CONFIG_SQLITE
885 // DEBUG("checkEventByAide - start\n");
888 LOG(LOG_ERR, "checkEventByAide - AIDE_CONTEXT is NULL\n");
892 if (eventWrapper == NULL) {
893 LOG(LOG_ERR, "OcheckEventByAide - PENPTS_PCR_EVENT_WRAPPER is NULL\n");
897 event = eventWrapper->event;
899 // 20100627 ignore pseudo event
900 if (event->eventType == OPENPTS_PSEUDO_EVENT_TYPE) {
901 LOG(LOG_ERR, "validateImaMeasurement - event->eventType == OPENPTS_PSEUDO_EVENT_TYPE\n");
905 if (event->rgbEvent == NULL) {
910 if (event->ulPcrValueLength != SHA1_DIGEST_SIZE) {
911 DEBUG("bad digest size\n");
915 /* OK, let's find the HIT */
923 LOG(LOG_ERR, "encodeBase64 fail");
926 rc = verifyBySQLite(ctx, (char*)buf);
929 if (rc == OPENPTS_RESULT_VALID) {
931 // md = (AIDE_METADATA *) ep->data;
932 // DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
933 // md->status = OPENPTS_AIDE_MD_STATUS_HIT;
934 // md->event_wrapper = eventWrapper; // n:1
935 // eventWrapper->aide_metadata = md; // 1:n
936 // this output many lines:-P
937 // DEBUG("HIT [%s] \n",b64);
940 #else // CONFIG_SQLITE
944 for (i = 0; i < ctx->metadata_num; i++) {
946 DEBUG("AIDE MeataData is NULL\n");
950 if (md->sha1 != NULL) {
951 if (memcmp(event->rgbEvent, md->sha1, SHA1_DIGEST_SIZE) == 0) {
953 DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
954 md->status = OPENPTS_AIDE_MD_STATUS_HIT;
955 md->event_wrapper = eventWrapper; // n:1
956 eventWrapper->aide_metadata = md; // 1:n
957 // copyAideMetadata(metadata, md);
963 DEBUG_FSM("checkFileByAide - MISS\n");
971 LOG(LOG_ERR, "encodeBase64 fail");
974 e.key = (char *) buf; // size?
975 e.data = NULL; // just initialized for static analysys
981 // after (hash) BINARY
985 // after (hash) BASE64 :-(
993 rc = hsearch_r(e, FIND, &ep, ctx->aide_md_table);
996 // DEBUG("MD HIT\n");
997 md = (AIDE_METADATA *) ep->data;
998 DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
999 md->status = OPENPTS_AIDE_MD_STATUS_HIT;
1000 md->event_wrapper = eventWrapper; // n:1
1001 eventWrapper->aide_metadata = md; // 1:n
1002 // DEBUG("HIT [%s] %s\n",b64, md->name);
1005 // DEBUG("MISS [%s] MISS\n",b64);
1009 #endif // CONFIG_SQLITE
1011 /* check ignore list */
1014 name = (char *)event->rgbEvent;
1015 name += SHA1_DIGEST_SIZE;
1017 name = snmalloc(name, (event->ulEventLength - SHA1_DIGEST_SIZE));
1020 rc = checkIgnoreList(ctx, name);
1037 * Get AIDE metadata by name
1039 * "name" must be unique but
1040 * if multiple entries has sama name this returns first one. :-P
1042 AIDE_METADATA *getMetadataFromAideByName(AIDE_CONTEXT *ctx, char *name) {
1048 LOG(LOG_ERR, "null input");
1052 LOG(LOG_ERR, "null input");
1058 for (i = 0; i < ctx->metadata_num; i++) {
1062 if (md->name != NULL) {
1063 if (!strcmp(md->name, name)) {
1065 DEBUG("checkFileByAide HIT %s\n", name);
1075 * Convert the following char to %XX
1077 * Caller have to free out buffer;
1093 int escapeFilename(char **out, char *in) {
1100 LOG(LOG_ERR, "null input");
1105 /* rough malloc new buffer */
1106 buf = xmalloc(len*3);
1108 LOG(LOG_ERR, "no memory");
1114 for (i = 0; i < len; i++) {
1115 if (in[i] == 0x20) {
1120 } else if (in[i] == 0x25) {
1125 } else if (in[i] == 0x3A) {
1130 } else if (in[i] == 0x40) {
1135 } else if (in[i] == 0x5B) {
1140 } else if (in[i] == 0x5D) {
1145 } else if (in[i] == 0x7B) {
1150 } else if (in[i] == 0x7D) {
1155 } else if (in[i] == 0x7E) {
1173 * Convert IML TSS/file(ptscd.conf) to AIDE DB
1175 * ctx get the IML before call this func
1176 * filename output AIDE DB filename
1178 * TODO(munetoh) IMA_31 only
1180 int convertImlToAideDbFile(OPENPTS_CONTEXT *ctx, char *filename) {
1183 OPENPTS_SNAPSHOT *ss;
1184 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
1185 TSS_PCR_EVENT *event;
1188 char *aide_filename = NULL;
1191 DEBUG_CAL("convertImlToAideDbFile %s\n", filename);
1195 LOG(LOG_ERR, "null input");
1198 if (filename == NULL) {
1199 LOG(LOG_ERR, "null input");
1203 /* file open for write */
1204 fp = gzopen(filename, "wb");
1206 LOG(LOG_ERR, "%s fail to open\n", filename);
1211 gzprintf(fp, "@@begin_db\n");
1212 gzprintf(fp, "# This file was generated by OpenPTS\n");
1213 gzprintf(fp, "@@db_spec name sha1 \n");
1216 ss = getSnapshotFromTable(ctx->ss_table, 10, 1); // TODO def or conf
1218 LOG(LOG_ERR, "events is missing\n");
1221 eventWrapper = ss->start;
1222 if (eventWrapper == NULL) {
1223 LOG(LOG_ERR, "events is missing\n");
1227 event = eventWrapper->event;
1229 // DEBUG("PCR[%d]\n", ss->pcrIndex);
1230 // DEBUG("event_num %d\n", ss->event_num);
1232 // for (i = 0; i < ctx->eventNum; i++) {
1233 for (i = 0; i < ctx->ss_table->event_num; i++) { // TODO ss->event_num?
1234 // DEBUG("SM DEBUG event %p\n",event);
1236 if (event == NULL) {
1237 LOG(LOG_ERR, "event is NULL\n");
1241 if (event->rgbEvent == NULL) {
1242 LOG(LOG_ERR, "event->rgbEvent is NULL\n");
1246 // TODO 2010-10-05 SM
1247 // AIDE convert the following chars in filename
1248 // SPACE 0x20 -> "%20"
1258 // gzprintf(fp, "%s ",&eventWrapper->event->rgbEvent[20]);
1260 /* filename (allocated) */
1261 len = escapeFilename(&aide_filename, (char *) &eventWrapper->event->rgbEvent[20]);
1263 LOG(LOG_ERR, "convertImlToAideDbFile - no mem?\n");
1264 gzprintf(fp, "bad_filename ");
1266 gzprintf(fp, "%s ", aide_filename);
1267 xfree(aide_filename);
1268 aide_filename = NULL;
1273 (unsigned char *)event->rgbEvent,
1277 LOG(LOG_ERR, "encodeBase64 fail");
1280 gzprintf(fp, "%s \n", buf);
1283 eventWrapper = eventWrapper->next_pcr;
1284 if (eventWrapper == NULL) break;
1285 event = eventWrapper->event;
1289 gzprintf(fp, "@@end_db\n");
1292 gzseek(fp, 1L, SEEK_CUR); // add one \n
1295 if (aide_filename != NULL) xfree(aide_filename);
1297 DEBUG("convertImlToAideDbFile - done\n");
1299 return i+1; // event num
1303 * reduce the size of AIDE DB
1306 * AIDE-DB IMA-IML AIDE-DB
1307 * --------------------------
1312 * --------------------------
1315 * return AIDE entry count
1318 int writeReducedAidbDatabase(AIDE_CONTEXT *ctx, char *filename) {
1326 DEBUG("writeReducedAidbDatabase %s\n", filename);
1330 LOG(LOG_ERR, "null input");
1333 if (filename == NULL) {
1334 LOG(LOG_ERR, "null input");
1338 /* file open for write */
1339 fp = gzopen(filename, "wb");
1341 LOG(LOG_ERR, "%s fail to open\n", filename);
1346 gzprintf(fp, "@@begin_db\n");
1347 gzprintf(fp, "# This file was generated by OpenPTS\n");
1348 gzprintf(fp, "@@db_spec name sha1 \n");
1353 for (i = 0; i < ctx->metadata_num; i++) {
1358 if (md->status == OPENPTS_AIDE_MD_STATUS_HIT) {
1360 (unsigned char *)md->sha1,
1364 LOG(LOG_ERR, "encodeBase64 fail");
1367 gzprintf(fp, "%s ", md->name);
1368 gzprintf(fp, "%s \n", buf);
1377 gzprintf(fp, "@@end_db\n");
1380 gzseek(fp, 1L, SEEK_CUR); // add one \n
1383 DEBUG("convertImlToAideDbFile - done\n");
1389 #ifdef CONFIG_SQLITE
1391 * Convert AIDE BD file to SQLite DB file
1394 * 0 PTS_SUCCESS success
1395 * PTS_INTERNAL_ERROR ERROR
1397 int convertAideDbfileToSQLiteDbFile(char * aide_filename, char * sqlite_filename) {
1398 int rc = PTS_SUCCESS;
1408 if (aide_filename == NULL) {
1409 LOG(LOG_ERR, "AIDE file is null\n");
1410 return PTS_INTERNAL_ERROR;
1412 if (sqlite_filename == NULL) {
1413 LOG(LOG_ERR, "sqlite file is null\n");
1414 return PTS_INTERNAL_ERROR;
1418 /* new AIDE context */
1419 ctx = newAideContext();
1421 /* read AIDE DB file -> ctx */
1422 rc = loadAideDatabaseFile(ctx, aide_filename);
1424 LOG(LOG_ERR, "read AIDE DB %s fail, rc = %d", aide_filename, rc);
1431 /* rm existing DB file */
1432 remove(sqlite_filename);
1435 sqlite3_open(sqlite_filename, &db);
1437 LOG(LOG_ERR, "open AIDE DB fail\n");
1438 rc = PTS_INTERNAL_ERROR;
1443 "CREATE TABLE sample (id INTEGER PRIMARY KEY, digest TEXT NOT NULL, "
1444 "name TEXT NOT NULL, state INTEGER NOT NULL)",
1446 // DEBUG("CREATE err=%s\n", err);
1449 sqlite3_exec(db, "BEGIN", NULL, NULL, &err);
1450 // DEBUG("BEGIN err=%s\n", err);
1455 for (i = 0; i < ctx->metadata_num; i++) {
1456 if (md->hash_key != NULL) {
1457 sql = sqlite3_mprintf(
1458 "INSERT INTO sample (id, digest, name, state) VALUES (%d, '%s','%s', %d)",
1459 j, md->hash_key, md->name, 0);
1460 sqlite3_exec(db, sql, NULL, NULL, &err);
1461 // DEBUG("INSERT err=%s\n", err);
1468 sqlite3_exec(db, "COMMIT", NULL, NULL, &err);
1469 // DEBUG("COMMIT err=%s\n", err);
1472 sqlite3_exec(db, "CREATE INDEX digestindex ON sample(digest)", NULL, NULL, &err);
1473 // DEBUG("CREATE INDEX err=%s\n", err);
1482 freeAideContext(ctx);
1488 * load (open) SQLite DB file
1490 int loadSQLiteDatabaseFile(AIDE_CONTEXT *ctx, char *filename) {
1493 LOG(LOG_ERR, "ctx == NULL\n");
1494 return PTS_INTERNAL_ERROR;
1496 if (filename == NULL) {
1497 LOG(LOG_ERR, "filename == NULL\n");
1498 return PTS_INTERNAL_ERROR;
1502 sqlite3_open(filename, &ctx->sqlite_db);
1503 if (ctx->sqlite_db == NULL) {
1504 LOG(LOG_ERR, "open AIDE SQLite DB %s fail\n", filename);
1505 return PTS_INTERNAL_ERROR;
1514 int verifyBySQLite(AIDE_CONTEXT *ctx, char * key) {
1522 LOG(LOG_ERR, "ctx == NULL\n");
1523 return PTS_INTERNAL_ERROR;
1525 if (ctx->sqlite_db == NULL) {
1526 LOG(LOG_ERR, "ctx->sqlite_db == NULL\n");
1527 return PTS_INTERNAL_ERROR;
1530 sql = sqlite3_mprintf("SELECT * from sample where digest = '%s'", key);
1531 sqlite3_get_table(ctx->sqlite_db, sql, &result, &row, &col, &err);
1534 return OPENPTS_RESULT_VALID;
1540 sqlite3_free_table(result);
1542 return OPENPTS_RESULT_UNKNOWN;
1544 #endif // CONFIG_SQLITE