aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/etc_groups.h42
-rw-r--r--src/tools/cleanup_etc.c261
2 files changed, 284 insertions, 19 deletions
diff --git a/src/include/etc_groups.h b/src/include/etc_groups.h
index fcb824778..61ac8ac69 100644
--- a/src/include/etc_groups.h
+++ b/src/include/etc_groups.h
@@ -27,6 +27,7 @@
27static char *etc_list[ETC_MAX + 1] = { // plus 1 for ending NULL pointer 27static char *etc_list[ETC_MAX + 1] = { // plus 1 for ending NULL pointer
28 "alternatives", 28 "alternatives",
29 "fonts", 29 "fonts",
30 "group",
30 "ld.so.cache", 31 "ld.so.cache",
31 "ld.so.conf", 32 "ld.so.conf",
32 "ld.so.conf.d", 33 "ld.so.conf.d",
@@ -38,16 +39,16 @@ static char *etc_list[ETC_MAX + 1] = { // plus 1 for ending NULL pointer
38 "login.defs", // firejail reading UID/GID MIN and MAX at startup 39 "login.defs", // firejail reading UID/GID MIN and MAX at startup
39 "nsswitch.conf", 40 "nsswitch.conf",
40 "passwd", 41 "passwd",
41 "group", 42 "selinux",
42 NULL 43 NULL
43}; 44};
44 45
45// @sound 46// @games
46static char *etc_group_sound[] = { 47static char *etc_group_games[] = {
47 "alsa", 48 "openal", // 3D sound
48 "asound.conf", 49 "timidity", // MIDI
49 "machine-id", // required by PulseAudio 50 "timidity.cfg",
50 "pulse", 51 "vulkan", // next generation OpenGL stack
51 NULL 52 NULL
52}; 53};
53 54
@@ -55,8 +56,17 @@ static char *etc_group_sound[] = {
55static char*etc_group_network[] = { 56static char*etc_group_network[] = {
56 "hostname", 57 "hostname",
57 "hosts", 58 "hosts",
58 "resolv.conf",
59 "protocols", 59 "protocols",
60 "resolv.conf",
61 NULL
62};
63
64// @sound
65static char *etc_group_sound[] = {
66 "alsa",
67 "asound.conf",
68 "machine-id", // required by PulseAudio
69 "pulse",
60 NULL 70 NULL
61}; 71};
62 72
@@ -72,24 +82,18 @@ static char *etc_group_tls_ca[] = {
72 82
73// @x11 83// @x11
74static char *etc_group_x11[] = { 84static char *etc_group_x11[] = {
75 "xdg", 85 "ati", // 3D
76 "drirc",
77 "dconf", 86 "dconf",
87 "drirc",
78 "gtk-2.0", 88 "gtk-2.0",
79 "gtk-3.0", 89 "gtk-3.0",
80 "kde4rc", 90 "kde4rc",
81 "kde5rc", 91 "kde5rc",
92 "nvidia", // 3D
82 "pango", // text rendering/internationalization 93 "pango", // text rendering/internationalization
83 "nvidia", 94 "Trolltech.conf", // old QT config file
84 "X11", 95 "X11",
85 NULL 96 "xdg",
86};
87
88// @games
89static char *etc_group_games[] = {
90 "timidity", // MIDI
91 "timidity.cfg",
92 "openal", // 3D sound
93 NULL 97 NULL
94}; 98};
95 99
diff --git a/src/tools/cleanup_etc.c b/src/tools/cleanup_etc.c
new file mode 100644
index 000000000..f57a1ddb1
--- /dev/null
+++ b/src/tools/cleanup_etc.c
@@ -0,0 +1,261 @@
1/*
2 * Copyright (C) 2014-2022 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 <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdarg.h>
25#include <assert.h>
26#include "../include/etc_groups.h"
27#define errExit(msg) do { char msgout[500]; sprintf(msgout, "Error %s:%s(%d)", msg, __FUNCTION__, __LINE__); perror(msgout); exit(1);} while (0)
28
29
30
31#define MAX_BUF 4098
32#define MAX_ARR 1024
33char *arr[MAX_ARR] = {NULL};
34int arr_cnt = 0;
35
36static int arr_tls_ca = 0;
37static int arr_x11 = 0;
38static int arr_games = 0;
39static char outbuf[256 * 1024];
40static char *outptr;
41static int arg_replace = 0;
42static int arg_debug = 0;
43
44void outprintf(char* fmt, ...) {
45 va_list args;
46 va_start(args,fmt);
47 outptr += vsprintf(outptr, fmt, args);
48 va_end(args);
49}
50
51
52
53static int arr_check(const char *fname, char **pptr) {
54 assert(fname);
55 assert(pptr);
56
57 while (*pptr != NULL) {
58 if (strcmp(fname, *pptr) == 0)
59 return 1;
60 pptr++;
61 }
62
63 return 0;
64}
65
66
67
68static void arr_add(const char *fname) {
69 assert(fname);
70 assert(arr_cnt < MAX_ARR);
71
72 int i;
73 for (i = 0; i < arr_cnt; i++)
74 if (strcmp(arr[i], fname) == 0)
75 return;
76
77 arr[arr_cnt] = strdup(fname);
78 if (!arr[arr_cnt])
79 errExit("strdup");
80 arr_cnt++;
81}
82
83int arr_cmp(const void *p1, const void *p2) {
84 char **ptr1 = (char **) p1;
85 char **ptr2 = (char **) p2;
86
87 return strcmp(*ptr1, *ptr2);
88}
89
90static void arr_sort(void) {
91 qsort(&arr[0], arr_cnt, sizeof(char *), arr_cmp);
92}
93
94static void arr_clean(void) {
95 int i;
96 for (i = 0; i < arr_cnt; i++) {
97 free(arr[i]);
98 arr[i] = NULL;
99 }
100
101 arr_cnt = 0;
102 arr_games = 0;
103 arr_tls_ca = 0;
104 arr_x11 = 0;
105}
106
107static char *arr_print(void) {
108 char *last_line = outptr;
109 outprintf("private-etc ");
110
111 if (arr_games)
112 outprintf("@games,");
113 if (arr_tls_ca)
114 outprintf("@tls-ca,");
115 if (arr_x11)
116 outprintf("@x11,");
117
118 int i;
119 for (i = 0; i < arr_cnt; i++)
120 outprintf("%s,", arr[i]);
121 if (*(outptr - 1) == ' ' || *(outptr - 1) == ',') {
122 outptr--;
123 *outptr = '\0';
124 }
125 outprintf("\n");
126
127 return last_line;
128}
129
130static void process_file(const char *fname) {
131 assert(fname);
132
133 FILE *fp = fopen(fname, "r");
134 if (!fp) {
135 fprintf(stderr, "Error: cannot open %s file\n", fname);
136 exit(1);
137 }
138
139 outptr = outbuf;
140 *outptr = '\0';
141 arr_clean();
142
143 char line[MAX_BUF];
144 char orig_line[MAX_BUF];
145 int cnt = 0;
146 int print = 0;
147 while (fgets(line, MAX_BUF, fp)) {
148 cnt++;
149 if (strncmp(line, "private-etc", 11) != 0) {
150 outprintf("%s", line);
151 continue;
152 }
153
154 strcpy(orig_line,line);
155 char *ptr = strchr(line, '\n');
156 if (ptr)
157 *ptr = '\0';
158
159 ptr = line + 12;
160 while (*ptr == ' ' || *ptr == '\t')
161 ptr++;
162
163 // check for blanks and tabs
164 char *ptr2 = ptr;
165 while (*ptr2 != '\0') {
166 if (*ptr2 == ' ' || *ptr2 == '\t') {
167 fprintf(stderr, "Error: invalid private-etc line %s:%d\n", fname, cnt);
168 exit(1);
169 }
170 ptr2++;
171 }
172
173 ptr = strtok(ptr, ",");
174 while (ptr) {
175 if (arg_debug)
176 printf("%s\n", ptr);
177 if (arr_check(ptr, &etc_list[0]));
178 else if (arr_check(ptr, &etc_group_sound[0]));
179 else if (arr_check(ptr, &etc_group_network[0]));
180 else if (strcmp(ptr, "@games") == 0)
181 arr_games = 1;
182 else if (strcmp(ptr, "@tls-ca") == 0)
183 arr_tls_ca = 1;
184 else if (strcmp(ptr, "@x11") == 0)
185 arr_x11 = 1;
186 else if (arr_check(ptr, &etc_group_games[0]))
187 arr_games = 1;
188 else if (arr_check(ptr, &etc_group_tls_ca[0]))
189 arr_tls_ca = 1;
190 else if (arr_check(ptr, &etc_group_x11[0]))
191 arr_x11 = 1;
192 else
193 arr_add(ptr);
194
195 ptr = strtok(NULL, ",");
196 }
197
198 arr_sort();
199 char *last_line = arr_print();
200 if (strcmp(last_line, orig_line) == 0) {
201 fclose(fp);
202 return;
203 }
204 printf("\n********************\nfile: %s\n\nold: %s\nnew: %s\n", fname, orig_line, last_line);
205 print = 1;
206 }
207
208 fclose(fp);
209
210 if (print && arg_replace) {
211 fp = fopen(fname, "w");
212 if (!fp) {
213 fprintf(stderr, "Error: cannot open profile file\n");
214 exit(1);
215 }
216 fprintf(fp, "%s", outbuf);
217 fclose(fp);
218 }
219}
220
221static void usage(void) {
222 printf("usage: cleanup-etc [options] file.profile [file.profile]\n");
223 printf("Group and clean private-etc entries in one or more profile files.\n");
224 printf("Options:\n");
225 printf(" --debug - print debug messages\n");
226 printf(" --help - this help screen\n");
227 printf(" --replace - replace profile file\n");
228}
229
230int main(int argc, char **argv) {
231 if (argc < 2) {
232 fprintf(stderr, "Error: invalid number of parameters\n");
233 usage();
234 return 1;
235 }
236
237 int i;
238 for (i = 1; i < argc; i++) {
239 if (strcmp(argv[i], "-h") == 0 ||
240 strcmp(argv[i], "-?") == 0 ||
241 strcmp(argv[i], "--help") == 0) {
242 usage();
243 return 0;
244 }
245 else if (strcmp(argv[i], "--debug") == 0)
246 arg_debug = 1;
247 else if (strcmp(argv[i], "--replace") == 0)
248 arg_replace = 1;
249 else if (*argv[i] == '-') {
250 fprintf(stderr, "Error: invalid program option %s\n", argv[i]);
251 return 1;
252 }
253 else
254 break;
255 }
256
257 for (; i < argc; i++)
258 process_file(argv[i]);
259
260 return 0;
261} \ No newline at end of file