- else if (!strncmp(CS av_buffer, "-1", 2)) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: malware acl condition: sophie reported error");
- return DEFER;
- }
- else {
- /* all ok, no virus */
- malware_name = NULL;
- };
- }
- /* ----------------------------------------------------------------------- */
-
-
- /* "clamd" scanner type ------------------------------------------------- */
- /* This code was contributed by David Saez */
- else if (strcmpic(scanner_name,US"clamd") == 0) {
- uschar *clamd_options;
- uschar clamd_options_buffer[1024];
- uschar clamd_options_default[] = "/tmp/clamd";
- uschar *p,*vname;
- struct sockaddr_un server;
- int sock,bread=0;
- unsigned int port;
- uschar file_name[1024];
- uschar av_buffer[1024];
- uschar hostname[256];
- struct hostent *he;
- struct in_addr in;
- uschar *clamd_options2;
- uschar clamd_options2_buffer[1024];
- uschar clamd_options2_default[] = "";
- uschar av_buffer2[1024];
- uschar *clamav_fbuf;
- uschar scanrequest[1024];
- int sockData, clam_fd, result;
- unsigned int fsize;
-
- if ((clamd_options = string_nextinlist(&av_scanner_work, &sep,
- clamd_options_buffer,
- sizeof(clamd_options_buffer))) == NULL) {
- /* no options supplied, use default options */
- clamd_options = clamd_options_default;
- }
- if ((clamd_options2 = string_nextinlist(&av_scanner_work, &sep,
- clamd_options2_buffer,
- sizeof(clamd_options2_buffer))) == NULL) {
- clamd_options2 = clamd_options2_default;
- }
-
- /* socket does not start with '/' -> network socket */
- if (*clamd_options != '/') {
-
- /* extract host and port part */
- if( sscanf(CS clamd_options, "%s %u", hostname, &port) != 2 ) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: invalid socket '%s'", clamd_options);
- return DEFER;
- };
-
- /* Lookup the host */
- if((he = gethostbyname(CS hostname)) == 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: failed to lookup host '%s'", hostname);
- return DEFER;
- }
-
- in = *(struct in_addr *) he->h_addr_list[0];
-
- /* Open the ClamAV Socket */
- if ( (sock = ip_socket(SOCK_STREAM, AF_INET)) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: unable to acquire socket (%s)",
- strerror(errno));
- return DEFER;
- }
-
- if (ip_connect(sock, AF_INET, (uschar*)inet_ntoa(in), port, 5) < 0) {
- (void)close(sock);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: connection to %s, port %u failed (%s)",
- inet_ntoa(in), port, strerror(errno));
- return DEFER;
- }
-
- if (strcmpic(clamd_options2,US"local") == 0) {
-
- /* Pass the string to ClamAV (7 = "SCAN \n" + \0) */
-
- (void)string_format(file_name,1024,"SCAN %s/scan/%s\n", spool_directory, message_id);
-
- if (send(sock, file_name, Ustrlen(file_name), 0) < 0) {
- (void)close(sock);
- log_write(0, LOG_MAIN|LOG_PANIC,"malware acl condition: clamd: unable to write to socket (%s)",
- strerror(errno));
- return DEFER;
- }
- } else {
-
- /* Pass the string to ClamAV (7 = "STREAM\n") */
-
- if (send(sock, "STREAM\n", 7, 0) < 0) {
- (void)close(sock);
- log_write(0, LOG_MAIN|LOG_PANIC,"malware acl condition: clamd: unable to write to socket (%s)",
- strerror(errno));
- return DEFER;
- }
- memset(av_buffer2, 0, sizeof(av_buffer2));
- bread = read(sock, av_buffer2, sizeof(av_buffer2));
-
- if (bread < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: unable to read PORT from socket (%s)",
- strerror(errno));
- return DEFER;
- }
-
- if (bread == sizeof(av_buffer)) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: buffer too small");
- return DEFER;
- }
-
- if (!(*av_buffer2)) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: ClamAV returned null");
- return DEFER;
- }
-
- av_buffer2[bread] = '\0';
- if( sscanf(CS av_buffer2, "PORT %u\n", &port) != 1 ) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: Expected port information from clamd, got '%s'", av_buffer2);
- return DEFER;
- };
-
- if ( (sockData = ip_socket(SOCK_STREAM, AF_INET)) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: unable to acquire socket (%s)",
- strerror(errno));
- return DEFER;
- }
-
- if (ip_connect(sockData, AF_INET, (uschar*)inet_ntoa(in), port, 5) < 0) {
- (void)close(sockData);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: connection to %s, port %u failed (%s)",
- inet_ntoa(in), port, strerror(errno));
- return DEFER;
- }
-
- (void)string_format(scanrequest, 1024,CS"%s/scan/%s/%s.eml",
- spool_directory, message_id, message_id);
-
- /* calc file size */
- clam_fd = open(CS scanrequest, O_RDONLY);
- if (clam_fd == -1) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: can't open spool file %s: %s",
- scanrequest, strerror(errno));
- return DEFER;
- }
- fsize = lseek(clam_fd, 0, SEEK_END);
- if (fsize == -1) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: can't seek spool file %s: %s",
- scanrequest, strerror(errno));
- return DEFER;
- }
- lseek(clam_fd, 0, SEEK_SET);
-
- clamav_fbuf = (uschar *) malloc (fsize);
- if (!clamav_fbuf) {
- (void)close(sockData);
- (void)close(clam_fd);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: unable to allocate memory %u for file (%s)",
- fsize, scanrequest);
- return DEFER;
- }
-
- result = read (clam_fd, clamav_fbuf, fsize);
- if (result == -1) {
- (void)close(sockData);
- (void)close(clam_fd);
- free(clamav_fbuf);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: can't read spool file %s: %s",
- scanrequest, strerror(errno));
- return DEFER;
- }
- (void)close(clam_fd);
-
- /* send file body to socket */
- if (send(sockData, clamav_fbuf, fsize, 0) < 0) {
- (void)close(sockData);
- free(clamav_fbuf);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: unable to send file body to socket (%s:%u)", hostname, port);
- return DEFER;
- }
- free(clamav_fbuf);
- (void)close(sockData);
- }
- }
- else {
- /* open the local socket */
- if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: unable to acquire socket (%s)",
- strerror(errno));
- return DEFER;
- }
-
- server.sun_family = AF_UNIX;
- Ustrcpy(server.sun_path, clamd_options);
-
- if (connect(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
- (void)close(sock);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: unable to connect to UNIX socket %s (%s)",
- clamd_options, strerror(errno) );
- return DEFER;
- }
- }
-
- /* Pass the string to ClamAV (7 = "SCAN \n" + \0) */
-
- (void)string_format(file_name,1024,"SCAN %s/scan/%s\n", spool_directory, message_id);