diff options
author | netblue30 <netblue30@yahoo.com> | 2017-11-18 08:39:02 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2017-11-18 08:39:02 -0500 |
commit | ead4ec3089b97eda1b438da248caf76f169345ad (patch) | |
tree | 31bc22bcba4e6530b5f0daba3f332702efa7a4b9 /src/fnetfilter/main.c | |
parent | Consistent home directory nomenclature (diff) | |
download | firejail-ead4ec3089b97eda1b438da248caf76f169345ad.tar.gz firejail-ead4ec3089b97eda1b438da248caf76f169345ad.tar.zst firejail-ead4ec3089b97eda1b438da248caf76f169345ad.zip |
netfilter template support
Diffstat (limited to 'src/fnetfilter/main.c')
-rw-r--r-- | src/fnetfilter/main.c | 144 |
1 files changed, 121 insertions, 23 deletions
diff --git a/src/fnetfilter/main.c b/src/fnetfilter/main.c index 67ab31832..723c1ac32 100644 --- a/src/fnetfilter/main.c +++ b/src/fnetfilter/main.c | |||
@@ -20,8 +20,12 @@ | |||
20 | #include "../include/common.h" | 20 | #include "../include/common.h" |
21 | 21 | ||
22 | #define MAXBUF 4098 | 22 | #define MAXBUF 4098 |
23 | #define MAXARGS 16 | ||
24 | static char *args[MAXARGS] = {0}; | ||
25 | static int argcnt = 0; | ||
23 | int arg_quiet = 0; | 26 | int arg_quiet = 0; |
24 | 27 | ||
28 | |||
25 | static char *default_filter = | 29 | static char *default_filter = |
26 | "*filter\n" | 30 | "*filter\n" |
27 | ":INPUT DROP [0:0]\n" | 31 | ":INPUT DROP [0:0]\n" |
@@ -29,7 +33,7 @@ static char *default_filter = | |||
29 | ":OUTPUT ACCEPT [0:0]\n" | 33 | ":OUTPUT ACCEPT [0:0]\n" |
30 | "-A INPUT -i lo -j ACCEPT\n" | 34 | "-A INPUT -i lo -j ACCEPT\n" |
31 | "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n" | 35 | "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n" |
32 | "# echo replay is handled by -m state RELATED/ESTABLISHED below\n" | 36 | "# echo replay is handled by -m state RELATED/ESTABLISHED above\n" |
33 | "#-A INPUT -p icmp --icmp-type echo-reply -j ACCEPT\n" | 37 | "#-A INPUT -p icmp --icmp-type echo-reply -j ACCEPT\n" |
34 | "-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT\n" | 38 | "-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT\n" |
35 | "-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT\n" | 39 | "-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT\n" |
@@ -46,6 +50,111 @@ static void usage(void) { | |||
46 | printf("\tfnetfilter netfilter-command destination-file\n"); | 50 | printf("\tfnetfilter netfilter-command destination-file\n"); |
47 | } | 51 | } |
48 | 52 | ||
53 | |||
54 | static void copy(const char *src, const char *dest) { | ||
55 | FILE *fp1 = fopen(src, "r"); | ||
56 | if (!fp1) { | ||
57 | fprintf(stderr, "Error fnetfilter: cannot open %s\n", src); | ||
58 | exit(1); | ||
59 | } | ||
60 | |||
61 | FILE *fp2 = fopen(dest, "w"); | ||
62 | if (!fp2) { | ||
63 | fprintf(stderr, "Error fnetfilter: cannot open %s\n", dest); | ||
64 | exit(1); | ||
65 | } | ||
66 | |||
67 | char buf[MAXBUF]; | ||
68 | while (fgets(buf, MAXBUF, fp1)) | ||
69 | fprintf(fp2, "%s", buf); | ||
70 | |||
71 | fclose(fp1); | ||
72 | fclose(fp2); | ||
73 | } | ||
74 | |||
75 | static void process_template(char *src, const char *dest) { | ||
76 | char *arg_start = strchr(src, ','); | ||
77 | assert(arg_start); | ||
78 | *arg_start = '\0'; | ||
79 | arg_start++; | ||
80 | if (*arg_start == '\0') { | ||
81 | fprintf(stderr, "Error fnetfilter: you need to provide at least on argument\n"); | ||
82 | exit(1); | ||
83 | } | ||
84 | |||
85 | // extract the arguments from command line | ||
86 | char *token = strtok(arg_start, ","); | ||
87 | while (token) { | ||
88 | // look for abnormal things | ||
89 | int len = strlen(token); | ||
90 | if (strcspn(token, "\\&!?\"'<>%^(){};,*[]") != (size_t)len) { | ||
91 | fprintf(stderr, "Error fnetfilter: invalid argument in netfilter command\n"); | ||
92 | exit(1); | ||
93 | } | ||
94 | args[argcnt] = token; | ||
95 | argcnt++; | ||
96 | token = strtok(NULL, ","); | ||
97 | } | ||
98 | #if 0 | ||
99 | { | ||
100 | printf("argcnt %d\n", argcnt); | ||
101 | int i; | ||
102 | for (i = 0; i < argcnt; i++) | ||
103 | printf("%s\n", args[i]); | ||
104 | } | ||
105 | #endif | ||
106 | |||
107 | // open the files | ||
108 | FILE *fp1 = fopen(src, "r"); | ||
109 | if (!fp1) { | ||
110 | fprintf(stderr, "Error fnetfilter: cannot open %s\n", src); | ||
111 | exit(1); | ||
112 | } | ||
113 | |||
114 | FILE *fp2 = fopen(dest, "w"); | ||
115 | if (!fp2) { | ||
116 | fprintf(stderr, "Error fnetfilter: cannot open %s\n", dest); | ||
117 | exit(1); | ||
118 | } | ||
119 | |||
120 | int line = 0; | ||
121 | char buf[MAXBUF]; | ||
122 | while (fgets(buf, MAXBUF, fp1)) { | ||
123 | line++; | ||
124 | char *ptr = buf; | ||
125 | while (*ptr != '\0') { | ||
126 | if (*ptr != '$') | ||
127 | fputc(*ptr, fp2); | ||
128 | else { | ||
129 | // parsing | ||
130 | int index = 0; | ||
131 | int rv = sscanf(ptr, "$ARG%u", &index) ; | ||
132 | if (rv != 1) { | ||
133 | fprintf(stderr, "Error fnetfilter: invalid template argument on line %d\n", line); | ||
134 | exit(1); | ||
135 | } | ||
136 | |||
137 | // print argument | ||
138 | if (index < 1 || index > argcnt) { | ||
139 | fprintf(stderr, "Error fnetfilter: $ARG%d on line %d was not defined\n", index, line); | ||
140 | exit(1); | ||
141 | } | ||
142 | fprintf(fp2, "%s", args[index - 1]); | ||
143 | |||
144 | // march to the end of argument | ||
145 | ptr += 4; | ||
146 | while (isdigit(*ptr)) | ||
147 | ptr++; | ||
148 | ptr--; | ||
149 | } | ||
150 | ptr++; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | fclose(fp1); | ||
155 | fclose(fp2); | ||
156 | } | ||
157 | |||
49 | int main(int argc, char **argv) { | 158 | int main(int argc, char **argv) { |
50 | #if 0 | 159 | #if 0 |
51 | { | 160 | { |
@@ -61,7 +170,7 @@ printf("\n"); | |||
61 | if (quiet && strcmp(quiet, "yes") == 0) | 170 | if (quiet && strcmp(quiet, "yes") == 0) |
62 | arg_quiet = 1; | 171 | arg_quiet = 1; |
63 | 172 | ||
64 | if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) { | 173 | if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0)) { |
65 | usage(); | 174 | usage(); |
66 | return 0; | 175 | return 0; |
67 | } | 176 | } |
@@ -75,6 +184,12 @@ printf("\n"); | |||
75 | char *command = (argc == 3)? argv[1]: NULL; | 184 | char *command = (argc == 3)? argv[1]: NULL; |
76 | //printf("command %s\n", command); | 185 | //printf("command %s\n", command); |
77 | //printf("destfile %s\n", destfile); | 186 | //printf("destfile %s\n", destfile); |
187 | // destfile is a real filename | ||
188 | int len = strlen(destfile); | ||
189 | if (strcspn(destfile, "\\&!?\"'<>%^(){};,*[]") != (size_t)len) { | ||
190 | fprintf(stderr, "Error fnetfilter: invalid destination file in netfilter command\n"); | ||
191 | exit(1); | ||
192 | } | ||
78 | 193 | ||
79 | // handle default config (command = NULL, destfile) | 194 | // handle default config (command = NULL, destfile) |
80 | if (command == NULL) { | 195 | if (command == NULL) { |
@@ -88,28 +203,11 @@ printf("\n"); | |||
88 | fclose(fp); | 203 | fclose(fp); |
89 | } | 204 | } |
90 | else { | 205 | else { |
91 | // copy the file | 206 | if (strrchr(command, ',')) |
92 | FILE *fp1 = fopen(command, "r"); | 207 | process_template(command, destfile); |
93 | if (!fp1) { | 208 | else |
94 | fprintf(stderr, "Error fnetfilter: cannot open %s\n", command); | 209 | copy(command, destfile); |
95 | exit(1); | ||
96 | } | ||
97 | |||
98 | FILE *fp2 = fopen(destfile, "w"); | ||
99 | if (!fp2) { | ||
100 | fprintf(stderr, "Error fnetfilter: cannot open %s\n", destfile); | ||
101 | exit(1); | ||
102 | } | ||
103 | |||
104 | char buf[MAXBUF]; | ||
105 | while (fgets(buf, MAXBUF, fp1)) | ||
106 | fprintf(fp2, "%s", buf); | ||
107 | |||
108 | fclose(fp1); | ||
109 | fclose(fp2); | ||
110 | } | 210 | } |
111 | 211 | ||
112 | |||
113 | printf("fnetfilter running\n"); | ||
114 | return 0; | 212 | return 0; |
115 | } | 213 | } |