- /* Do not scan twice. */
- if (malware_ok == 0) {
-
- /* find the scanner type from the av_scanner option */
- if ((scanner_name = string_nextinlist(&av_scanner_work, &sep,
- scanner_name_buffer,
- sizeof(scanner_name_buffer))) == NULL) {
- /* no scanner given */
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: av_scanner configuration variable is empty");
- return DEFER;
- };
-
- /* "drweb" scanner type ----------------------------------------------- */
- /* v0.1 - added support for tcp sockets */
- /* v0.0 - initial release -- support for unix sockets */
- if (strcmpic(scanner_name,US"drweb") == 0) {
- uschar *drweb_options;
- uschar drweb_options_buffer[1024];
- uschar drweb_options_default[] = "/usr/local/drweb/run/drwebd.sock";
- struct sockaddr_un server;
- int sock, result, ovector[30];
- unsigned int port, fsize;
- uschar tmpbuf[1024], *drweb_fbuf;
- uschar scanrequest[1024];
- uschar drweb_match_string[128];
- int drweb_rc, drweb_cmd, drweb_flags = 0x0000, drweb_fd,
- drweb_vnum, drweb_slen, drweb_fin = 0x0000;
- unsigned long bread;
- uschar hostname[256];
- struct hostent *he;
- struct in_addr in;
- pcre *drweb_re;
-
- if ((drweb_options = string_nextinlist(&av_scanner_work, &sep,
- drweb_options_buffer, sizeof(drweb_options_buffer))) == NULL) {
- /* no options supplied, use default options */
- drweb_options = drweb_options_default;
- };
-
- if (*drweb_options != '/') {
-
- /* extract host and port part */
- if( sscanf(CS drweb_options, "%s %u", hostname, &port) != 2 ) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: invalid socket '%s'", drweb_options);
- return DEFER;
- }
-
- /* Lookup the host */
- if((he = gethostbyname(CS hostname)) == 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: failed to lookup host '%s'", hostname);
- return DEFER;
- }
-
- in = *(struct in_addr *) he->h_addr_list[0];
-
- /* Open the drwebd TCP socket */
- if ( (sock = ip_socket(SOCK_STREAM, AF_INET)) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: unable to acquire socket (%s)",
- strerror(errno));
- return DEFER;
- }
-
- if (ip_connect(sock, AF_INET, (uschar*)inet_ntoa(in), port, 5) < 0) {
- close(sock);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: connection to %s, port %u failed (%s)",
- inet_ntoa(in), port, strerror(errno));
- return DEFER;
- }
-
- /* prepare variables */
- drweb_cmd = htonl(DRWEBD_SCAN_CMD);
- drweb_flags = htonl(DRWEBD_RETURN_VIRUSES | DRWEBD_IS_MAIL);
- snprintf(CS scanrequest, 1024,CS"%s/scan/%s/%s.eml",
- spool_directory, message_id, message_id);
-
- /* calc file size */
- drweb_fd = open(CS scanrequest, O_RDONLY);
- if (drweb_fd == -1) {
- close(sock);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: can't open spool file %s: %s",
- scanrequest, strerror(errno));
- return DEFER;
- }
- fsize = lseek(drweb_fd, 0, SEEK_END);
- if (fsize == -1) {
- close(sock);
- close(drweb_fd);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: can't seek spool file %s: %s",
- scanrequest, strerror(errno));
- return DEFER;
- }
- drweb_slen = htonl(fsize);
- lseek(drweb_fd, 0, SEEK_SET);
-
- /* send scan request */
- if ((send(sock, &drweb_cmd, sizeof(drweb_cmd), 0) < 0) ||
- (send(sock, &drweb_flags, sizeof(drweb_flags), 0) < 0) ||
- (send(sock, &drweb_fin, sizeof(drweb_fin), 0) < 0) ||
- (send(sock, &drweb_slen, sizeof(drweb_slen), 0) < 0)) {
- close(sock);
- close(drweb_fd);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: unable to send commands to socket (%s)", drweb_options);
- return DEFER;
- }
-
- drweb_fbuf = (uschar *) malloc (fsize);
- if (!drweb_fbuf) {
- close(sock);
- close(drweb_fd);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: unable to allocate memory %u for file (%s)",
- fsize, scanrequest);
- return DEFER;
- }
-
- result = read (drweb_fd, drweb_fbuf, fsize);
- if (result == -1) {
- close(sock);
- close(drweb_fd);
- free(drweb_fbuf);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: can't read spool file %s: %s",
- scanrequest, strerror(errno));
- return DEFER;
- }
- close(drweb_fd);
-
- /* send file body to socket */
- if (send(sock, drweb_fbuf, fsize, 0) < 0) {
- close(sock);
- free(drweb_fbuf);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: unable to send file body to socket (%s)", drweb_options);
- return DEFER;
- }
- close(drweb_fd);
- }
- else {
- /* open the drwebd UNIX socket */
- sock = socket(AF_UNIX, SOCK_STREAM, 0);
- if (sock < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: can't open UNIX socket");
- return DEFER;
- }
- server.sun_family = AF_UNIX;
- Ustrcpy(server.sun_path, drweb_options);
- if (connect(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
- close(sock);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: unable to connect to socket (%s). errno=%d", drweb_options, errno);
- return DEFER;
- }
-
- /* prepare variables */
- drweb_cmd = htonl(DRWEBD_SCAN_CMD);
- drweb_flags = htonl(DRWEBD_RETURN_VIRUSES | DRWEBD_IS_MAIL);
- snprintf(CS scanrequest, 1024,CS"%s/scan/%s/%s.eml", spool_directory, message_id, message_id);
- drweb_slen = htonl(Ustrlen(scanrequest));
-
- /* send scan request */
- if ((send(sock, &drweb_cmd, sizeof(drweb_cmd), 0) < 0) ||
- (send(sock, &drweb_flags, sizeof(drweb_flags), 0) < 0) ||
- (send(sock, &drweb_slen, sizeof(drweb_slen), 0) < 0) ||
- (send(sock, scanrequest, Ustrlen(scanrequest), 0) < 0) ||
- (send(sock, &drweb_fin, sizeof(drweb_fin), 0) < 0)) {
- close(sock);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: drweb: unable to send commands to socket (%s)", drweb_options);
- return DEFER;
- }
- }