git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@80 77e5149b-7576-45b1-b177-96237e5ba77b
Nigel Horne authored on 2003/10/12 17:39:15... | ... |
@@ -1,4 +1,11 @@ |
1 |
+Sun Oct 12 09:37:44 BST 2003 (njh) |
|
2 |
+--------------------------------- |
|
3 |
+ * clamav-milter: use VERSION info to talk to clamd not PING/PONG |
|
4 |
+ Only close fd 0/1/2 if !Foreground |
|
5 |
+ Sanity checking now performed on LocalSocket as well as TCPSocket |
|
6 |
+ |
|
1 | 7 |
Sat Oct 11 16:42:42 BST 2003 (njh) |
8 |
+--------------------------------- |
|
2 | 9 |
* clamav-milter: fixed possible crash with long e-mail addresses |
3 | 10 |
Removed call to clamdscan to get version |
4 | 11 |
|
... | ... |
@@ -135,6 +135,9 @@ Changes |
135 | 135 |
Removed remote possibility of crash if the target |
136 | 136 |
e-mail address is very long |
137 | 137 |
No longer calls clamdscan to get the version |
138 |
+0.60m 12/10/03 Now does sanity check if using localSocket |
|
139 |
+ Gets version info from clamd |
|
140 |
+ Only reset fd's 0/1/2 if !ForeGround |
|
138 | 141 |
|
139 | 142 |
BUG REPORTS |
140 | 143 |
|
... | ... |
@@ -140,9 +140,15 @@ |
140 | 140 |
* Removed remote possibility of crash if the target |
141 | 141 |
* e-mail address is very long |
142 | 142 |
* No longer calls clamdscan to get the version |
143 |
+ * 0.60m 12/10/03 Now does sanity check if using localSocket |
|
144 |
+ * Gets version info from clamd |
|
145 |
+ * Only reset fd's 0/1/2 if !ForeGround |
|
143 | 146 |
* |
144 | 147 |
* Change History: |
145 | 148 |
* $Log: clamav-milter.c,v $ |
149 |
+ * Revision 1.14 2003/10/12 08:37:21 nigelhorne |
|
150 |
+ * Uses VERSION command to get version information |
|
151 |
+ * |
|
146 | 152 |
* Revision 1.13 2003/10/11 15:42:15 nigelhorne |
147 | 153 |
* Don't call clamdscan |
148 | 154 |
* |
... | ... |
@@ -168,9 +174,9 @@ |
168 | 168 |
* Added -f flag use MaxThreads if --max-children not set |
169 | 169 |
* |
170 | 170 |
*/ |
171 |
-static char const rcsid[] = "$Id: clamav-milter.c,v 1.13 2003/10/11 15:42:15 nigelhorne Exp $"; |
|
171 |
+static char const rcsid[] = "$Id: clamav-milter.c,v 1.14 2003/10/12 08:37:21 nigelhorne Exp $"; |
|
172 | 172 |
|
173 |
-#define CM_VERSION "0.60k" |
|
173 |
+#define CM_VERSION "0.60m" |
|
174 | 174 |
|
175 | 175 |
/*#define CONFDIR "/usr/local/etc"*/ |
176 | 176 |
|
... | ... |
@@ -250,7 +256,7 @@ static void clamfi_cleanup(SMFICTX *ctx); |
250 | 250 |
static int clamfi_send(const struct privdata *privdata, size_t len, const char *format, ...); |
251 | 251 |
static char *strrcpy(char *dest, const char *source); |
252 | 252 |
|
253 |
-static char clamav_version[64]; |
|
253 |
+static char clamav_version[128]; |
|
254 | 254 |
static int fflag = 0; /* force a scan, whatever */ |
255 | 255 |
static int oflag = 0; /* scan messages from our machine? */ |
256 | 256 |
static int lflag = 0; /* scan messages from our site? */ |
... | ... |
@@ -344,6 +350,10 @@ main(int argc, char **argv) |
344 | 344 |
clamfi_close, /* connection cleanup callback */ |
345 | 345 |
}; |
346 | 346 |
|
347 |
+ /* |
|
348 |
+ * Temporarily enter guessed value into clamav_version, will |
|
349 |
+ * be overwritten later by the value returned by clamd |
|
350 |
+ */ |
|
347 | 351 |
snprintf(clamav_version, sizeof(clamav_version), |
348 | 352 |
"ClamAV version %s, clamav-milter version %s", |
349 | 353 |
VERSION, CM_VERSION); |
... | ... |
@@ -504,14 +514,25 @@ main(int argc, char **argv) |
504 | 504 |
|
505 | 505 |
/* |
506 | 506 |
* Get the outgoing socket details - the way to talk to clamd |
507 |
- * TODO: support TCP sockets |
|
508 | 507 |
*/ |
509 |
- if((cpt = cfgopt(copt, "LocalSocket")) != NULL) |
|
508 |
+ if((cpt = cfgopt(copt, "LocalSocket")) != NULL) { |
|
509 |
+ if(cfgopt(copt, "TCPSocket") != NULL) { |
|
510 |
+ fprintf(stderr, "%s: You can select one server type only (local/TCP) in %s\n", |
|
511 |
+ argv[0], cfgfile); |
|
512 |
+ return EX_CONFIG; |
|
513 |
+ } |
|
510 | 514 |
/* |
511 | 515 |
* TODO: check --server hasn't been set |
512 | 516 |
*/ |
513 | 517 |
localSocket = cpt->strarg; |
514 |
- else if((cpt = cfgopt(copt, "TCPSocket")) != NULL) { |
|
518 |
+ if(!pingServer()) { |
|
519 |
+ fprintf(stderr, "Can't talk to clamd server via %s\n", |
|
520 |
+ localSocket); |
|
521 |
+ fprintf(stderr, "Check your entry for LocalSocket in %s\n", |
|
522 |
+ cfgfile); |
|
523 |
+ return EX_CONFIG; |
|
524 |
+ } |
|
525 |
+ } else if((cpt = cfgopt(copt, "TCPSocket")) != NULL) { |
|
515 | 526 |
/* |
516 | 527 |
* TCPSocket is in fact a port number not a full socket |
517 | 528 |
*/ |
... | ... |
@@ -528,13 +549,8 @@ main(int argc, char **argv) |
528 | 528 |
argv[0], cfgfile); |
529 | 529 |
return EX_CONFIG; |
530 | 530 |
} |
531 |
- if(localSocket && tcpSocket) { |
|
532 |
- fprintf(stderr, "%s: You can select one server type only (local/TCP) in %s\n", |
|
533 |
- argv[0], cfgfile); |
|
534 |
- return EX_CONFIG; |
|
535 |
- } |
|
536 | 531 |
|
537 |
- if(!cfgopt(copt, "Foreground")) |
|
532 |
+ if(!cfgopt(copt, "Foreground")) { |
|
538 | 533 |
switch(fork()) { |
539 | 534 |
case -1: |
540 | 535 |
perror("fork"); |
... | ... |
@@ -544,6 +560,13 @@ main(int argc, char **argv) |
544 | 544 |
default: /* parent */ |
545 | 545 |
return EX_OK; |
546 | 546 |
} |
547 |
+ close(0); |
|
548 |
+ close(1); |
|
549 |
+ close(2); |
|
550 |
+ open("/dev/null", O_RDONLY); |
|
551 |
+ if(open("/dev/console", O_WRONLY) == 1) |
|
552 |
+ dup(1); |
|
553 |
+ } |
|
547 | 554 |
|
548 | 555 |
if(smfi_setconn(port) == MI_FAILURE) { |
549 | 556 |
fprintf(stderr, "%s: smfi_setconn failed\n", |
... | ... |
@@ -592,13 +615,6 @@ main(int argc, char **argv) |
592 | 592 |
|
593 | 593 |
signal(SIGPIPE, SIG_IGN); |
594 | 594 |
|
595 |
- close(0); |
|
596 |
- close(1); |
|
597 |
- close(2); |
|
598 |
- open("/dev/null", O_RDONLY); |
|
599 |
- if(open("/dev/console", O_WRONLY) == 1) |
|
600 |
- dup(1); |
|
601 |
- |
|
602 | 595 |
return smfi_main(); |
603 | 596 |
} |
604 | 597 |
|
... | ... |
@@ -609,24 +625,54 @@ main(int argc, char **argv) |
609 | 609 |
static int |
610 | 610 |
pingServer(void) |
611 | 611 |
{ |
612 |
- struct sockaddr_in server; |
|
612 |
+ char *ptr; |
|
613 | 613 |
int sock, nbytes; |
614 |
- char buf[6]; |
|
614 |
+ char buf[128]; |
|
615 | 615 |
|
616 |
- memset((char *)&server, 0, sizeof(struct sockaddr_in)); |
|
617 |
- server.sin_family = AF_INET; |
|
618 |
- server.sin_port = htons(tcpSocket); |
|
619 |
- server.sin_addr.s_addr = inet_addr(serverIP); |
|
616 |
+ if(localSocket) { |
|
617 |
+ struct sockaddr_un server; |
|
620 | 618 |
|
621 |
- if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { |
|
622 |
- perror("socket"); |
|
623 |
- return 0; |
|
624 |
- } |
|
625 |
- if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) { |
|
626 |
- perror("connect"); |
|
627 |
- return 0; |
|
619 |
+ memset((char *)&server, 0, sizeof(struct sockaddr_un)); |
|
620 |
+ server.sun_family = AF_UNIX; |
|
621 |
+ strncpy(server.sun_path, localSocket, sizeof(server.sun_path)); |
|
622 |
+ |
|
623 |
+ if((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { |
|
624 |
+ perror("socket"); |
|
625 |
+ return 0; |
|
626 |
+ } |
|
627 |
+ if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_un)) < 0) { |
|
628 |
+ perror(localSocket); |
|
629 |
+ return 0; |
|
630 |
+ } |
|
631 |
+ } else { |
|
632 |
+ struct sockaddr_in server; |
|
633 |
+ |
|
634 |
+ memset((char *)&server, 0, sizeof(struct sockaddr_in)); |
|
635 |
+ server.sin_family = AF_INET; |
|
636 |
+ server.sin_port = htons(tcpSocket); |
|
637 |
+ server.sin_addr.s_addr = inet_addr(serverIP); |
|
638 |
+ |
|
639 |
+ if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { |
|
640 |
+ perror("socket"); |
|
641 |
+ return 0; |
|
642 |
+ } |
|
643 |
+ if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) { |
|
644 |
+ perror("connect"); |
|
645 |
+ return 0; |
|
646 |
+ } |
|
628 | 647 |
} |
629 |
- if(send(sock, "PING\n", 5, 0) < 5) { |
|
648 |
+ |
|
649 |
+ /* |
|
650 |
+ * It would be better to use PING, check for PONG then issue the |
|
651 |
+ * VERSION command, since that would better validate that we're |
|
652 |
+ * talking to clamd, however clamd closes the session after |
|
653 |
+ * sending PONG :-( |
|
654 |
+ * So this code does not really validate that we're talking to clamd |
|
655 |
+ * Needs a fix to clamd |
|
656 |
+ * Also version command is verbose: says "clamd / ClamAV version" |
|
657 |
+ * instead of "clamAV version" |
|
658 |
+ */ |
|
659 |
+ if(send(sock, "VERSION\n", 8, 0) < 8) { |
|
630 | 660 |
perror("send"); |
631 | 661 |
close(sock); |
632 | 662 |
return 0; |
... | ... |
@@ -644,7 +690,18 @@ pingServer(void) |
644 | 644 |
} |
645 | 645 |
buf[nbytes] = '\0'; |
646 | 646 |
|
647 |
- return strcmp(buf, "PONG\n") == 0; |
|
647 |
+ /* Remove the trailing new line from the reply */ |
|
648 |
+ if((ptr = strchr(buf, '\n')) != NULL) |
|
649 |
+ *ptr = '\0'; |
|
650 |
+ |
|
651 |
+ /* |
|
652 |
+ * No real validation is done here |
|
653 |
+ */ |
|
654 |
+ snprintf(clamav_version, sizeof(clamav_version), |
|
655 |
+ "ClamAV version '%s', clamav-milter version '%s'", |
|
656 |
+ buf, CM_VERSION); |
|
657 |
+ |
|
658 |
+ return 1; |
|
648 | 659 |
} |
649 | 660 |
|
650 | 661 |
static sfsistat |