diff options
author | netblue30 <netblue30@yahoo.com> | 2017-09-16 08:49:05 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2017-09-16 08:49:05 -0400 |
commit | 280f37eba89ebc211d0c02848d3d47d086458b25 (patch) | |
tree | 1398c5dfc53c4d286d7b6b528d5a3c1585a67325 /src/fbuilder/build_home.c | |
parent | Merge pull request #1552 from SpotComms/mf (diff) | |
download | firejail-280f37eba89ebc211d0c02848d3d47d086458b25.tar.gz firejail-280f37eba89ebc211d0c02848d3d47d086458b25.tar.zst firejail-280f37eba89ebc211d0c02848d3d47d086458b25.zip |
--build
Diffstat (limited to 'src/fbuilder/build_home.c')
-rw-r--r-- | src/fbuilder/build_home.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/src/fbuilder/build_home.c b/src/fbuilder/build_home.c new file mode 100644 index 000000000..947f172d8 --- /dev/null +++ b/src/fbuilder/build_home.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2017 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 | |||
21 | #include "fbuilder.h" | ||
22 | |||
23 | static FileDB *db_skip = NULL; | ||
24 | static FileDB *db_out = NULL; | ||
25 | |||
26 | static void load_whitelist_common(void) { | ||
27 | FILE *fp = fopen("/etc/firejail/whitelist-common.inc", "r"); | ||
28 | if (!fp) { | ||
29 | fprintf(stderr, "Error: cannot open whitelist-common.inc\n"); | ||
30 | exit(1); | ||
31 | } | ||
32 | |||
33 | char buf[MAX_BUF]; | ||
34 | while (fgets(buf, MAX_BUF, fp)) { | ||
35 | if (strncmp(buf, "whitelist ~/", 12) != 0) | ||
36 | continue; | ||
37 | char *fn = buf + 12; | ||
38 | char *ptr = strchr(buf, '\n'); | ||
39 | if (!ptr) | ||
40 | continue; | ||
41 | *ptr = '\0'; | ||
42 | |||
43 | // add the file to skip list | ||
44 | db_skip = filedb_add(db_skip, fn); | ||
45 | } | ||
46 | |||
47 | fclose(fp); | ||
48 | } | ||
49 | |||
50 | void process_home(const char *fname, char *home, int home_len) { | ||
51 | assert(fname); | ||
52 | assert(home); | ||
53 | assert(home_len); | ||
54 | |||
55 | // process trace file | ||
56 | FILE *fp = fopen(fname, "r"); | ||
57 | if (!fp) { | ||
58 | fprintf(stderr, "Error: cannot open %s\n", fname); | ||
59 | exit(1); | ||
60 | } | ||
61 | |||
62 | char buf[MAX_BUF]; | ||
63 | while (fgets(buf, MAX_BUF, fp)) { | ||
64 | // remove \n | ||
65 | char *ptr = strchr(buf, '\n'); | ||
66 | if (ptr) | ||
67 | *ptr = '\0'; | ||
68 | |||
69 | // parse line: 4:galculator:access /etc/fonts/conf.d:0 | ||
70 | // number followed by : | ||
71 | ptr = buf; | ||
72 | if (!isdigit(*ptr)) | ||
73 | continue; | ||
74 | while (isdigit(*ptr)) | ||
75 | ptr++; | ||
76 | if (*ptr != ':') | ||
77 | continue; | ||
78 | ptr++; | ||
79 | |||
80 | // next : | ||
81 | ptr = strchr(ptr, ':'); | ||
82 | if (!ptr) | ||
83 | continue; | ||
84 | ptr++; | ||
85 | if (strncmp(ptr, "access /home", 12) == 0) | ||
86 | ptr += 7; | ||
87 | else if (strncmp(ptr, "fopen /home", 11) == 0) | ||
88 | ptr += 6; | ||
89 | else if (strncmp(ptr, "fopen64 /home", 13) == 0) | ||
90 | ptr += 8; | ||
91 | else if (strncmp(ptr, "open64 /home", 12) == 0) | ||
92 | ptr += 7; | ||
93 | else if (strncmp(ptr, "open /home", 10) == 0) | ||
94 | ptr += 5; | ||
95 | else | ||
96 | continue; | ||
97 | |||
98 | // end of filename | ||
99 | char *ptr2 = strchr(ptr, ':'); | ||
100 | if (!ptr2) | ||
101 | continue; | ||
102 | *ptr2 = '\0'; | ||
103 | |||
104 | // check home directory | ||
105 | if (strncmp(ptr, home, home_len) != 0) | ||
106 | continue; | ||
107 | if (strcmp(ptr, home) == 0) | ||
108 | continue; | ||
109 | ptr += home_len + 1; | ||
110 | |||
111 | // skip files handled automatically by firejail | ||
112 | if (strcmp(ptr, ".Xauthority") == 0 || | ||
113 | strcmp(ptr, ".Xdefaults-debian") == 0 || | ||
114 | strncmp(ptr, ".config/pulse/", 13) == 0 || | ||
115 | strncmp(ptr, ".pulse/", 7) == 0 || | ||
116 | strncmp(ptr, ".bash_hist", 10) == 0 || | ||
117 | strcmp(ptr, ".bashrc") == 0) | ||
118 | continue; | ||
119 | |||
120 | |||
121 | // try to find the relevant directory for this file | ||
122 | char *dir = extract_dir(ptr); | ||
123 | char *toadd = (dir)? dir: ptr; | ||
124 | |||
125 | // skip some dot directories | ||
126 | if (strcmp(toadd, ".config") == 0 || | ||
127 | strcmp(toadd, ".local") == 0 || | ||
128 | strcmp(toadd, ".local/share") == 0 || | ||
129 | strcmp(toadd, ".cache") == 0) { | ||
130 | if (dir) | ||
131 | free(dir); | ||
132 | continue; | ||
133 | } | ||
134 | |||
135 | // clean .cache entries | ||
136 | if (strncmp(toadd, ".cache/", 7) == 0) { | ||
137 | char *ptr2 = toadd + 7; | ||
138 | ptr2 = strchr(ptr2, '/'); | ||
139 | if (ptr2) | ||
140 | *ptr2 = '\0'; | ||
141 | } | ||
142 | |||
143 | // skip files and directories in whitelist-common.inc | ||
144 | if (filedb_find(db_skip, toadd)) { | ||
145 | if (dir) | ||
146 | free(dir); | ||
147 | continue; | ||
148 | } | ||
149 | |||
150 | // add the file to out list | ||
151 | db_out = filedb_add(db_out, toadd); | ||
152 | if (dir) | ||
153 | free(dir); | ||
154 | |||
155 | } | ||
156 | fclose(fp); | ||
157 | } | ||
158 | |||
159 | |||
160 | // process fname, fname.1, fname.2, fname.3, fname.4, fname.5 | ||
161 | void build_home(const char *fname) { | ||
162 | assert(fname); | ||
163 | |||
164 | // load whitelist common | ||
165 | load_whitelist_common(); | ||
166 | |||
167 | // find user home directory | ||
168 | struct passwd *pw = getpwuid(getuid()); | ||
169 | if (!pw) | ||
170 | errExit("getpwuid"); | ||
171 | char *home = pw->pw_dir; | ||
172 | if (!home) | ||
173 | errExit("getpwuid"); | ||
174 | int home_len = strlen(home); | ||
175 | |||
176 | // run fname | ||
177 | process_home(fname, home, home_len); | ||
178 | |||
179 | // run all the rest | ||
180 | struct stat s; | ||
181 | int i; | ||
182 | for (i = 1; i <= 5; i++) { | ||
183 | char *newname; | ||
184 | if (asprintf(&newname, "%s.%d", fname, i) == -1) | ||
185 | errExit("asprintf"); | ||
186 | if (stat(newname, &s) == 0) | ||
187 | process_home(newname, home, home_len); | ||
188 | free(newname); | ||
189 | } | ||
190 | |||
191 | // print the out list if any | ||
192 | if (db_out) { | ||
193 | filedb_print(db_out, "whitelist ~/"); | ||
194 | printf("include /etc/firejail/whitelist-common.inc\n"); | ||
195 | } | ||
196 | else | ||
197 | printf("private\n"); | ||
198 | |||
199 | } \ No newline at end of file | ||