11 rule allow:udp:172.16.20.1:53:"DNS query"
12 rule allow:*:127.0.0.1:*:"localhost"
13 rule deny:*:207.38.11.35:*:"motd.gamespy.com"
16 app /opt/logjam/bin/logjam
17 rule allow:tcp:78.152.169.8:80:"my LiveJournal server"
21 static char *loadFile (const char *fname
) {
23 int fd
= open(fname
, O_RDONLY
| O_NOATIME
);
24 if (fd
< 0) return NULL
;
25 off_t size
= lseek(fd
, 0, SEEK_END
);
26 if (size
<= 0) goto done
;
27 if (lseek(fd
, 0, SEEK_SET
) < 0) goto done
;
30 if (read(fd
, res
, size
) != size
) { free(res
); res
= NULL
; goto done
; }
41 static char *skipBlanks (char **buf
) {
43 while (*res
&& (unsigned char)(*res
) <= ' ') res
++;
45 if (!res
[0]) res
= NULL
;
53 static char *skipLine (char **buf
) {
55 while (*res
&& (unsigned char)(*res
) != '\n') res
++;
58 if (!res
[0]) res
= NULL
;
64 * return ptr to the start of the word or NULL
65 * **buf will be changed!
67 static char *getWord (char **buf
) {
74 while (*end
&& *end
!= '"') {
76 char ch
= end
[1]; end
+= 2;
77 if (!ch
) { end
--; break; }
79 case 't': *s
++ = '\t'; break;
80 case 'r': *s
++ = '\r'; break;
81 case 'n': *s
++ = '\n'; break;
82 default: *s
++ = ch
; break;
88 while (*end
&& (unsigned char)(*end
) > ' ') {
89 if (*end
== ':') break;
95 if (!res
[0]) res
= NULL
;
100 /* ok: 0 -- error; -1: ends with dot; 1: normal number; 2: * */
101 static uint16_t getInt (char **buf
, int *ok
) {
103 char *word
= getWord(buf
);
105 if (!strcmp(word
, "*")) { *ok
= 2; return 0; }
108 if (*word
< '0' || *word
> '9') {
109 if (*word
== '.') *ok
= -1;
110 return (uint16_t)res
;
114 if (res
& 0x10000) return 0;
118 return (uint16_t)res
;
122 static uint16_t parseInt (char **buf
, int *ok
) {
125 if (!word
[0]) return 0;
126 if (!strcmp(word
, "*")) { *ok
= 2; return 0; }
129 if (*word
< '0' || *word
> '9') {
135 return (uint16_t)res
;
139 if (res
& 0x10000) return 0;
144 return (uint16_t)res
;
148 static uint32_t getIP (char **buf
, int *ok
) {
152 char *word
= getWord(buf
);
154 if (!strcmp(word
, "*")) { *ok
= 1; return 0; }
157 for (f
= 0; f
< 4; f
++) {
159 uint32_t t
= parseInt(&word
, &kk
);
160 /*printf("int: ok=%i, int=%u\n", kk, t);*/
161 if (f
== 0 && kk
== 2) { *ok
= 1; return 0; }
162 if ((f
== 3 && kk
!= 1) || (f
!= 3 && kk
!= -1)) return 0;
170 static char *ruleFilePath
= NULL
;
172 static void parseRulesFile (void) {
173 char *text
= NULL
, *tpos
= NULL
;
174 if (!ruleFilePath
) return;
175 text
= loadFile(ruleFilePath
);
176 if (!text
) goto error
;
178 logMsg(LOGMSG_DEBUG
, "parsing rule file: '%s'\n", ruleFilePath
);
180 char *word
; tpos
= text
;
181 while ((word
= getWord(&tpos
))) {
182 #ifdef OPT_RULEPARSER_TEST
183 printf("{%s}\n", word
);
185 if (strcmp(word
, "newrule")) {
191 tSessionRule
*sRulesH
= NULL
, *sRulesL
= NULL
;
192 #ifdef OPT_RULEPARSER_TEST
193 if (sRulesH
) printf("!!!\n");
195 while ((word
= getWord(&tpos
))) {
196 if (!strcmp(word
, "endrule")) {
197 #ifdef OPT_RULEPARSER_TEST
198 printf("{%s}\n", word
);
202 if (!strcmp(word
, "app")) {
203 word
= getWord(&tpos
);
206 #ifdef OPT_RULEPARSER_TEST
207 printf("{app: %s}\n", app
);
210 } else if (!strcmp(word
, "rule")) {
211 /* action, proto, ip, port, descr */
212 uint8_t allow
, flags
= /*IPCR_FLAG_SESSION*/0;
217 word
= getWord(&tpos
);
219 if (!strcmp(word
, "allow")) allow
= 1;
220 else if (!strcmp(word
, "deny")) allow
= 0;
221 else { skipLine(&tpos
); break; }
223 word
= getWord(&tpos
);
225 if (!strcmp(word
, "tcp")) flags
|= IPCR_FLAG_TCP
;
226 else if (!strcmp(word
, "udp")) flags
|= IPCR_FLAG_UDP
;
227 else if (!strcmp(word
, "*")) flags
|= IPCR_FLAG_TCP
| IPCR_FLAG_UDP
;
228 else { skipLine(&tpos
); break; }
231 ip
= getIP(&tpos
, &ok
);
232 /*printf("ok=%i; ip=%u\n", ok, ip);*/
233 if (!ok
) { skipLine(&tpos
); break; }
234 flags
|= IPCR_FLAG_IP
;
235 if (!ip
) flags
|= IPCR_FLAG_ANYIP
;
237 port
= getInt(&tpos
, &ok
);
238 /*printf("ok=%i; port=%u\n", ok, port);*/
239 if (!ok
) { skipLine(&tpos
); break; }
240 flags
|= IPCR_FLAG_PORT
;
241 if (!port
) flags
|= IPCR_FLAG_ANYPORT
;
243 #ifdef OPT_RULEPARSER_TEST
245 inet_ntop(AF_INET
, &ip
, dip
, sizeof(dip
));
246 printf("rule: allow=%u, flags=0x%02x, port=%u, ip=%s\n", allow
, flags
, port
, dip
);
248 addRuleEx(&sRulesH
, &sRulesL
, ip
, port
, allow
, flags
);
250 } else skipLine(&tpos
);
253 if (!strcmp(app
, "*") || !strcmp(app
, getProcName())) {
254 /* this is our rules! */
255 #ifdef OPT_RULEPARSER_TEST
256 tSessionRule
*c
= sRulesH
;
259 inet_ntop(AF_INET
, &c
->ip
, dip
, sizeof(dip
));
260 printf("OUR rule: allow=%u, flags=0x%02x, port=%u, ip=%s\n", c
->allow
, c
->flags
, c
->port
, dip
);
264 clearPermanentRules();
266 if (sRulesLast
) sRulesLast
->next
= sRulesH
; else sRules
= sRulesH
;
267 sRulesLast
= sRulesL
;
279 if (text
) free(text
);
280 #ifdef OPT_RULEPARSER_TEST
286 static void initRuleParser (void) {
290 #ifdef OPT_RULEPARSER_TEST
291 ruleFilePath
= strdup("./umfwGUI/rules.rc");
293 char *env
= getenv("TUMFW_RULEFILE");
294 if (env
) ruleFilePath
= strdup(env
);
301 static void updateRuleParser (void) {