packages: exim/exim.spec, exim/exim-bug-1057.patch (NEW) - rel 2; add av lo...

arekm arekm at pld-linux.org
Fri Oct 21 09:02:46 CEST 2011


Author: arekm                        Date: Fri Oct 21 07:02:46 2011 GMT
Module: packages                      Tag: HEAD
---- Log message:
- rel 2; add av loadbalancing (upstream bug 1057)

---- Files affected:
packages/exim:
   exim.spec (1.331 -> 1.332) , exim-bug-1057.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: packages/exim/exim.spec
diff -u packages/exim/exim.spec:1.331 packages/exim/exim.spec:1.332
--- packages/exim/exim.spec:1.331	Wed Oct 12 19:36:42 2011
+++ packages/exim/exim.spec	Fri Oct 21 09:02:41 2011
@@ -16,7 +16,7 @@
 Summary(pt_BR.UTF-8):	Servidor de correio eletrônico exim
 Name:		exim
 Version:	4.77
-Release:	1
+Release:	2
 Epoch:		2
 License:	GPL
 Group:		Networking/Daemons/SMTP
@@ -54,6 +54,7 @@
 Patch8:		%{name}-spam-timeout.patch
 Patch9:		%{name}-dkim.patch
 Patch10:	%{name}-force-sigalrm.patch
+Patch11:	%{name}-bug-1057.patch
 URL:		http://www.exim.org/
 %{?with_sasl:BuildRequires:	cyrus-sasl-devel >= 2.1.0}
 BuildRequires:	db-devel
@@ -169,6 +170,7 @@
 %patch8 -p1
 #%patch9 -p0
 %patch10 -p1
+%patch11 -p1
 
 install %{SOURCE13} doc/FAQ.txt.bz2
 install %{SOURCE14} doc/config.samples.tar.bz2
@@ -376,6 +378,9 @@
 All persons listed below can be reached at <cvs_login>@pld-linux.org
 
 $Log$
+Revision 1.332  2011/10/21 07:02:41  arekm
+- rel 2; add av loadbalancing (upstream bug 1057)
+
 Revision 1.331  2011/10/12 17:36:42  arekm
 - up to 4.77
 

================================================================
Index: packages/exim/exim-bug-1057.patch
diff -u /dev/null packages/exim/exim-bug-1057.patch:1.1
--- /dev/null	Fri Oct 21 09:02:46 2011
+++ packages/exim/exim-bug-1057.patch	Fri Oct 21 09:02:41 2011
@@ -0,0 +1,221 @@
+diff -urN exim-4.73_RC1/src/malware.c exim-4.73_RC1-new/src/malware.c
+--- exim-4.73_RC1/src/malware.c	2010-12-23 14:19:35.000000000 +0000
++++ exim-4.73_RC1-new/src/malware.c	2011-01-05 09:58:34.000000000 +0000
+@@ -12,6 +12,16 @@
+ #include "exim.h"
+ #ifdef WITH_CONTENT_SCAN
+ 
++/* The maximum number of clamd servers that are supported in the configuration */
++#define MAX_CLAMD_SERVERS 32
++/* Maximum length of the hostname that can be specified in the clamd address list */
++#define MAX_CLAMD_ADDRESS_LENGTH 64
++
++typedef struct clamd_address_container {
++  uschar tcp_addr[MAX_CLAMD_ADDRESS_LENGTH];
++  unsigned int tcp_port;
++} clamd_address_container;
++
+ /* declaration of private routines */
+ static int mksd_scan_packed(int sock, uschar *scan_filename);
+ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking);
+@@ -1295,7 +1305,7 @@
+      * WITH_OLD_CLAMAV_STREAM is defined.
+      * See Exim bug 926 for details.  */
+     else if (strcmpic(scanner_name,US"clamd") == 0) {
+-      uschar *clamd_options;
++      uschar *clamd_options = NULL;
+       uschar clamd_options_buffer[1024];
+       uschar clamd_options_default[] = "/tmp/clamd";
+       uschar *p, *vname, *result_tag, *response_end;
+@@ -1304,16 +1314,16 @@
+       unsigned int port;
+       uschar file_name[1024];
+       uschar av_buffer[1024];
+-      uschar hostname[256];
++      uschar *hostname = "";
+       struct hostent *he;
+       struct in_addr in;
+-      uschar *clamd_options2;
+-      uschar clamd_options2_buffer[1024];
+-      uschar clamd_options2_default[] = "";
+       uschar *clamav_fbuf;
+       int clam_fd, result;
+       unsigned int fsize;
+-      BOOL use_scan_command, fits;
++      BOOL use_scan_command = FALSE, fits;
++      clamd_address_container * clamd_address_vector[MAX_CLAMD_SERVERS];
++      int current_server;
++      int num_servers = 0;
+ #ifdef WITH_OLD_CLAMAV_STREAM
+       uschar av_buffer2[1024];
+       int sockData;
+@@ -1327,16 +1337,60 @@
+         /* 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;
+-      }
+ 
+-      if ((*clamd_options == '/') || (strcmpic(clamd_options2,US"local") == 0))
++      if (*clamd_options == '/')
++        /* Local file; so we def want to use_scan_command and don't want to try
++         * passing IP/port combinations */
+         use_scan_command = TRUE;
+-      else
+-        use_scan_command = FALSE;
++      else {
++        uschar *address = clamd_options;
++        uschar address_buffer[MAX_CLAMD_ADDRESS_LENGTH + 20];
++
++        /* Go through the rest of the list of host/port and construct an array
++         * of servers to try. The first one is the bit we just passed from
++         * clamd_options so process that first and then scan the remainder of
++         * the address buffer */
++        do {
++          clamd_address_container *this_clamd;
++
++          /* The 'local' option means use the SCAN command over the network
++           * socket (ie common file storage in use) */
++          if (strcmpic(address,US"local") == 0) {
++            use_scan_command = TRUE;
++            continue;
++          }
++
++          /* XXX: If unsuccessful we should free this memory */
++          this_clamd =
++              (clamd_address_container *)store_get(sizeof(clamd_address_container));
++
++          /* extract host and port part */
++          if( sscanf(CS address, "%" MAX_CLAMD_ADDRESS_LENGTH "s %u", this_clamd->tcp_addr,
++                                            &(this_clamd->tcp_port)) != 2 ) {
++            log_write(0, LOG_MAIN|LOG_PANIC,
++                      "malware acl condition: clamd: invalid address '%s'", address);
++            continue;
++          }
++
++          clamd_address_vector[num_servers] = this_clamd;
++          num_servers++;
++          if (num_servers >= MAX_CLAMD_SERVERS) {
++            log_write(0, LOG_MAIN|LOG_PANIC,
++                  "More than " MAX_CLAMD_SERVERS " clamd servers specified; "
++                  "only using the first " MAX_CLAMD_SERVERS );
++            break;
++          }
++        } while ((address = string_nextinlist(&av_scanner_work, &sep,
++                                        address_buffer,
++                                        sizeof(address_buffer))) != NULL);
++
++        /* check if we have at least one server */
++        if (!num_servers) {
++          log_write(0, LOG_MAIN|LOG_PANIC,
++             "malware acl condition: clamd: no useable clamd server addresses in malware configuration option.");
++          return DEFER;
++        }
++      }
+ 
+       /* See the discussion of response formats below to see why we really don't
+       like colons in filenames when passing filenames to ClamAV. */
+@@ -1347,45 +1401,72 @@
+ 	return DEFER;
+       }
+ 
+-      /* socket does not start with '/' -> network socket */
+-      if (*clamd_options != '/') {
++      /* We have some network servers specified */
++      if (num_servers) {
+ 
+         /* Confirmed in ClamAV source (0.95.3) that the TCPAddr option of clamd
+          * only supports AF_INET, but we should probably be looking to the
+          * future and rewriting this to be protocol-independent anyway. */
+ 
+-        /* 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;
+-        };
++        while ( num_servers > 0 ) {
++          /* Randomly pick a server to start with */
++          current_server = random_number( num_servers );
++
++          debug_printf("trying server name %s, port %u\n",
++                       clamd_address_vector[current_server]->tcp_addr,
++                       clamd_address_vector[current_server]->tcp_port);
++
++          /* Lookup the host. This is to ensure that we connect to the same IP
++           * on both connections (as one host could resolve to multiple ips) */
++          if((he = gethostbyname(CS clamd_address_vector[current_server]->tcp_addr))
++                          == 0) {
++            log_write(0, LOG_MAIN|LOG_PANIC,
++                    "malware acl condition: clamd: failed to lookup host '%s'",
++                    clamd_address_vector[current_server]->tcp_addr
++                    );
++            goto try_next_server;
++          }
+ 
+-        /* 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];
+ 
+-        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));
++            goto try_next_server;
++          }
+ 
+-        /* 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),
++                          clamd_address_vector[current_server]->tcp_port,
++                          5 ) > -1) {
++            /* Connection successfully established with a server */
++            hostname = clamd_address_vector[current_server]->tcp_addr;
++            break;
++          } else {
++            log_write(0, LOG_MAIN|LOG_PANIC,
++               "malware acl condition: clamd: connection to %s, port %u failed (%s)",
++               clamd_address_vector[current_server]->tcp_addr,
++               clamd_address_vector[current_server]->tcp_port,
++               strerror(errno));
+ 
+-        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;
++            (void)close(sock);
++          }
++
++try_next_server:
++          /* Remove the server from the list. XXX We should free the memory */
++          num_servers--;
++          int i;
++          for( i = current_server; i < num_servers; i++ )
++            clamd_address_vector[i] = clamd_address_vector[i+1];
+         }
+ 
++        if ( num_servers == 0 ) {
++          log_write(0, LOG_MAIN|LOG_PANIC, "malware acl condition: all clamd servers failed");
++            return DEFER;
++        }
+       } else {
+         /* open the local socket */
+         if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
================================================================

---- CVS-web:
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/packages/exim/exim.spec?r1=1.331&r2=1.332&f=u



More information about the pld-cvs-commit mailing list