... | ... |
@@ -43,7 +43,7 @@ export makefile_defs |
43 | 43 |
VERSION = 0 |
44 | 44 |
PATCHLEVEL = 8 |
45 | 45 |
SUBLEVEL = 12 |
46 |
-EXTRAVERSION = dev-17-cristian |
|
46 |
+EXTRAVERSION = dev-18-fifo |
|
47 | 47 |
|
48 | 48 |
RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) |
49 | 49 |
OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]") |
... | ... |
@@ -39,6 +39,7 @@ |
39 | 39 |
* require_certificate added (andrei) |
40 | 40 |
* 2003-07-06 more tls config. vars added: tls_method, tls_port_no (andrei) |
41 | 41 |
* 2003-10-02 added {,set_}advertised_{address,port} (andrei) |
42 |
+ * 2003-10-07 added hex and octal numbers support (andrei) |
|
42 | 43 |
*/ |
43 | 44 |
|
44 | 45 |
|
... | ... |
@@ -197,9 +198,11 @@ TLSv1 "tlsv1"|"TLSv1"|"TLSV1" |
197 | 198 |
LETTER [a-zA-Z] |
198 | 199 |
DIGIT [0-9] |
199 | 200 |
ALPHANUM {LETTER}|{DIGIT}|[_] |
200 |
-NUMBER {DIGIT}+ |
|
201 |
+NUMBER 0|([1-9]{DIGIT}*) |
|
201 | 202 |
ID {LETTER}{ALPHANUM}* |
202 | 203 |
HEX [0-9a-fA-F] |
204 |
+HEXNUMBER 0x{HEX}+ |
|
205 |
+OCTNUMBER 0[0-7]+ |
|
203 | 206 |
HEX4 {HEX}{1,4} |
204 | 207 |
IPV6ADDR ({HEX4}":"){7}{HEX4}|({HEX4}":"){1,7}(":"{HEX4}){1,7}|":"(":"{HEX4}){1,7}|({HEX4}":"){1,7}":"|"::" |
205 | 208 |
QUOTES \" |
... | ... |
@@ -342,6 +345,10 @@ EAT_ABLE [\ \t\b\r] |
342 | 345 |
|
343 | 346 |
<INITIAL>{IPV6ADDR} { count(); yylval.strval=yytext; return IPV6ADDR; } |
344 | 347 |
<INITIAL>{NUMBER} { count(); yylval.intval=atoi(yytext);return NUMBER; } |
348 |
+<INITIAL>{HEXNUMBER} { count(); yylval.intval=(int)strtol(yytext, 0, 16); |
|
349 |
+ return NUMBER; } |
|
350 |
+<INITIAL>{OCTNUMBER} { count(); yylval.intval=(int)strtol(yytext, 0, 8); |
|
351 |
+ return NUMBER; } |
|
345 | 352 |
<INITIAL>{YES} { count(); yylval.intval=1; return NUMBER; } |
346 | 353 |
<INITIAL>{NO} { count(); yylval.intval=0; return NUMBER; } |
347 | 354 |
<INITIAL>{TCP} { count(); yylval.intval=PROTO_TCP; return NUMBER; } |
... | ... |
@@ -56,6 +56,8 @@ |
56 | 56 |
* 2003-03-29 destroy pkg mem introduced (jiri) |
57 | 57 |
* 2003-03-19 replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei) |
58 | 58 |
* 2003-01-29 new built-in fifo commands: arg and pwd (jiri) |
59 |
+ * 2003-10-07 fifo security fixes: permissions, always delete old fifo, |
|
60 |
+ * reply fifo checks -- added fifo_check (andrei) |
|
59 | 61 |
*/ |
60 | 62 |
|
61 | 63 |
|
... | ... |
@@ -87,8 +89,7 @@ |
87 | 89 |
|
88 | 90 |
/* FIFO server vars */ |
89 | 91 |
char *fifo=0; /* FIFO name */ |
90 |
-int fifo_mode=S_IRUSR | S_IWUSR | S_IRGRP | |
|
91 |
- S_IWGRP | S_IROTH | S_IWOTH; |
|
92 |
+int fifo_mode=S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ; |
|
92 | 93 |
pid_t fifo_pid; |
93 | 94 |
/* file descriptors */ |
94 | 95 |
static int fifo_read=0; |
... | ... |
@@ -299,6 +300,60 @@ static char *trim_filename( char * file ) |
299 | 300 |
return new_fn; |
300 | 301 |
} |
301 | 302 |
|
303 |
+ |
|
304 |
+ |
|
305 |
+/* reply fifo security checks: |
|
306 |
+ * checks if fd is a fifo, is not hardlinked and it's not a softlink |
|
307 |
+ * opened file descriptor + file name (for soft link check) |
|
308 |
+ * returns 0 if ok, <0 if not */ |
|
309 |
+static int fifo_check(int fd, char* fname) |
|
310 |
+{ |
|
311 |
+ struct stat fst; |
|
312 |
+ struct stat lst; |
|
313 |
+ |
|
314 |
+ if (fstat(fd, &fst)<0){ |
|
315 |
+ LOG(L_ERR, "ERROR: fifo_check: fstat failed: %s\n", |
|
316 |
+ strerror(errno)); |
|
317 |
+ return -1; |
|
318 |
+ } |
|
319 |
+ /* check if fifo */ |
|
320 |
+ if (!S_ISFIFO(fst.st_mode)){ |
|
321 |
+ LOG(L_ERR, "ERROR: fifo_check: %s is not a fifo\n", fname); |
|
322 |
+ return -1; |
|
323 |
+ } |
|
324 |
+ /* check if hard-linked */ |
|
325 |
+ if (fst.st_nlink>1){ |
|
326 |
+ LOG(L_ERR, "ERROR: security: fifo_check: %s is hard-linked %d times\n", |
|
327 |
+ fname, fst.st_nlink); |
|
328 |
+ return -1; |
|
329 |
+ } |
|
330 |
+ |
|
331 |
+ /* lstat to check for soft links */ |
|
332 |
+ if (lstat(fname, &lst)<0){ |
|
333 |
+ LOG(L_ERR, "ERROR: fifo_check: lstat failed: %s\n", |
|
334 |
+ strerror(errno)); |
|
335 |
+ return -1; |
|
336 |
+ } |
|
337 |
+ if (S_ISLNK(lst.st_mode)){ |
|
338 |
+ LOG(L_ERR, "ERROR: security: fifo_check: %s is a soft link\n", |
|
339 |
+ fname); |
|
340 |
+ return -1; |
|
341 |
+ } |
|
342 |
+ /* if this is not a symbolic link, check to see if the inode didn't |
|
343 |
+ * change to avoid possible sym.link, rm sym.link & replace w/ fifo race |
|
344 |
+ */ |
|
345 |
+ if ((lst.st_dev!=fst.st_dev)||(lst.st_ino!=fst.st_ino)){ |
|
346 |
+ LOG(L_ERR, "ERROR: security: fifo_check: inode/dev number differ" |
|
347 |
+ ": %ld %ld (%s)\n", |
|
348 |
+ fst.st_ino, lst.st_ino, fname); |
|
349 |
+ return -1; |
|
350 |
+ } |
|
351 |
+ /* success */ |
|
352 |
+ return 0; |
|
353 |
+} |
|
354 |
+ |
|
355 |
+ |
|
356 |
+ |
|
302 | 357 |
/* tell FIFO client what happened via reply pipe */ |
303 | 358 |
void fifo_reply( char *reply_fifo, char *reply_fmt, ... ) |
304 | 359 |
{ |
... | ... |
@@ -367,6 +422,10 @@ tryagain: |
367 | 422 |
pipe_name, strerror(errno)); |
368 | 423 |
return 0; |
369 | 424 |
} |
425 |
+ /* security checks: is this really a fifo?, is |
|
426 |
+ * it hardlinked? is it a soft link? */ |
|
427 |
+ if (fifo_check(fifofd, pipe_name)<0) goto error; |
|
428 |
+ |
|
370 | 429 |
/* we want server blocking for big writes */ |
371 | 430 |
if ( (flags=fcntl(fifofd, F_GETFL, 0))<0) { |
372 | 431 |
LOG(L_ERR, "ERROR: open_reply_pipe (%s): getfl failed: %s\n", |
... | ... |
@@ -484,7 +543,15 @@ int open_fifo_server() |
484 | 543 |
return 1; |
485 | 544 |
} |
486 | 545 |
DBG("DBG: open_uac_fifo: opening fifo...\n"); |
487 |
- if (stat(fifo, &filestat)==-1) { /* FIFO doesn't exist yet ... */ |
|
546 |
+ if (stat(fifo, &filestat)==0){ |
|
547 |
+ /* FIFO exist, delete it (safer) */ |
|
548 |
+ if (unlink(fifo)<0){ |
|
549 |
+ LOG(L_ERR, "ERROR: open_fifo_server: cannot delete old fifo (%s):" |
|
550 |
+ " %s\n", fifo, strerror(errno)); |
|
551 |
+ return -1; |
|
552 |
+ } |
|
553 |
+ } |
|
554 |
+ /* create FIFO ... */ |
|
488 | 555 |
LOG(L_DBG, "DEBUG: open_fifo_server: FIFO stat failed: %s\n", |
489 | 556 |
strerror(errno)); |
490 | 557 |
if ((mkfifo(fifo, fifo_mode)<0)) { |
... | ... |
@@ -500,14 +567,6 @@ int open_fifo_server() |
500 | 567 |
strerror(errno), fifo_mode); |
501 | 568 |
return -1; |
502 | 569 |
} |
503 |
- } else { /* file can be stat-ed, check if it is really a FIFO */ |
|
504 |
- if (!(S_ISFIFO(filestat.st_mode))) { |
|
505 |
- LOG(L_ERR, "ERROR: open_fifo_server: " |
|
506 |
- "the file is not a FIFO: %s\n", |
|
507 |
- fifo ); |
|
508 |
- return -1; |
|
509 |
- } |
|
510 |
- } |
|
511 | 570 |
DBG("DEBUG: fifo %s opened, mode=%d\n", fifo, fifo_mode ); |
512 | 571 |
time(&up_since); |
513 | 572 |
t=ctime(&up_since); |