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 2011-07-06 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 *) malloc(sizeof(AIDE_METADATA));
84 if (metadata == NULL) {
88 memset(metadata, 0, sizeof(AIDE_METADATA));
98 * TODO(munetoh) sep. all and single
100 void freeAideMetadata(AIDE_METADATA *md) {
101 if (md == NULL) return;
103 if (md->next != NULL) {
104 freeAideMetadata(md->next);
108 if (md->name != NULL) free(md->name);
109 if (md->lname != NULL) free(md->lname);
110 if (md->sha1 != NULL) free(md->sha1);
111 if (md->sha256 != NULL) free(md->sha256);
112 if (md->ima_name != NULL) free(md->ima_name);
113 if (md->hash_key != NULL) free(md->hash_key);
124 int addAideMetadata(AIDE_CONTEXT *ctx, AIDE_METADATA *md) {
128 if (ctx->start == NULL) {
142 // #define AIDE_CHBY_LIST 1
143 #define AIDE_CHBY_LIST 0
145 #define AIDE_HASH_TABLE_SIZE 16000
151 #define AIDE_HASH_CHECK_SIZE SHA1_DIGEST_SIZE
152 // #define AIDE_HASH_CHECK_SIZE 20
157 AIDE_CONTEXT * newAideContext() {
161 // DEBUG("newAideContext()\n");
163 ctx = malloc(sizeof(AIDE_CONTEXT));
165 ERROR("no memory\n");
168 memset(ctx, 0, sizeof(AIDE_CONTEXT));
171 // TODO set the size in openpts.h
172 ctx->aide_md_table = malloc(sizeof(struct hsearch_data));
174 memset(ctx->aide_md_table, 0, sizeof(struct hsearch_data));
175 rc = hcreate_r(AIDE_HASH_TABLE_SIZE, ctx->aide_md_table); // hash table for metadata
177 ERROR("hcreate faild, errno=%x\n", errno);
180 ctx->aide_md_table_size = 0;
182 ctx->aide_in_table = malloc(sizeof(struct hsearch_data));
184 memset(ctx->aide_in_table, 0, sizeof(struct hsearch_data));
186 rc = hcreate_r(AIDE_HASH_TABLE_SIZE, ctx->aide_in_table); // hash table for ignore name
188 ERROR("hcreate faild\n");
191 ctx->aide_in_table_size = 0;
193 DEBUG("newAideContext %p\n", ctx);
197 if (ctx != NULL) free(ctx);
204 void freeAideIgnoreList(AIDE_LIST *list) {
209 if (list->next != NULL) {
210 freeAideIgnoreList(list->next);
215 if (list->name != NULL) {
227 void freeAideContext(AIDE_CONTEXT *ctx) {
230 ERROR("ctx is NULL\n");
233 DEBUG("freeAideContext %p \n", ctx);
235 // DEBUG("aide_md_table_size = %d\n", ctx->aide_md_table_size);
236 // DEBUG("aide_in_table_size = %d\n", ctx->aide_in_table_size);
239 hdestroy_r(ctx->aide_md_table);
240 hdestroy_r(ctx->aide_in_table);
242 free(ctx->aide_md_table);
243 free(ctx->aide_in_table);
246 if (ctx->sqlite_db != NULL) {
248 sqlite3_close(ctx->sqlite_db);
252 /* free metadata chain */
253 if (ctx->start != NULL) {
254 freeAideMetadata(ctx->start);
257 /* free ignore list */
258 if (ctx->ignore_name_start != NULL) {
259 // DEBUG("free tx->ignore_name_start\n");
260 freeAideIgnoreList(ctx->ignore_name_start);
269 * load AIDE db file (giped)
271 name lname attr sha1 sha256
272 /bin/vi 0 1073750017 C9ID19uSxnrv/Bt0uYbloaVO1SQ= VTYuAxsuG4pmWHP9ZCTO1KUsYk2uwTvwiCJ/OxzsVd0=
274 /bin/dnsdomainname hostname 3 0 0
278 #define AIDE_SPEC_BUF_SIZE 1024
279 #define AIDE_MAX_ITEM_NUM 20
280 #define AIDE_MAX_ITEM_SIZE 10
282 // TODO(munetoh) add more...
283 #define AIDE_ITEM_NAME 0 // char
284 #define AIDE_ITEM_LNAME 1 // int
285 #define AIDE_ITEM_ATTR 2 // int
286 #define AIDE_ITEM_SHA1 3 // base64
287 #define AIDE_ITEM_SHA256 4 // base64
288 #define AIDE_ITEM_SHA512 5 // base64
289 #define AIDE_ITEM_PERM 6 //
290 #define AIDE_ITEM_UID 7 //
291 #define AIDE_ITEM_GID 8 //
292 #define AIDE_ITEM_ACL 9 //
293 #define AIDE_ITEM_XATTRS 10 //
295 int getAideItemIndex(char *buf) {
296 if (!strncmp(buf, "name", 4)) {
297 return AIDE_ITEM_NAME;
298 } else if (!strncmp(buf, "lname", 5)) {
299 return AIDE_ITEM_LNAME;
300 } else if (!strncmp(buf, "attr", 4)) {
301 return AIDE_ITEM_ATTR;
302 } else if (!strncmp(buf, "sha1", 4)) {
303 return AIDE_ITEM_SHA1;
304 } else if (!strncmp(buf, "sha256", 6)) {
305 return AIDE_ITEM_SHA256;
306 } else if (!strncmp(buf, "sha512", 6)) {
307 return AIDE_ITEM_SHA512;
308 } else if (!strncmp(buf, "perm", 4)) {
309 return AIDE_ITEM_PERM;
310 } else if (!strncmp(buf, "acl", 4)) {
311 return AIDE_ITEM_ACL;
312 } else if (!strncmp(buf, "uid", 4)) {
313 return AIDE_ITEM_UID;
314 } else if (!strncmp(buf, "gid", 4)) {
315 return AIDE_ITEM_GID;
316 } else if (!strncmp(buf, "xattrs", 6)) {
317 return AIDE_ITEM_XATTRS;
319 ERROR("Unknown AIDE item [%s]\n", buf);
326 * load AIDE database from file
328 * filename base64(digest)
333 int loadAideDatabaseFile(AIDE_CONTEXT *ctx, char *filename) {
335 char buf[AIDE_SPEC_BUF_SIZE];
336 int items[AIDE_MAX_ITEM_NUM];
352 DEBUG("loadAideDatabaseFile - start, filename=[%s]\n", filename);
354 fp = gzopen(filename, "r");
356 ERROR("%s missing\n", filename);
360 while (gzgets(fp, buf, sizeof(buf)) != NULL) {
361 if (!strncmp(buf, "#", 1)) {
362 } else if (!strncmp(buf, "@@begin_db", 10)) {
364 } else if (!strncmp(buf, "@@end_db", 8)) {
366 } else if (!strncmp(buf, "@@db_spec", 9)) {
369 end = buf + strlen(buf);
375 while ((ptr < end) && (*ptr == 0x20)) {
376 printf("skip %d ", *ptr);
381 sep = strstr(ptr, " ");
383 ERROR("bad data, %s\n", buf);
390 items[item_num] = getAideItemIndex(ptr);
392 if (items[item_num] < 0) {
398 if (sep + 3 > end) break; // TODO(munetoh)
403 if (item_num > AIDE_MAX_ITEM_NUM) {
404 ERROR("loadAideDatabaseFile - %d items > %d \n", item_num, AIDE_MAX_ITEM_NUM);
407 DEBUG("loadAideDatabaseFile - has %d items\n", item_num);
408 } else if (body == 2) { /* DB items */
410 md = newAideMetadata();
414 end = buf + strlen(buf);
417 // *end = 0; // TODO(munetoh) remove \n
422 for (i = 0; i < item_num; i++) {
424 if (i != item_num - 1) {
425 // printf("SEP %d %d\n",i, item_num);
426 sep = strstr(ptr, " ");
428 ERROR("bad data, %s\n", buf);
429 freeAideMetadata(md);
436 /* check the null string*/
437 if (!strncmp(ptr, "0", strlen(ptr))) {
439 } else if (!strncmp(ptr, "0\n", strlen(ptr))) {
446 case AIDE_ITEM_NAME: // char
448 md->name = smalloc(ptr);
451 case AIDE_ITEM_LNAME: // char
453 md->lname = smalloc(ptr);
456 case AIDE_ITEM_ATTR: // int
457 md->attr = atoi(ptr);
459 case AIDE_ITEM_SHA1: // base64
462 md->sha1 = malloc(SHA1_DIGEST_SIZE + 8);
465 (unsigned char *)ptr,
466 SHA1_BASE64_DIGEST_SIZE);
467 if (len != SHA1_DIGEST_SIZE) {
468 ERROR("bad SHA1 size %d %s\n", len, ptr);
469 // printf("base64 [%s] => [", ptr);
470 printHex("digest", md->sha1, len, "\n");
475 case AIDE_ITEM_SHA256: // base64
477 md->sha256 = malloc(SHA256_DIGEST_SIZE);
480 (unsigned char *)ptr,
481 SHA256_BASE64_DIGEST_SIZE);
482 if (len != SHA256_DIGEST_SIZE) {
483 ERROR("bad SHA256 size %d\n", len);
484 printf("base64 [%s] => [", ptr);
485 printHex("", (BYTE *)ptr, 2, " ");
487 printHex("", md->sha256, len, " ");
492 case AIDE_ITEM_SHA512: // base64
494 md->sha512 = malloc(SHA512_DIGEST_SIZE);
497 (unsigned char *)ptr,
498 SHA512_BASE64_DIGEST_SIZE);
499 if (len != SHA512_DIGEST_SIZE) {
500 ERROR("bad SHA512 size %d\n", len);
501 printf("base64 [%s] => [", ptr);
502 printHex("", (BYTE *)ptr, 2, "");
504 printHex("", md->sha512, len, "");
509 case AIDE_ITEM_XATTRS:
510 // DEBUG("AIDE_ITEM_XATTRS\n");
513 // DEBUG("Unknown item[%d] %d\n", i, items[i]);
520 md->status = OPENPTS_AIDE_MD_STATUS_NEW;
521 addAideMetadata(ctx, md);
523 /* save to the hash table */
524 if (sha1_b64_ptr != NULL) {
525 // TODO SHA1 only, add hash agility later
527 sha1_b64_ptr[SHA1_BASE64_DIGEST_SIZE] = 0; // jXgiZyt0yUbP4QhAq9WFsLF/FL4= 28
528 md->hash_key = malloc(strlen(sha1_b64_ptr) +1);
530 memcpy(md->hash_key, sha1_b64_ptr, strlen(sha1_b64_ptr) + 1);
532 e.key = (char *)md->hash_key;
534 rc = hsearch_r(e, ENTER, &ep, ctx->aide_md_table);
537 if (errno == ENOMEM) {
538 ERROR(" hsearch_r failed, table is full, errno=%x\n", errno);
540 ERROR(" hsearch_r failed, errno=%x\n", errno);
543 // CAUTION too many messages, use for debugging the unit test
544 // DEBUG("Hash Table <- %4d [%s] %s\n", ctx->aide_md_table_size, md->hash_key, md->name);
545 ctx->aide_md_table_size++;
550 if (ctx->start == NULL) {
561 // ignore printf("??? [%s]\n", buf);
566 DEBUG("loadAideDatabaseFile - has %d entries\n", ctx->metadata_num);
567 DEBUG("loadAideDatabaseFile - done\n");
569 return ctx->metadata_num;
574 * read AIDE ignore name
582 int readAideIgnoreNameFile(AIDE_CONTEXT *ctx, char *filename) {
583 int rc = PTS_SUCCESS;
592 DEBUG("readAideIgnoreNameFile - start, filename=[%s]\n", filename);
594 /* Open file for read */
595 fp = fopen(filename, "r");
597 DEBUG("%s missing\n", filename);
603 while (fgets(line, BUF_SIZE, fp) != NULL) { // read line
604 /* ignore comment, null line */
605 if (line[0] == '#') {
611 if (line[len-1] == 0x0a) line[len-1] = 0;
613 DEBUG("%4d [%s]\n", cnt, line);
616 list = malloc(sizeof(AIDE_LIST));
620 goto error; // return -1;
622 memset(list, 0, sizeof(AIDE_LIST));
623 list->name = smalloc(line);
626 if (ctx->ignore_name_start == NULL) {
628 ctx->ignore_name_start = list;
629 ctx->ignore_name_end = list;
633 ctx->ignore_name_end->next = list;
634 ctx->ignore_name_end = list;
640 e.data = (void *)list;
641 rc = hsearch_r(e, ENTER, &ep, ctx->aide_in_table);
643 if (errno == ENOMEM) {
644 ERROR(" hsearch_r failed, ignore name table is full, errno=%x\n", errno);
646 ERROR(" hsearch_r failed, errno=%x\n", errno);
649 ctx->aide_in_table_size++;
658 DEBUG("readAideIgnoreNameFile - done, num = %d\n", cnt);
665 * print all AIDE data, for TEST and DEBUG
667 int printAideData(AIDE_CONTEXT *ctx) {
671 DEBUG("printAideData - start\n");
672 DEBUG("printAideData - num = %d\n", ctx->metadata_num);
676 for (i = 0; i < ctx->metadata_num; i++) {
678 if ( md->name != NULL) printf("%30s ", md->name);
679 if ( md->lname != NULL) printf("%20s ", md->lname);
680 if ( md->attr != 0) printf("%08X ", md->attr);
681 if (md->sha1 != NULL)
682 printHex("", md->sha1, 20, " ");
686 if (md->sha256 != NULL)
687 printHex("", md->sha256, 32, " ");
695 DEBUG("printAideData - end\n");
701 int hexcmp(BYTE *d1, BYTE *d2, int len) {
704 for (i = 0; i < len; i++) {
705 if (d1[i] != d2[i]) {
714 // TODO(munetoh) how this work?
715 void copyAideMetadata(AIDE_METADATA *dst, AIDE_METADATA *src) {
716 if (dst->name == NULL) {
717 dst->name = malloc(strlen(src->name) + 1);
718 memcpy(dst->name, src->name, strlen(src->name) + 1);
723 * check AIDE MD vs given MD (SHA1)
725 * TODO(munetoh) obsolute use checkEventByAide()
727 int checkFileByAide(AIDE_CONTEXT *ctx, AIDE_METADATA *metadata) {
735 if (metadata == NULL) {
741 for (i = 0; i < ctx->metadata_num; i++) {
745 if ((metadata->sha1 != NULL) && (md->sha1 != NULL)) {
746 if (!hexcmp(metadata->sha1, md->sha1, SHA1_DIGEST_SIZE)) {
748 DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
749 md->status = OPENPTS_AIDE_MD_STATUS_HIT;
750 copyAideMetadata(metadata, md);
756 DEBUG_FSM("checkFileByAide - MISS\n");
768 int checkIgnoreList(AIDE_CONTEXT *ctx, char *name) {
774 ERROR("checkIgnoreList() - name is null\n");
778 list = ctx->ignore_name_start;
779 while (list != NULL) {
780 // TODO(munetoh) not check the all string
781 if (list->name != NULL) {
782 len = strlen(list->name);
783 if (!strncmp(name, list->name, len)) {
785 DEBUG("HIT %s\n", name);
789 ERROR("checkIgnoreList() - list->name is null\n");
801 * check Eventlog with AIDE DB
804 * event->rgbEvent[0] - [20] <= SHA1 digest of the File
812 * skip this check 33sec -> 2sec
815 int checkEventByAide(AIDE_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
816 TSS_PCR_EVENT *event;
820 BYTE b64[SHA1_BASE64_DIGEST_SIZE+1];
828 BYTE b64[SHA1_BASE64_DIGEST_SIZE+1];
830 #endif // CONFIG_SQLITE
832 // DEBUG("checkEventByAide - start\n");
835 ERROR("checkEventByAide - AIDE_CONTEXT is NULL\n");
839 if (eventWrapper == NULL) {
840 ERROR("OcheckEventByAide - PENPTS_PCR_EVENT_WRAPPER is NULL\n");
844 event = eventWrapper->event;
846 // 20100627 ignore pseudo event
847 if (event->eventType == OPENPTS_PSEUDO_EVENT_TYPE) {
848 ERROR("validateImaMeasurement - event->eventType == OPENPTS_PSEUDO_EVENT_TYPE\n");
852 if (event->rgbEvent == NULL) {
857 if (event->ulPcrValueLength != SHA1_DIGEST_SIZE) {
858 DEBUG("bad digest size\n");
862 /* OK, let's find the HIT */
865 encodeBase64(b64, event->rgbEvent, 20);
866 b64[SHA1_BASE64_DIGEST_SIZE] = 0;
868 rc = verifyBySQLite(ctx, (char*)b64);
870 if (rc == OPENPTS_RESULT_VALID) {
872 // md = (AIDE_METADATA *) ep->data;
873 // DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
874 // md->status = OPENPTS_AIDE_MD_STATUS_HIT;
875 // md->event_wrapper = eventWrapper; // n:1
876 // eventWrapper->aide_metadata = md; // 1:n
877 // this output many lines:-P
878 // DEBUG("HIT [%s] \n",b64);
881 #else // CONFIG_SQLITE
885 for (i = 0; i < ctx->metadata_num; i++) {
887 DEBUG("AIDE MeataData is NULL\n");
891 if (md->sha1 != NULL) {
892 if (memcmp(event->rgbEvent, md->sha1, SHA1_DIGEST_SIZE) == 0) {
894 DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
895 md->status = OPENPTS_AIDE_MD_STATUS_HIT;
896 md->event_wrapper = eventWrapper; // n:1
897 eventWrapper->aide_metadata = md; // 1:n
898 // copyAideMetadata(metadata, md);
904 DEBUG_FSM("checkFileByAide - MISS\n");
907 encodeBase64(b64, event->rgbEvent, 20);
908 b64[SHA1_BASE64_DIGEST_SIZE] = 0;
910 e.key = (char *) b64; // size?
911 e.data = NULL; // just initialized for static analysys
917 // after (hash) BINARY
921 // after (hash) BASE64 :-(
929 rc = hsearch_r(e, FIND, &ep, ctx->aide_md_table);
932 // DEBUG("MD HIT\n");
933 md = (AIDE_METADATA *) ep->data;
934 DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
935 md->status = OPENPTS_AIDE_MD_STATUS_HIT;
936 md->event_wrapper = eventWrapper; // n:1
937 eventWrapper->aide_metadata = md; // 1:n
938 // DEBUG("HIT [%s] %s\n",b64, md->name);
941 // DEBUG("MISS [%s] MISS\n",b64);
945 #endif // CONFIG_SQLITE
947 /* check ignore list */
950 name = (char *)event->rgbEvent;
951 name += SHA1_DIGEST_SIZE;
953 name = snmalloc(name, (event->ulEventLength - SHA1_DIGEST_SIZE));
956 rc = checkIgnoreList(ctx, name);
973 * Get AIDE metadata by name
975 * "name" must be unique but
976 * if multiple entries has sama name this returns first one. :-P
978 AIDE_METADATA *getMetadataFromAideByName(AIDE_CONTEXT *ctx, char *name) {
992 for (i = 0; i < ctx->metadata_num; i++) {
996 if (md->name != NULL) {
997 if (!strcmp(md->name, name)) {
999 DEBUG("checkFileByAide HIT %s\n", name);
1009 * Convert the following char to %XX
1011 * Caller have to free out buffer;
1027 int escapeFilename(char **out, char *in) {
1034 /* rough malloc new buffer */
1035 buf = malloc(len*3);
1037 ERROR("no memory\n");
1043 for (i = 0; i < len; i++) {
1044 if (in[i] == 0x20) {
1049 } else if (in[i] == 0x25) {
1054 } else if (in[i] == 0x3A) {
1059 } else if (in[i] == 0x40) {
1064 } else if (in[i] == 0x5B) {
1069 } else if (in[i] == 0x5D) {
1074 } else if (in[i] == 0x7B) {
1079 } else if (in[i] == 0x7D) {
1084 } else if (in[i] == 0x7E) {
1102 * Convert IML TSS/file(ptscd.conf) to AIDE DB
1104 * ctx get the IML before call this func
1105 * filename output AIDE DB filename
1107 * TODO(munetoh) IMA_31 only
1109 int convertImlToAideDbFile(OPENPTS_CONTEXT *ctx, char *filename) {
1112 OPENPTS_SNAPSHOT *ss;
1113 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
1114 TSS_PCR_EVENT *event;
1115 unsigned char buf[128]; // TODO(munetoh)
1116 char *aide_filename = NULL;
1119 DEBUG("convertImlToAideDbFile %s\n", filename);
1121 /* file open for write */
1122 fp = gzopen(filename, "wb");
1124 ERROR("%s fail to open\n", filename);
1129 gzprintf(fp, "@@begin_db\n");
1130 gzprintf(fp, "# This file was generated by OpenPTS\n");
1131 gzprintf(fp, "@@db_spec name sha1 \n");
1134 ss = getSnapshotFromTable(ctx->ss_table, 10, 1); // TODO def or conf
1136 ERROR("events is missing\n");
1139 eventWrapper = ss->start;
1140 if (eventWrapper == NULL) {
1141 ERROR("events is missing\n");
1145 event = eventWrapper->event;
1147 // DEBUG("PCR[%d]\n", ss->pcrIndex);
1148 // DEBUG("event_num %d\n", ss->event_num);
1150 // for (i = 0; i < ctx->eventNum; i++) {
1151 for (i = 0; i < ctx->ss_table->event_num; i++) { // TODO ss->event_num?
1152 memset(buf, 0, sizeof(buf));
1153 // DEBUG("SM DEBUG event %p\n",event);
1155 if (event == NULL) {
1156 ERROR("event is NULL\n");
1160 if (event->rgbEvent == NULL) {
1161 ERROR("event->rgbEvent is NULL\n");
1165 // TODO 2010-10-05 SM
1166 // AIDE convert the following chars in filename
1167 // SPACE 0x20 -> "%20"
1177 // gzprintf(fp, "%s ",&eventWrapper->event->rgbEvent[20]);
1179 /* filename (allocated) */
1180 len = escapeFilename(&aide_filename, (char *) &eventWrapper->event->rgbEvent[20]);
1182 ERROR("convertImlToAideDbFile - no mem?\n");
1183 gzprintf(fp, "bad_filename ");
1185 gzprintf(fp, "%s ", aide_filename);
1186 free(aide_filename);
1187 aide_filename = NULL;
1191 encodeBase64(buf, (unsigned char *)event->rgbEvent, SHA1_DIGEST_SIZE);
1192 gzprintf(fp, "%s \n", buf);
1194 // printf("%d %s\n", i, buf);
1196 eventWrapper = eventWrapper->next_pcr;
1197 if (eventWrapper == NULL) break;
1198 event = eventWrapper->event;
1202 gzprintf(fp, "@@end_db\n");
1205 gzseek(fp, 1L, SEEK_CUR); // add one \n
1208 if (aide_filename != NULL) free(aide_filename);
1210 DEBUG("convertImlToAideDbFile - done\n");
1212 return i+1; // event num
1216 * reduce the size of AIDE DB
1219 * AIDE-DB IMA-IML AIDE-DB
1220 * --------------------------
1225 * --------------------------
1228 * return AIDE entry count
1231 int writeReducedAidbDatabase(AIDE_CONTEXT *ctx, char *filename) {
1236 unsigned char buf[128]; // TODO(munetoh)
1238 DEBUG("writeReducedAidbDatabase %s\n", filename);
1244 /* file open for write */
1245 fp = gzopen(filename, "wb");
1247 ERROR("%s fail to open\n", filename);
1252 gzprintf(fp, "@@begin_db\n");
1253 gzprintf(fp, "# This file was generated by OpenPTS\n");
1254 gzprintf(fp, "@@db_spec name sha1 \n");
1259 for (i = 0; i < ctx->metadata_num; i++) {
1264 if (md->status == OPENPTS_AIDE_MD_STATUS_HIT) {
1266 memset(buf, 0, sizeof(buf));
1267 encodeBase64(buf, (unsigned char *)md->sha1, SHA1_DIGEST_SIZE);
1268 gzprintf(fp, "%s ", md->name);
1269 gzprintf(fp, "%s \n", buf);
1277 gzprintf(fp, "@@end_db\n");
1280 gzseek(fp, 1L, SEEK_CUR); // add one \n
1283 DEBUG("convertImlToAideDbFile - done\n");
1289 #ifdef CONFIG_SQLITE
1291 * Convert AIDE BD file to SQLite DB file
1294 * 0 PTS_SUCCESS success
1295 * PTS_INTERNAL_ERROR ERROR
1297 int convertAideDbfileToSQLiteDbFile(char * aide_filename, char * sqlite_filename) {
1298 int rc = PTS_SUCCESS;
1308 if (aide_filename == NULL) {
1309 ERROR("AIDE file is null\n");
1310 return PTS_INTERNAL_ERROR;
1312 if (sqlite_filename == NULL) {
1313 ERROR("sqlite file is null\n");
1314 return PTS_INTERNAL_ERROR;
1318 /* new AIDE context */
1319 ctx = newAideContext();
1321 /* read AIDE DB file -> ctx */
1322 rc = loadAideDatabaseFile(ctx, aide_filename);
1324 ERROR("read AIDE DB %s fail, rc = %d", aide_filename, rc);
1331 /* rm existing DB file */
1332 remove(sqlite_filename);
1335 sqlite3_open(sqlite_filename, &db);
1337 ERROR("open AIDE DB fail\n");
1338 rc = PTS_INTERNAL_ERROR;
1343 "CREATE TABLE sample (id INTEGER PRIMARY KEY, digest TEXT NOT NULL, "
1344 "name TEXT NOT NULL, state INTEGER NOT NULL)",
1346 // DEBUG("CREATE err=%s\n", err);
1349 sqlite3_exec(db, "BEGIN", NULL, NULL, &err);
1350 // DEBUG("BEGIN err=%s\n", err);
1355 for (i = 0; i < ctx->metadata_num; i++) {
1356 if (md->hash_key != NULL) {
1357 sql = sqlite3_mprintf(
1358 "INSERT INTO sample (id, digest, name, state) VALUES (%d, '%s','%s', %d)",
1359 j, md->hash_key, md->name, 0);
1360 sqlite3_exec(db, sql, NULL, NULL, &err);
1361 // DEBUG("INSERT err=%s\n", err);
1368 sqlite3_exec(db, "COMMIT", NULL, NULL, &err);
1369 // DEBUG("COMMIT err=%s\n", err);
1372 sqlite3_exec(db, "CREATE INDEX digestindex ON sample(digest)", NULL, NULL, &err);
1373 // DEBUG("CREATE INDEX err=%s\n", err);
1382 freeAideContext(ctx);
1388 * load (open) SQLite DB file
1390 int loadSQLiteDatabaseFile(AIDE_CONTEXT *ctx, char *filename) {
1393 ERROR("ctx == NULL\n");
1394 return PTS_INTERNAL_ERROR;
1396 if (filename == NULL) {
1397 ERROR("filename == NULL\n");
1398 return PTS_INTERNAL_ERROR;
1402 sqlite3_open(filename, &ctx->sqlite_db);
1403 if (ctx->sqlite_db == NULL) {
1404 ERROR("open AIDE SQLite DB %s fail\n", filename);
1405 return PTS_INTERNAL_ERROR;
1414 int verifyBySQLite(AIDE_CONTEXT *ctx, char * key) {
1422 ERROR("ctx == NULL\n");
1423 return PTS_INTERNAL_ERROR;
1425 if (ctx->sqlite_db == NULL) {
1426 ERROR("ctx->sqlite_db == NULL\n");
1427 return PTS_INTERNAL_ERROR;
1430 sql = sqlite3_mprintf("SELECT * from sample where digest = '%s'", key);
1431 sqlite3_get_table(ctx->sqlite_db, sql, &result, &row, &col, &err);
1432 // DEBUG("%2d %d %s\n",row,col, md->hash_key);
1435 return OPENPTS_RESULT_VALID;
1438 // ERROR("row = %d\n",row);
1443 sqlite3_free_table(result);
1447 return OPENPTS_RESULT_UNKNOWN;
1449 #endif // CONFIG_SQLITE