aboutsummaryrefslogtreecommitdiffstats
path: root/src/fids/db.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fids/db.c')
-rw-r--r--src/fids/db.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/fids/db.c b/src/fids/db.c
new file mode 100644
index 000000000..e0021bc48
--- /dev/null
+++ b/src/fids/db.c
@@ -0,0 +1,159 @@
1/*
2 * Copyright (C) 2014-2021 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include"fids.h"
21
22typedef struct db_t {
23 struct db_t *next;
24 char *fname;
25 char *checksum;
26 char *mode;
27 int checked;
28} DB;
29
30#define MAXBUF 4096
31static DB *database[HASH_MAX] = {NULL};
32
33// djb2 hash function by Dan Bernstein
34static unsigned hash(const char *str) {
35 const unsigned char *s = (unsigned char *) str;
36 unsigned long hash = 5381;
37 int c;
38
39 while (c = *s++)
40 hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
41
42 return hash & (HASH_MAX - 1);
43}
44
45#if 0
46// for testing the hash table
47static void db_print(void) {
48 int i;
49 for (i = 0; i < HASH_MAX; i++) {
50 int cnt = 0;
51 DB *ptr = database[i];
52 while (ptr) {
53 cnt++;
54 ptr = ptr->next;
55 }
56 printf("%d ", cnt);
57 fflush(0);
58 }
59 printf("\n");
60}
61#endif
62
63static void db_add(const char *fname, const char *checksum, const char *mode) {
64 DB *ptr = malloc(sizeof(DB));
65 if (!ptr)
66 errExit("malloc");
67 ptr->fname = strdup(fname);
68 ptr->checksum = strdup(checksum);
69 ptr->mode = strdup(mode);
70 ptr->checked = 0;
71 if (!ptr->fname || !ptr->checksum || !ptr->mode)
72 errExit("strdup");
73
74 unsigned h = hash(fname);
75 ptr->next = database[h];
76 database[h] = ptr;
77}
78
79void db_check(const char *fname, const char *checksum, const char *mode) {
80 assert(fname);
81 assert(checksum);
82 assert(mode);
83
84 unsigned h =hash(fname);
85 DB *ptr = database[h];
86 while (ptr) {
87 if (strcmp(fname, ptr->fname) == 0) {
88 ptr->checked = 1;
89 break;
90 }
91 ptr = ptr->next;
92 }
93
94 if (ptr ) {
95 if (strcmp(checksum, ptr->checksum)) {
96 f_modified++;
97 fprintf(stderr, "\nWarning: modified %s\n", fname);
98 }
99 if (strcmp(mode, ptr->mode)) {
100 f_permissions++;
101 fprintf(stderr, "\nWarning: permissions %s: old %s, new %s\n",
102 fname, ptr->mode, mode);
103 }
104 }
105 else {
106 f_new++;
107 fprintf(stderr, "\nWarning: new file %s\n", fname);
108 }
109}
110
111void db_missing(void) {
112 int i;
113 for (i = 0; i < HASH_MAX; i++) {
114 DB *ptr = database[i];
115 while (ptr) {
116 if (!ptr->checked) {
117 f_removed++;
118 fprintf(stderr, "Warning: removed %s\n", ptr->fname);
119 }
120 ptr = ptr->next;
121 }
122 }
123}
124
125// return 0 if ok, 1 if error
126int db_init(void) {
127 char buf[MAXBUF];
128 while(fgets(buf, MAXBUF, stdin)) {
129 // split - tab separated
130
131 char *mode = buf;
132 char *ptr = strchr(buf, '\t');
133 if (!ptr)
134 goto errexit;
135 *ptr = '\0';
136
137 char *checksum = ptr + 1;
138 ptr = strchr(checksum, '\t');
139 if (!ptr)
140 goto errexit;
141 *ptr = '\0';
142
143 char *fname = ptr + 1;
144 ptr = strchr(fname, '\n');
145 if (!ptr)
146 goto errexit;
147 *ptr = '\0';
148
149 db_add(fname, checksum, mode);
150 }
151// db_print();
152
153 return 0;
154
155errexit:
156 fprintf(stderr, "Error fids: database corrupted\n");
157 exit(1);
158}
159