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 = decodeBase64(
464 SHA1_BASE64_DIGEST_SIZE,
466 if (md->sha1 == NULL) {
467 ERROR("decodeBase64 fail");
470 if (len != SHA1_DIGEST_SIZE) {
471 ERROR("bad SHA1 size %d %s\n", len, ptr);
472 // printf("base64 [%s] => [", ptr);
473 printHex("digest", md->sha1, len, "\n");
478 case AIDE_ITEM_SHA256: // base64
480 md->sha256 = decodeBase64(
482 SHA256_BASE64_DIGEST_SIZE,
484 if (md->sha256 == NULL) {
485 ERROR("decodeBase64 fail");
488 if (len != SHA256_DIGEST_SIZE) {
489 ERROR("bad SHA256 size %d\n", len);
490 printf("base64 [%s] => [", ptr);
491 printHex("", (BYTE *)ptr, 2, " ");
493 printHex("", md->sha256, len, " ");
498 case AIDE_ITEM_SHA512: // base64
500 md->sha512 = decodeBase64(
502 SHA512_BASE64_DIGEST_SIZE,
504 if (md->sha512 == NULL) {
505 ERROR("decodeBase64 fail");
508 if (len != SHA512_DIGEST_SIZE) {
509 ERROR("bad SHA512 size %d\n", len);
510 printf("base64 [%s] => [", ptr);
511 printHex("", (BYTE *)ptr, 2, "");
513 printHex("", md->sha512, len, "");
518 case AIDE_ITEM_XATTRS:
519 // DEBUG("AIDE_ITEM_XATTRS\n");
522 // DEBUG("Unknown item[%d] %d\n", i, items[i]);
529 md->status = OPENPTS_AIDE_MD_STATUS_NEW;
530 addAideMetadata(ctx, md);
532 /* save to the hash table */
533 if (sha1_b64_ptr != NULL) {
534 // TODO SHA1 only, add hash agility later
536 sha1_b64_ptr[SHA1_BASE64_DIGEST_SIZE] = 0; // jXgiZyt0yUbP4QhAq9WFsLF/FL4= 28
537 md->hash_key = malloc(strlen(sha1_b64_ptr) +1);
539 memcpy(md->hash_key, sha1_b64_ptr, strlen(sha1_b64_ptr) + 1);
541 e.key = (char *)md->hash_key;
543 rc = hsearch_r(e, ENTER, &ep, ctx->aide_md_table);
546 if (errno == ENOMEM) {
547 ERROR(" hsearch_r failed, table is full, errno=%x\n", errno);
549 ERROR(" hsearch_r failed, errno=%x\n", errno);
552 // CAUTION too many messages, use for debugging the unit test
553 // DEBUG("Hash Table <- %4d [%s] %s\n", ctx->aide_md_table_size, md->hash_key, md->name);
554 ctx->aide_md_table_size++;
559 if (ctx->start == NULL) {
570 // ignore printf("??? [%s]\n", buf);
575 DEBUG("loadAideDatabaseFile - has %d entries\n", ctx->metadata_num);
576 DEBUG("loadAideDatabaseFile - done\n");
578 return ctx->metadata_num;
583 * read AIDE ignore name
591 int readAideIgnoreNameFile(AIDE_CONTEXT *ctx, char *filename) {
592 int rc = PTS_SUCCESS;
601 DEBUG("readAideIgnoreNameFile - start, filename=[%s]\n", filename);
603 /* Open file for read */
604 fp = fopen(filename, "r");
606 DEBUG("%s missing\n", filename);
612 while (fgets(line, BUF_SIZE, fp) != NULL) { // read line
613 /* ignore comment, null line */
614 if (line[0] == '#') {
620 if (line[len-1] == 0x0a) line[len-1] = 0;
622 DEBUG("%4d [%s]\n", cnt, line);
625 list = malloc(sizeof(AIDE_LIST));
629 goto error; // return -1;
631 memset(list, 0, sizeof(AIDE_LIST));
632 list->name = smalloc(line);
635 if (ctx->ignore_name_start == NULL) {
637 ctx->ignore_name_start = list;
638 ctx->ignore_name_end = list;
642 ctx->ignore_name_end->next = list;
643 ctx->ignore_name_end = list;
649 e.data = (void *)list;
650 rc = hsearch_r(e, ENTER, &ep, ctx->aide_in_table);
652 if (errno == ENOMEM) {
653 ERROR(" hsearch_r failed, ignore name table is full, errno=%x\n", errno);
655 ERROR(" hsearch_r failed, errno=%x\n", errno);
658 ctx->aide_in_table_size++;
667 DEBUG("readAideIgnoreNameFile - done, num = %d\n", cnt);
674 * print all AIDE data, for TEST and DEBUG
676 int printAideData(AIDE_CONTEXT *ctx) {
680 DEBUG("printAideData - start\n");
681 DEBUG("printAideData - num = %d\n", ctx->metadata_num);
685 for (i = 0; i < ctx->metadata_num; i++) {
687 if ( md->name != NULL) printf("%30s ", md->name);
688 if ( md->lname != NULL) printf("%20s ", md->lname);
689 if ( md->attr != 0) printf("%08X ", md->attr);
690 if (md->sha1 != NULL)
691 printHex("", md->sha1, 20, " ");
695 if (md->sha256 != NULL)
696 printHex("", md->sha256, 32, " ");
704 DEBUG("printAideData - end\n");
710 int hexcmp(BYTE *d1, BYTE *d2, int len) {
713 for (i = 0; i < len; i++) {
714 if (d1[i] != d2[i]) {
723 // TODO(munetoh) how this work?
724 void copyAideMetadata(AIDE_METADATA *dst, AIDE_METADATA *src) {
725 if (dst->name == NULL) {
726 dst->name = malloc(strlen(src->name) + 1);
727 memcpy(dst->name, src->name, strlen(src->name) + 1);
732 * check AIDE MD vs given MD (SHA1)
734 * TODO(munetoh) obsolute use checkEventByAide()
736 int checkFileByAide(AIDE_CONTEXT *ctx, AIDE_METADATA *metadata) {
744 if (metadata == NULL) {
750 for (i = 0; i < ctx->metadata_num; i++) {
754 if ((metadata->sha1 != NULL) && (md->sha1 != NULL)) {
755 if (!hexcmp(metadata->sha1, md->sha1, SHA1_DIGEST_SIZE)) {
757 DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
758 md->status = OPENPTS_AIDE_MD_STATUS_HIT;
759 copyAideMetadata(metadata, md);
765 DEBUG_FSM("checkFileByAide - MISS\n");
777 int checkIgnoreList(AIDE_CONTEXT *ctx, char *name) {
783 ERROR("checkIgnoreList() - name is null\n");
787 list = ctx->ignore_name_start;
788 while (list != NULL) {
789 // TODO(munetoh) not check the all string
790 if (list->name != NULL) {
791 len = strlen(list->name);
792 if (!strncmp(name, list->name, len)) {
794 DEBUG("HIT %s\n", name);
798 ERROR("checkIgnoreList() - list->name is null\n");
810 * check Eventlog with AIDE DB
813 * event->rgbEvent[0] - [20] <= SHA1 digest of the File
821 * skip this check 33sec -> 2sec
824 int checkEventByAide(AIDE_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
825 TSS_PCR_EVENT *event;
838 #endif // AIDE_CHBY_LIST
839 #endif // CONFIG_SQLITE
841 // DEBUG("checkEventByAide - start\n");
844 ERROR("checkEventByAide - AIDE_CONTEXT is NULL\n");
848 if (eventWrapper == NULL) {
849 ERROR("OcheckEventByAide - PENPTS_PCR_EVENT_WRAPPER is NULL\n");
853 event = eventWrapper->event;
855 // 20100627 ignore pseudo event
856 if (event->eventType == OPENPTS_PSEUDO_EVENT_TYPE) {
857 ERROR("validateImaMeasurement - event->eventType == OPENPTS_PSEUDO_EVENT_TYPE\n");
861 if (event->rgbEvent == NULL) {
866 if (event->ulPcrValueLength != SHA1_DIGEST_SIZE) {
867 DEBUG("bad digest size\n");
871 /* OK, let's find the HIT */
879 ERROR("encodeBase64 fail");
882 rc = verifyBySQLite(ctx, (char*)buf);
885 if (rc == OPENPTS_RESULT_VALID) {
887 // md = (AIDE_METADATA *) ep->data;
888 // DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
889 // md->status = OPENPTS_AIDE_MD_STATUS_HIT;
890 // md->event_wrapper = eventWrapper; // n:1
891 // eventWrapper->aide_metadata = md; // 1:n
892 // this output many lines:-P
893 // DEBUG("HIT [%s] \n",b64);
896 #else // CONFIG_SQLITE
900 for (i = 0; i < ctx->metadata_num; i++) {
902 DEBUG("AIDE MeataData is NULL\n");
906 if (md->sha1 != NULL) {
907 if (memcmp(event->rgbEvent, md->sha1, SHA1_DIGEST_SIZE) == 0) {
909 DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
910 md->status = OPENPTS_AIDE_MD_STATUS_HIT;
911 md->event_wrapper = eventWrapper; // n:1
912 eventWrapper->aide_metadata = md; // 1:n
913 // copyAideMetadata(metadata, md);
919 DEBUG_FSM("checkFileByAide - MISS\n");
927 ERROR("encodeBase64 fail");
930 e.key = (char *) buf; // size?
931 e.data = NULL; // just initialized for static analysys
937 // after (hash) BINARY
941 // after (hash) BASE64 :-(
949 rc = hsearch_r(e, FIND, &ep, ctx->aide_md_table);
952 // DEBUG("MD HIT\n");
953 md = (AIDE_METADATA *) ep->data;
954 DEBUG_FSM("checkFileByAide - HIT name=[%s]\n", md->name);
955 md->status = OPENPTS_AIDE_MD_STATUS_HIT;
956 md->event_wrapper = eventWrapper; // n:1
957 eventWrapper->aide_metadata = md; // 1:n
958 // DEBUG("HIT [%s] %s\n",b64, md->name);
961 // DEBUG("MISS [%s] MISS\n",b64);
965 #endif // CONFIG_SQLITE
967 /* check ignore list */
970 name = (char *)event->rgbEvent;
971 name += SHA1_DIGEST_SIZE;
973 name = snmalloc(name, (event->ulEventLength - SHA1_DIGEST_SIZE));
976 rc = checkIgnoreList(ctx, name);
993 * Get AIDE metadata by name
995 * "name" must be unique but
996 * if multiple entries has sama name this returns first one. :-P
998 AIDE_METADATA *getMetadataFromAideByName(AIDE_CONTEXT *ctx, char *name) {
1012 for (i = 0; i < ctx->metadata_num; i++) {
1016 if (md->name != NULL) {
1017 if (!strcmp(md->name, name)) {
1019 DEBUG("checkFileByAide HIT %s\n", name);
1029 * Convert the following char to %XX
1031 * Caller have to free out buffer;
1047 int escapeFilename(char **out, char *in) {
1054 /* rough malloc new buffer */
1055 buf = malloc(len*3);
1057 ERROR("no memory\n");
1063 for (i = 0; i < len; i++) {
1064 if (in[i] == 0x20) {
1069 } else if (in[i] == 0x25) {
1074 } else if (in[i] == 0x3A) {
1079 } else if (in[i] == 0x40) {
1084 } else if (in[i] == 0x5B) {
1089 } else if (in[i] == 0x5D) {
1094 } else if (in[i] == 0x7B) {
1099 } else if (in[i] == 0x7D) {
1104 } else if (in[i] == 0x7E) {
1122 * Convert IML TSS/file(ptscd.conf) to AIDE DB
1124 * ctx get the IML before call this func
1125 * filename output AIDE DB filename
1127 * TODO(munetoh) IMA_31 only
1129 int convertImlToAideDbFile(OPENPTS_CONTEXT *ctx, char *filename) {
1132 OPENPTS_SNAPSHOT *ss;
1133 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
1134 TSS_PCR_EVENT *event;
1137 char *aide_filename = NULL;
1140 DEBUG("convertImlToAideDbFile %s\n", filename);
1142 /* file open for write */
1143 fp = gzopen(filename, "wb");
1145 ERROR("%s fail to open\n", filename);
1150 gzprintf(fp, "@@begin_db\n");
1151 gzprintf(fp, "# This file was generated by OpenPTS\n");
1152 gzprintf(fp, "@@db_spec name sha1 \n");
1155 ss = getSnapshotFromTable(ctx->ss_table, 10, 1); // TODO def or conf
1157 ERROR("events is missing\n");
1160 eventWrapper = ss->start;
1161 if (eventWrapper == NULL) {
1162 ERROR("events is missing\n");
1166 event = eventWrapper->event;
1168 // DEBUG("PCR[%d]\n", ss->pcrIndex);
1169 // DEBUG("event_num %d\n", ss->event_num);
1171 // for (i = 0; i < ctx->eventNum; i++) {
1172 for (i = 0; i < ctx->ss_table->event_num; i++) { // TODO ss->event_num?
1173 // DEBUG("SM DEBUG event %p\n",event);
1175 if (event == NULL) {
1176 ERROR("event is NULL\n");
1180 if (event->rgbEvent == NULL) {
1181 ERROR("event->rgbEvent is NULL\n");
1185 // TODO 2010-10-05 SM
1186 // AIDE convert the following chars in filename
1187 // SPACE 0x20 -> "%20"
1197 // gzprintf(fp, "%s ",&eventWrapper->event->rgbEvent[20]);
1199 /* filename (allocated) */
1200 len = escapeFilename(&aide_filename, (char *) &eventWrapper->event->rgbEvent[20]);
1202 ERROR("convertImlToAideDbFile - no mem?\n");
1203 gzprintf(fp, "bad_filename ");
1205 gzprintf(fp, "%s ", aide_filename);
1206 free(aide_filename);
1207 aide_filename = NULL;
1212 (unsigned char *)event->rgbEvent,
1216 ERROR("encodeBase64 fail");
1219 gzprintf(fp, "%s \n", buf);
1222 // printf("%d %s\n", i, buf);
1224 eventWrapper = eventWrapper->next_pcr;
1225 if (eventWrapper == NULL) break;
1226 event = eventWrapper->event;
1230 gzprintf(fp, "@@end_db\n");
1233 gzseek(fp, 1L, SEEK_CUR); // add one \n
1236 if (aide_filename != NULL) free(aide_filename);
1238 DEBUG("convertImlToAideDbFile - done\n");
1240 return i+1; // event num
1244 * reduce the size of AIDE DB
1247 * AIDE-DB IMA-IML AIDE-DB
1248 * --------------------------
1253 * --------------------------
1256 * return AIDE entry count
1259 int writeReducedAidbDatabase(AIDE_CONTEXT *ctx, char *filename) {
1267 DEBUG("writeReducedAidbDatabase %s\n", filename);
1273 /* file open for write */
1274 fp = gzopen(filename, "wb");
1276 ERROR("%s fail to open\n", filename);
1281 gzprintf(fp, "@@begin_db\n");
1282 gzprintf(fp, "# This file was generated by OpenPTS\n");
1283 gzprintf(fp, "@@db_spec name sha1 \n");
1288 for (i = 0; i < ctx->metadata_num; i++) {
1293 if (md->status == OPENPTS_AIDE_MD_STATUS_HIT) {
1296 (unsigned char *)md->sha1,
1300 ERROR("encodeBase64 fail");
1303 gzprintf(fp, "%s ", md->name);
1304 gzprintf(fp, "%s \n", buf);
1313 gzprintf(fp, "@@end_db\n");
1316 gzseek(fp, 1L, SEEK_CUR); // add one \n
1319 DEBUG("convertImlToAideDbFile - done\n");
1325 #ifdef CONFIG_SQLITE
1327 * Convert AIDE BD file to SQLite DB file
1330 * 0 PTS_SUCCESS success
1331 * PTS_INTERNAL_ERROR ERROR
1333 int convertAideDbfileToSQLiteDbFile(char * aide_filename, char * sqlite_filename) {
1334 int rc = PTS_SUCCESS;
1344 if (aide_filename == NULL) {
1345 ERROR("AIDE file is null\n");
1346 return PTS_INTERNAL_ERROR;
1348 if (sqlite_filename == NULL) {
1349 ERROR("sqlite file is null\n");
1350 return PTS_INTERNAL_ERROR;
1354 /* new AIDE context */
1355 ctx = newAideContext();
1357 /* read AIDE DB file -> ctx */
1358 rc = loadAideDatabaseFile(ctx, aide_filename);
1360 ERROR("read AIDE DB %s fail, rc = %d", aide_filename, rc);
1367 /* rm existing DB file */
1368 remove(sqlite_filename);
1371 sqlite3_open(sqlite_filename, &db);
1373 ERROR("open AIDE DB fail\n");
1374 rc = PTS_INTERNAL_ERROR;
1379 "CREATE TABLE sample (id INTEGER PRIMARY KEY, digest TEXT NOT NULL, "
1380 "name TEXT NOT NULL, state INTEGER NOT NULL)",
1382 // DEBUG("CREATE err=%s\n", err);
1385 sqlite3_exec(db, "BEGIN", NULL, NULL, &err);
1386 // DEBUG("BEGIN err=%s\n", err);
1391 for (i = 0; i < ctx->metadata_num; i++) {
1392 if (md->hash_key != NULL) {
1393 sql = sqlite3_mprintf(
1394 "INSERT INTO sample (id, digest, name, state) VALUES (%d, '%s','%s', %d)",
1395 j, md->hash_key, md->name, 0);
1396 sqlite3_exec(db, sql, NULL, NULL, &err);
1397 // DEBUG("INSERT err=%s\n", err);
1404 sqlite3_exec(db, "COMMIT", NULL, NULL, &err);
1405 // DEBUG("COMMIT err=%s\n", err);
1408 sqlite3_exec(db, "CREATE INDEX digestindex ON sample(digest)", NULL, NULL, &err);
1409 // DEBUG("CREATE INDEX err=%s\n", err);
1418 freeAideContext(ctx);
1424 * load (open) SQLite DB file
1426 int loadSQLiteDatabaseFile(AIDE_CONTEXT *ctx, char *filename) {
1429 ERROR("ctx == NULL\n");
1430 return PTS_INTERNAL_ERROR;
1432 if (filename == NULL) {
1433 ERROR("filename == NULL\n");
1434 return PTS_INTERNAL_ERROR;
1438 sqlite3_open(filename, &ctx->sqlite_db);
1439 if (ctx->sqlite_db == NULL) {
1440 ERROR("open AIDE SQLite DB %s fail\n", filename);
1441 return PTS_INTERNAL_ERROR;
1450 int verifyBySQLite(AIDE_CONTEXT *ctx, char * key) {
1458 ERROR("ctx == NULL\n");
1459 return PTS_INTERNAL_ERROR;
1461 if (ctx->sqlite_db == NULL) {
1462 ERROR("ctx->sqlite_db == NULL\n");
1463 return PTS_INTERNAL_ERROR;
1466 sql = sqlite3_mprintf("SELECT * from sample where digest = '%s'", key);
1467 sqlite3_get_table(ctx->sqlite_db, sql, &result, &row, &col, &err);
1468 // DEBUG("%2d %d %s\n",row,col, md->hash_key);
1471 return OPENPTS_RESULT_VALID;
1474 // ERROR("row = %d\n",row);
1479 sqlite3_free_table(result);
1483 return OPENPTS_RESULT_UNKNOWN;
1485 #endif // CONFIG_SQLITE