aboutsummaryrefslogtreecommitdiff
path: root/mail/exim
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@FreeBSD.org>2014-11-04 16:14:30 +0000
committerVsevolod Stakhov <vsevolod@FreeBSD.org>2014-11-04 16:14:30 +0000
commit29e213fecefac1ee28002d5280203b6458dde1a4 (patch)
tree4b3e09865beaa46403e6d0843554f24c904e5db1 /mail/exim
parentcae6212aec4bf076fae54c306d2f193eb9ed0f87 (diff)
Notes
Diffstat (limited to 'mail/exim')
-rw-r--r--mail/exim/Makefile2
-rw-r--r--mail/exim/files/extra-patch-kas886
-rw-r--r--mail/exim/options3
3 files changed, 1 insertions, 890 deletions
diff --git a/mail/exim/Makefile b/mail/exim/Makefile
index 66c77df60f93..347efc595aa3 100644
--- a/mail/exim/Makefile
+++ b/mail/exim/Makefile
@@ -49,8 +49,6 @@ EMBEDDED_PERL_USE= perl5=run,build
EXIMON_USE= xorg=x11,xaw,xt
GNUTLS_LIB_DEPENDS= libgnutls.so:${PORTSDIR}/security/gnutls
ICONV_USES= iconv:lib,build
-KAS_BUILD_DEPENDS= libspamtest>=0:${PORTSDIR}/mail/libspamtest
-KAS_EXTRA_PATCHES= ${FILESDIR}/extra-patch-kas
MYSQL_USE= mysql=yes
OPENLDAP_USE= openldap=yes
PGSQL_USE= pgsql=yes
diff --git a/mail/exim/files/extra-patch-kas b/mail/exim/files/extra-patch-kas
deleted file mode 100644
index 19048398e5a1..000000000000
--- a/mail/exim/files/extra-patch-kas
+++ /dev/null
@@ -1,886 +0,0 @@
---- src/EDITME 2007-01-22 16:29:54.000000000 +0000
-+++ src/EDITME 2009-07-24 13:46:01.000000000 +0000
-@@ -1133,4 +1133,9 @@
-
- # ENABLE_DISABLE_FSYNC=yes
-
-+CFLAGS= -I/usr/local/ap-mailfilter3/include
-+EXTRALIBS_EXIM=-L/usr/local/ap-mailfilter3/lib -lspamtest
-+LOCAL_SCAN_SOURCE=Local/kas_exim.c
-+LOCAL_SCAN_HAS_OPTIONS=yes
-+
- # End of EDITME for Exim 4.
---- /dev/null 2009-07-24 13:44:23.000000000 +0000
-+++ Local/kas_exim.c 2009-07-24 13:42:28.000000000 +0000
-@@ -0,0 +1,871 @@
-+
-+#include "local_scan.h"
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <stdarg.h>
-+#include <fcntl.h>
-+#include <sys/types.h>
-+#include <syslog.h>
-+#include <sys/stat.h>
-+#include <errno.h>
-+#include "spamtest.h"
-+#include "msgstore.h"
-+
-+//#define SPAMTEST_USE_SYSLOG
-+
-+/* Default values for configuration options */
-+#define KAS_CONNECT_TIMEOUT 60000
-+#define KAS_DEFAULT_DOMAIN ""
-+#define KAS_LOG_LEVEL 0
-+#define KAS_ON_ERROR "tempfail"
-+#define KAS_DATA_TIMEOUT 60000
-+#define KAS_CONNECT_TO "tcp:127.0.0.1:2277"
-+#define KAS_FILTERING_SIZE_LIMIT 512
-+
-+/* Result variables for configuration options */
-+static uschar *result_default_domain;
-+static uschar *result_connect_to;
-+static uschar *result_on_error_str;
-+static int result_on_error;
-+
-+/* Configuration options */
-+//old
-+static int st_connect_timeout = 0;
-+static int debug_level = 0;
-+static int st_rw_timeout = 0;
-+static int filtering_size_limit=0;
-+static uschar *st_mail_domain;
-+static uschar *st_on_error;
-+static uschar *st_address;
-+//new
-+static int kas_connect_timeout = 0;
-+static int kas_log_level = 0;
-+static int kas_data_timeout = 0;
-+static int kas_filtering_size_limit = 0;
-+static uschar *kas_default_domain;
-+static uschar *kas_on_error;
-+static uschar *kas_connect_to;
-+
-+optionlist local_scan_options[] =
-+{/* The entries must appear in alphabetical order */
-+ { "connect_timeout", opt_int, &st_connect_timeout },
-+ { "kas_connect_timeout", opt_int, &kas_connect_timeout },
-+ { "kas_connect_to", opt_stringptr, &kas_connect_to },
-+ { "kas_data_timeout", opt_int, &kas_data_timeout },
-+ { "kas_default_domain", opt_stringptr, &kas_default_domain },
-+ { "kas_filtering_size_limit", opt_int, &kas_filtering_size_limit },
-+ { "kas_log_level",opt_int,&kas_log_level},
-+ { "kas_on_error",opt_stringptr,&kas_on_error},
-+ { "local_mail_domain", opt_stringptr, &st_mail_domain },
-+ { "log_level",opt_int,&debug_level},
-+ { "on_spamtest_error",opt_stringptr,&st_on_error},
-+ { "rw_timeout", opt_int, &st_rw_timeout },
-+ { "spamtest_address", opt_stringptr, &st_address },
-+ { "spamtest_filtering_size_limit", opt_int, &filtering_size_limit },
-+};
-+
-+int local_scan_options_count = sizeof(local_scan_options)/sizeof(optionlist);
-+
-+
-+int check_results(spamtest_session_t *s,spamtest_status_t *status,int *res,int fd,uschar **return_text);
-+int proceed_accept(spamtest_status_t *status,int fd);
-+void logger(const int log_level,const char *fmt,...);
-+void prepare_config_parameters();
-+void free_conf();
-+
-+
-+int local_scan(int fd, uschar **return_text)
-+{
-+ int myfd;
-+ char buf[4096];
-+ int cnt = 0;
-+ int totalcnt = 0;
-+ int i;
-+ header_line * tmp;
-+ spamtest_session_t s;
-+ int errorcode = STS_ERR_NO_ERR;
-+ spamtest_status_t *status = NULL;
-+ int rcpt_sent = 0;
-+ int res = 0;
-+ int rest = 0;
-+ char *ctmp;
-+
-+ /* Initialize spamtest session */
-+
-+ prepare_config_parameters();
-+
-+ if(filtering_size_limit > 0)
-+ {
-+ struct stat sb;
-+ fstat(fd,&sb);
-+ if(sb.st_size > filtering_size_limit * 1024)
-+ {
-+ logger(LOG_DEBUG," Message larger than filtering_size_limit, accepting");
-+ free_conf();
-+ return LOCAL_SCAN_ACCEPT;
-+ }
-+ }
-+
-+ bzero(&s,sizeof(s));
-+ s.access_address = result_connect_to;
-+ s.rw_timeout = st_rw_timeout;
-+ s.connect_timeout = st_connect_timeout;
-+ s.mail_domain = result_default_domain;
-+
-+ if ( s.access_address == NULL || s.access_address[0] == '\0' )
-+ {
-+ logger(LOG_ERR," Spamtest access address not defined, cannot process mail by spam filtering");
-+ free_conf();
-+ return LOCAL_SCAN_ACCEPT;
-+ }
-+
-+ logger(LOG_DEBUG," Spam test session: %s %s %d %d",s.access_address,s.mail_domain,s.connect_timeout,s.rw_timeout);
-+
-+ if ( (errorcode = sts_init(&s)) < 0 )
-+ {
-+ logger(LOG_ERR," Unable to connect to %s (%s)",s.access_address,sts_strerror(errorcode));
-+ free_conf();
-+ return result_on_error;
-+ };
-+
-+ if ( ! s.should_store_message )
-+ {
-+ /* SMTP mode, blackholing message because filter will send message */
-+ logger(LOG_ERR," Filter in SMTP mode, Incorrect situation.");
-+ //recipients_count = 0;
-+ sts_close(&s);
-+ free_conf();
-+ return result_on_error;
-+ }
-+
-+ if ( sender_address != NULL && sender_address[0] != '\0' )
-+ {
-+ if ( (errorcode = sts_set_sender(&s,sender_address)) != STS_ERR_NO_ERR )
-+ {
-+ logger(LOG_ERR," Unable to pass sender address %s(%d)",sender_address,errorcode);
-+ free_conf();
-+ return result_on_error;
-+ }
-+ }
-+
-+ if ( sender_host_address != NULL && sender_host_address[0] != '\0' )
-+ {
-+ if ( ( errorcode = sts_set_relay(&s,sender_host_address) ) != STS_ERR_NO_ERR )
-+ {
-+ logger(LOG_ERR," Unable to pass relay IP");
-+ if(errorcode == STS_ERR_OUT_OF_MEMORY){
-+ free_conf();
-+ return result_on_error;
-+ }
-+ }
-+ }
-+
-+ rcpt_sent = 0;
-+ for ( i = 0;i<recipients_count;i++)
-+ {
-+ if ( recipients_list[i].address != NULL && recipients_list[i].address[0] != '\0' )
-+ {
-+ if ( ( errorcode = sts_add_recipient(&s,recipients_list[i].address) ) != STS_ERR_NO_ERR )
-+ {
-+ logger(LOG_ERR," Unable to pass recipient '%s' to filter",recipients_list[i].address);
-+ }
-+ else
-+ {
-+ rcpt_sent++;
-+ }
-+ }
-+ }
-+ if ( rcpt_sent == 0 )
-+ {
-+ logger(LOG_DEBUG," Recipients not sent to filter. Continue.");
-+ }
-+
-+ tmp = header_list;
-+ while ( tmp != NULL )
-+ {
-+ if(tmp->type != '*')
-+ {
-+ logger(LOG_DEBUG,"Iterating a , %c %d %s|%d",tmp->type,tmp->slen,tmp->text,tmp->text[tmp->slen-1]);
-+ if ( ( status = sts_send_body(&s,tmp->text,tmp->slen,STS_REINIT_TIMEOUT) ) == NULL )
-+ {
-+ /* failure. finish proceed */
-+ logger(LOG_ERR," NULL status after sending header %s",tmp->text);
-+ sts_close(&s);
-+ }
-+ else
-+ { /* check status and finish if need */
-+ logger(LOG_DEBUG," header %s sent to filter",tmp->text);
-+ if ( check_results(&s,status,&res,fd,return_text) > 0 ){
-+ free_conf();
-+ return res;
-+ }
-+ }
-+ }
-+ if(tmp==header_last)
-+ break;
-+ tmp = tmp->next;
-+ }
-+
-+ logger(LOG_DEBUG," Headers sent");
-+
-+ if ( ( status = sts_send_body(&s,"\n",1,STS_REINIT_TIMEOUT) ) == NULL )
-+ {
-+ /* failure. finish proceed */
-+ logger(LOG_ERR," NULL status after sending empty string(end of headers)");
-+ sts_close(&s);
-+ }
-+ else
-+ { /* check status and finish if need */
-+ logger(LOG_DEBUG," empty string (end of headers) sent to filter");
-+ if ( check_results(&s,status,&res,fd,return_text) > 0 ){
-+ free_conf();
-+ return res;
-+ }
-+ }
-+
-+ logger(LOG_DEBUG," Enter sent");
-+
-+ i = 0;
-+ ctmp = buf;
-+ while ( (cnt = read(fd,ctmp,buf + sizeof(buf) - ctmp)) > 0 )
-+ {
-+ logger(LOG_DEBUG,"sending %d bytes to filter",cnt);
-+ status = sts_send_body(&s,buf,cnt,STS_REINIT_TIMEOUT);
-+ logger(LOG_DEBUG,"send");
-+ if ( status == NULL )
-+ {
-+ // failure. finish proceed
-+ logger(LOG_ERR," NULL status after sending part of body");
-+ sts_close(&s);
-+ }
-+ else
-+ { // check status and finish if need
-+ logger(LOG_DEBUG," part of body sent to filter");
-+ if ( check_results(&s,status,&res,fd,return_text) > 0 ){
-+ free_conf();
-+ return res;
-+ }
-+ }
-+ };
-+
-+ logger(LOG_DEBUG," Total sent %d bytes of message",totalcnt);
-+
-+ status = sts_body_end(&s,STS_FLUSH_DATA);
-+ logger(LOG_DEBUG," Body sent");
-+
-+
-+ if ( check_results(&s,status,&res,fd,return_text) > 0 ){
-+ free_conf();
-+ return res;
-+ }
-+ else
-+ sts_close(&s);
-+
-+ logger(LOG_DEBUG," EOF");
-+
-+ free_conf();
-+ return LOCAL_SCAN_ACCEPT;
-+
-+}
-+
-+
-+int check_results(spamtest_session_t *s,spamtest_status_t *status,int *res,int fd,uschar **return_text)
-+{
-+ logger(LOG_DEBUG," Check results started.");
-+ switch ( status->status )
-+ {
-+ case STS_SMTP_ACCEPT:
-+ case STS_BLACKHOLE:
-+ logger(LOG_DEBUG," SMTP_ACCEPT or BLACK_HOLE.");
-+ recipients_count = 0;
-+ sts_close(s);
-+ *res = LOCAL_SCAN_ACCEPT;
-+ return 1;
-+ case STS_REJECT:
-+ logger(LOG_DEBUG," REJECT");
-+ *return_text=(uschar *)status->reason;
-+ sts_close(s);
-+ *res = LOCAL_SCAN_REJECT;
-+ return 1;
-+ case STS_FILTER_ERROR:
-+ logger(LOG_DEBUG," FILTER_ERROR");
-+ sts_close(s);
-+ *res = result_on_error;
-+ return 1;
-+ case STS_ACCEPT:
-+ logger(LOG_DEBUG," ACCEPT");
-+ if ( proceed_accept(status,fd) != 0 )
-+ *res = result_on_error;
-+ else
-+ *res = LOCAL_SCAN_ACCEPT;
-+ sts_close(s);
-+ return 1;
-+ case STS_CONTINUE:
-+ logger(LOG_DEBUG," CONTINUE");
-+ return 0;
-+ }
-+
-+}
-+
-+extern int recipients_list_max;
-+int proceed_accept(spamtest_status_t *status,int fd)
-+{
-+ spamtest_status_t *st;
-+ message_status_t *mst;
-+ int i;
-+ int rcptn;
-+ int good_rcpt_cnt = 0,k;
-+ int found = 0;
-+
-+ logger(LOG_DEBUG," accept_message started.");
-+
-+ st = glue_actions(status);
-+
-+ if (st==NULL) {
-+ logger(LOG_ERR," glue_actions return NULL" );
-+ return -1;
-+ }
-+
-+ mst = &st->ms_array[0] ;
-+
-+ rcptn = rcptlist_count(mst->rcpts);
-+ for( k=0; k<rcptn; k++)
-+ if(strlen(rcptlist_getn(mst->rcpts, k))>0)
-+ good_rcpt_cnt++;
-+ if(good_rcpt_cnt <1)
-+ {
-+ logger(LOG_INFO," Empty recipient list");
-+ recipients_count = 0;
-+ return 0;
-+ }
-+
-+ if ( (mst != NULL) && (mst->action == STS_ACTION_CHANGE) )
-+ {
-+ logger(LOG_DEBUG," spamtest status returned STS_ACTION_CHANGE for message.");
-+
-+ // cleanup old rcpts list
-+ recipients_count = 0;
-+ recipients_list = NULL;
-+ recipients_list_max = 0;
-+ for (i = 0; i<rcptlist_count(mst->rcpts);i++)
-+ {
-+ char *rcpt = rcptlist_getn(mst->rcpts,i);
-+ if(rcpt)
-+ {
-+ logger(LOG_DEBUG,"Adding recipient: %s",rcpt);
-+ receive_add_recipient(string_copy(US rcpt),-1);
-+ }
-+ }
-+
-+ logger(LOG_DEBUG," new recipients_count=%d",recipients_count);
-+
-+ if ( sender_address[0] != '\0' )
-+ {
-+ if (strcasecmp(mst->mailfrom,sender_address) != 0 )
-+ { /* changing sender address */
-+ logger(LOG_DEBUG," senders different");
-+ sender_address = string_copy( US mst->mailfrom );
-+ }
-+ else
-+ {
-+ logger(LOG_DEBUG," senders equivalented");
-+ }
-+ }
-+ logger(LOG_DEBUG," Actions count = %d",mst->action_count);
-+ for (i=0;i<mst->action_count;i++)
-+ {
-+ header_line * tmp;
-+ header_line * matched;
-+ header_line * last;
-+ int deleted_count = 0;
-+ int matched_count = 0;
-+ int hdrlen = strlen(mst->act_array[i].header);
-+
-+ switch ( mst->act_array[i].type )
-+ {
-+ case STS_HEADER_DEL:
-+ logger(LOG_DEBUG," Delete header %s",mst->act_array[i].header);
-+ tmp = header_list;
-+ while ( tmp != NULL )
-+ {
-+ if ( (tmp->type != '*') &&
-+ (tmp->slen > 0) &&
-+ (strncasecmp(tmp->text,
-+ mst->act_array[i].header,
-+ hdrlen < tmp->slen ? hdrlen:tmp->slen) == 0 )
-+ )
-+ {
-+ deleted_count++;
-+ tmp->type = '*';
-+ }
-+ tmp = tmp->next;
-+ }
-+ logger(LOG_DEBUG," deleted %d headers",deleted_count);
-+ break;
-+ case STS_HEADER_ADD:
-+ logger(LOG_DEBUG," Add value to header %s %s",mst->act_array[i].header,mst->act_array[i].value);
-+ tmp = header_list;
-+ matched = NULL;
-+ while ( tmp != NULL )
-+ {
-+ logger(LOG_DEBUG,"Iterating, %c %d %s",tmp->type,tmp->slen,tmp->text);
-+ if ( (tmp->slen > 0) &&
-+ (strncasecmp(tmp->text,
-+ mst->act_array[i].header,
-+ hdrlen < tmp->slen ? hdrlen:tmp->slen) == 0 )
-+ )
-+ {
-+ if ( matched != NULL )
-+ {
-+ if ( (tmp->type != '*') || ( matched->type == '*' ) )
-+ matched = tmp;
-+ }
-+ else
-+ {
-+ matched = tmp;
-+ }
-+ }
-+ tmp = tmp->next;
-+ if(matched)
-+ break;
-+ }
-+ if ( matched != NULL )
-+ { /* adding value to exits header */
-+ logger(LOG_DEBUG,"Found matched header, %c %d %s",matched->type,matched->slen,matched->text);
-+ if ( matched->type == '*' )
-+ {
-+ matched->text = string_sprintf("%s: %s\n",mst->act_array[i].header,mst->act_array[i].value);
-+ matched->slen = strlen(matched->text);
-+ matched->type = ' ';
-+ matched->type = header_checkname(matched,0);
-+ }
-+ else
-+ {
-+ logger(LOG_DEBUG,"Appending value to existing header value");
-+ matched->text = string_sprintf("%s %s\n",matched->text,mst->act_array[i].value);
-+ matched->slen += (strlen(mst->act_array[i].value) + 2);
-+ }
-+ }
-+ else
-+ { /* add new header in case when this header not found */
-+ logger(LOG_DEBUG," We must add value to header %s but this header not found.",mst->act_array[i].header);
-+ header_add(' ',"%s: %s\n",mst->act_array[i].header,mst->act_array[i].value);
-+ }
-+ logger(LOG_DEBUG," Add header %s %s",mst->act_array[i].header,mst->act_array[i].value);
-+ break;
-+
-+
-+ case STS_HEADER_PREPEND:
-+ logger(LOG_DEBUG," Prepend value to header %s %s",mst->act_array[i].header,mst->act_array[i].value);
-+ tmp = header_list;
-+ matched = NULL;
-+ while ( tmp != NULL )
-+ {
-+ logger(LOG_DEBUG,"Iterating, %c %d %s",tmp->type,tmp->slen,tmp->text);
-+ if ( (tmp->slen > 0) &&
-+ (strncasecmp(tmp->text,
-+ mst->act_array[i].header,
-+ hdrlen < tmp->slen ? hdrlen:tmp->slen) == 0 )
-+ )
-+ {
-+ if ( matched != NULL )
-+ {
-+ if ( (tmp->type != '*') || ( matched->type == '*' ) )
-+ matched = tmp;
-+ }
-+ else
-+ {
-+ matched = tmp;
-+ }
-+ }
-+ tmp = tmp->next;
-+ if(matched)
-+ break;
-+ }
-+ if ( matched != NULL )
-+ { /* adding value to exits header */
-+ logger(LOG_DEBUG,"Found matched header, %c %d %s",matched->type,matched->slen,matched->text);
-+ if ( matched->type == '*' )
-+ {
-+ matched->text = string_sprintf("%s: %s\n",mst->act_array[i].header,mst->act_array[i].value);
-+ matched->slen = strlen(matched->text);
-+ matched->type = ' ';
-+ matched->type = header_checkname(matched,0);
-+ }
-+ else
-+ {
-+ int l = strlen(mst->act_array[i].header);
-+ char *p = matched->text+l+2;
-+ matched->text[l]=0;
-+ matched->text = string_sprintf("%s: %s %s",matched->text,
-+ mst->act_array[i].value,p);
-+ matched->slen += (strlen(mst->act_array[i].value) + 1);
-+ logger(LOG_DEBUG,"Prepending value %s to existing header value %s|",
-+ mst->act_array[i].value, matched->text);
-+
-+ }
-+ }
-+ else
-+ { /* add new header in case when this header not found */
-+ logger(LOG_DEBUG," We must add value to header %s but this header not found.",mst->act_array[i].header);
-+ header_add(' ',"%s: %s\n",mst->act_array[i].header,mst->act_array[i].value);
-+ }
-+ logger(LOG_DEBUG," Prepend header %s %s",mst->act_array[i].header,mst->act_array[i].value);
-+ break;
-+
-+ case STS_HEADER_CHG:
-+ logger(LOG_DEBUG," Change header %s %s",mst->act_array[i].header,mst->act_array[i].value);
-+ tmp = header_list;
-+ matched = NULL;
-+ matched_count = 0;
-+ while ( tmp != NULL )
-+ {
-+ int hdrlen = strlen(mst->act_array[i].header);
-+ if ( (tmp->type != '*') &&
-+ (tmp->slen > 0) &&
-+ (strncasecmp(tmp->text,
-+ mst->act_array[i].header,
-+ hdrlen < tmp->slen ? hdrlen:tmp->slen) == 0 )
-+ )
-+ {
-+ matched = tmp;
-+ matched_count++;
-+ }
-+ tmp = tmp->next;
-+ }
-+ if ( matched != NULL )
-+ {
-+ matched->text = string_sprintf("%s: %s\n",mst->act_array[i].header,mst->act_array[i].value);
-+ matched->slen += (strlen(mst->act_array[i].value) + strlen(mst->act_array[i].header) + 3);
-+ if ( matched_count > 1 )
-+ {
-+ tmp = header_list;
-+ while ( (tmp != NULL) && matched_count > 1 )
-+ {
-+ if ( (tmp->type != '*') &&
-+ (tmp->slen > 0) &&
-+ (strncasecmp(tmp->text,
-+ mst->act_array[i].header,
-+ hdrlen < tmp->slen ? hdrlen:tmp->slen) == 0 ) &&
-+ (tmp != matched)
-+ )
-+ {
-+ tmp->type = '*';
-+ matched_count--;
-+ }
-+ tmp = tmp->next;
-+ }
-+ }
-+
-+ }
-+ else
-+ {
-+ logger(LOG_DEBUG," We must change value for header %s but this header not found.Adding new",mst->act_array[i].header);
-+ header_add(' ',"%s: %s\n",mst->act_array[i].header,mst->act_array[i].value);
-+ }
-+ break;
-+ case STS_HEADER_NEW:
-+ logger(LOG_DEBUG," New header %s: %s",mst->act_array[i].header,mst->act_array[i].value);
-+
-+ tmp = header_list;
-+ matched = NULL;
-+ while ( tmp != NULL )
-+ {
-+ if ( (tmp->type != '*') &&
-+ (tmp->slen > 0) &&
-+ (strncasecmp(tmp->text,
-+ mst->act_array[i].header,
-+ hdrlen < tmp->slen ? hdrlen:tmp->slen) == 0 )
-+ )
-+ {
-+ matched = tmp;
-+ }
-+ tmp = tmp->next;
-+ }
-+ if ( matched != NULL && matched != header_last )
-+ {
-+ if(matched == header_last)
-+ {
-+ logger(LOG_DEBUG,"Header %s is last in message, adding below",
-+ mst->act_array[i].header);
-+ header_add(' ',"%s: %s\n",mst->act_array[i].header,mst->act_array[i].value);
-+ }
-+ else
-+ { /* adding value after last header with this name */
-+ logger(LOG_DEBUG,"Some headers %s found",mst->act_array[i].header);
-+ tmp = header_last;
-+ header_add(' ',"%s: %s\n",mst->act_array[i].header,mst->act_array[i].value);
-+ tmp->next->next = matched->next;
-+ matched->next = tmp->next;
-+ tmp->next = NULL;
-+ header_last = tmp;
-+ }
-+ }
-+ else
-+ { /* add new header at the end of headers list */
-+ logger(LOG_DEBUG,"Headers %s not found",mst->act_array[i].header);
-+ header_add(' ',"%s: %s\n",mst->act_array[i].header,mst->act_array[i].value);
-+ }
-+
-+ break;
-+ default:
-+ logger(LOG_INFO," Invalid action type %d",mst->act_array[i].type);
-+ }
-+ }
-+ }
-+ else if ( (mst != NULL) && (mst->action == STS_ACTION_BOUNCE) )
-+ { /* bounce message */
-+ header_line *tmp;
-+ message_t *bounced_mess;
-+
-+ logger(LOG_DEBUG," bouncing message.");
-+
-+ /* preparing bounced message */
-+ bounced_mess = message_init();
-+ if ( bounced_mess == NULL )
-+ {
-+ logger(LOG_ERR," Unable to allocate memory for bounced message");
-+ return -1;
-+ }
-+ logger(LOG_DEBUG," new message allocated.");
-+
-+ /* copying data from filter to prepared message (for automatically creating headers list ) */
-+ for (i=0;i<msgtext_count_chunks(mst->bouncemsg);i++ )
-+ {
-+ if ( message_put_body(bounced_mess,msgtext_get_chunk(mst->bouncemsg,i),msgtext_chunk_len(mst->bouncemsg,i)) == -1 )
-+ {
-+ logger(LOG_ERR," unable to copy data from filter to bounced message");
-+ message_free(bounced_mess);
-+ return -1;
-+ }
-+ else
-+ {
-+ logger(LOG_DEBUG," message_put_body - ok.");
-+ }
-+ }
-+
-+ /* deleting exim old headers */
-+ tmp = header_list;
-+ while ( tmp != NULL )
-+ {
-+ tmp->type = '*';
-+ tmp = tmp->next;
-+ };
-+ logger(LOG_DEBUG," headers deleted.");
-+
-+ /* adding new headers */
-+ for ( i = 0;i < bounced_mess->headers->used; i++ )
-+ {
-+ header_add(' ',"%s: %s",bounced_mess->headers->array[i].header.hptr,bounced_mess->headers->array[i].value.hptr);
-+ logger(LOG_DEBUG," added header: %s: %s",bounced_mess->headers->array[i].header.hptr,bounced_mess->headers->array[i].value.hptr);
-+ }
-+
-+ /* replacing rcpts */
-+ recipients_count = 0;
-+ recipients_list = NULL;
-+ recipients_list_max = 0;
-+
-+ if ( rcptlist_count(bounced_mess->recipients) > 0 )
-+ {
-+ for (i = 0; i<rcptlist_count(bounced_mess->recipients);i++)
-+ {
-+ char *rcpt = rcptlist_getn(bounced_mess->recipients,i);
-+ if ( rcpt == NULL )
-+ {
-+ logger(LOG_ERR," unable to get recipient %d",i);
-+ message_free(bounced_mess);
-+ return -1;
-+ }
-+ logger(LOG_DEBUG," rcpt = %s",rcpt);
-+ receive_add_recipient(string_copy(US rcpt),-1);
-+ }
-+ }
-+ else
-+ {
-+ if ( sender_address[0] != '\0' )
-+ receive_add_recipient(string_copy(US sender_address),-1);
-+ else
-+ {
-+ logger(LOG_ERR," Unable to get sender address to bounce, failed");
-+ return -1;
-+ }
-+ }
-+ /* cleaning sender ( must be empty string ) */
-+ logger(LOG_DEBUG," sender address emptied");
-+ sender_address = "";
-+
-+ /* writing new message body */
-+ lseek(fd,SPOOL_DATA_START_OFFSET,SEEK_SET);
-+
-+ if ( get_message_bodychunks_count(bounced_mess) > 0 )
-+ {
-+ for (i=0;i<get_message_bodychunks_count(bounced_mess);i++ )
-+ {
-+ if ( write(fd,get_message_bodychunk_ptr(bounced_mess,i),get_message_bodychunk_len(bounced_mess,i)) == -1 )
-+ {
-+ logger(LOG_ERR," unable to write bounced message body.");
-+ message_free(bounced_mess);
-+ return -1;
-+ }
-+ else
-+ {
-+ logger(LOG_DEBUG," written part of body to file");
-+ }
-+ }
-+ }
-+ else
-+ {
-+ char *autogenmsg = "Autogenerated message for bouncing\n\n\n";
-+ if ( write(fd,autogenmsg,strlen(autogenmsg)) == -1 )
-+ {
-+ logger(LOG_ERR," unable to write bounced message body.");
-+ message_free(bounced_mess);
-+ return -1;
-+ }
-+ else
-+ {
-+ logger(LOG_DEBUG," written autogenerated message to file");
-+ }
-+ }
-+
-+ message_free(bounced_mess);
-+ logger(LOG_DEBUG," bouncing finished");
-+
-+
-+ }
-+ else
-+ {
-+ if ( mst != NULL )
-+ logger(LOG_ERR," Invalid action %d",mst->action);
-+ else
-+ logger(LOG_ERR," mst is NULL");
-+ }
-+
-+ logger(LOG_DEBUG," Message accepted.");
-+ return 0;
-+
-+}
-+
-+
-+void logger(const int log_level,const char *fmt,...)
-+{
-+ va_list params;
-+ char buf[512];
-+ /* LOG_ERR == 3 is minimum level for us */
-+ if (log_level <= (debug_level+3))
-+ {
-+ va_start(params,fmt);
-+ vsnprintf(buf,(size_t)512,fmt,params);
-+ debug_printf("-ls- %s\n",buf);
-+#ifdef SPAMTEST_USE_SYSLOG
-+ va_start(params,fmt);
-+ vsyslog(log_level>LOG_DEBUG?LOG_DEBUG:log_level,fmt,params);
-+#else
-+ log_write(0,LOG_MAIN,"spamtest: %s",buf);
-+#endif
-+ va_end(params);
-+ }
-+}
-+
-+void prepare_config_parameters()
-+{
-+ int len;
-+ /*
-+ * Firstly we are looking for new parameter,
-+ * then - for old parameter, else - we use
-+ * default value.
-+ */
-+ if (kas_log_level != 0)
-+ debug_level = kas_log_level;
-+ if (debug_level == 0)
-+ debug_level = KAS_LOG_LEVEL;
-+
-+ if (kas_connect_timeout != 0)
-+ st_connect_timeout = kas_connect_timeout*1000;
-+ if (st_connect_timeout == 0)
-+ st_connect_timeout = KAS_CONNECT_TIMEOUT;
-+
-+ if (kas_data_timeout != 0)
-+ st_rw_timeout = kas_data_timeout*1000;
-+ if (st_rw_timeout == 0)
-+ st_rw_timeout = KAS_DATA_TIMEOUT;
-+
-+ if (kas_filtering_size_limit != 0)
-+ filtering_size_limit = kas_filtering_size_limit;
-+ if (filtering_size_limit == 0)
-+ filtering_size_limit = KAS_FILTERING_SIZE_LIMIT;
-+
-+
-+ if (kas_default_domain != NULL){
-+ len = strlen(kas_default_domain);
-+ result_default_domain = malloc(len+1);
-+ strncpy(result_default_domain,kas_default_domain,len);
-+ result_default_domain[len]='\0';
-+ }
-+ else if (st_mail_domain != NULL){
-+ len = strlen(st_mail_domain);
-+ result_default_domain = malloc(len+1);
-+ strncpy(result_default_domain,st_mail_domain,len);
-+ result_default_domain[len]='\0';
-+ }
-+ else{
-+ len = strlen(KAS_DEFAULT_DOMAIN);
-+ result_default_domain = malloc(len+1);
-+ strncpy(result_default_domain,KAS_DEFAULT_DOMAIN,len);
-+ result_default_domain[len]='\0';
-+ }
-+
-+ if (kas_connect_to != NULL){
-+ len = strlen(kas_connect_to);
-+ result_connect_to = malloc(len+1);
-+ strncpy(result_connect_to,kas_connect_to,len);
-+ result_connect_to[len]='\0';
-+ }
-+ else if (st_address != NULL){
-+ len = strlen(st_address);
-+ result_connect_to = malloc(len+1);
-+ strncpy(result_connect_to,st_address,len);
-+ result_connect_to[len]='\0';
-+ }/* one parameter have no default,
-+ * because else we can't disable kas-exim in config file*/
-+
-+ if (kas_on_error != NULL){
-+ len = strlen(kas_on_error);
-+ result_on_error_str = malloc(len+1);
-+ strncpy(result_on_error_str,kas_on_error,len);
-+ result_on_error_str[len]='\0';
-+ }
-+ else if (st_on_error != NULL){
-+ len = strlen(st_on_error);
-+ result_on_error_str = malloc(len+1);
-+ strncpy(result_on_error_str,st_on_error,len);
-+ result_on_error_str[len]='\0';
-+ }
-+ else{
-+ len = strlen(KAS_ON_ERROR);
-+ result_on_error_str = malloc(len+1);
-+ strncpy(result_on_error_str,KAS_ON_ERROR,len);
-+ result_on_error_str[len]='\0';
-+ }
-+
-+ if ( strcasecmp(result_on_error_str,"accept") == 0 ){
-+ result_on_error = LOCAL_SCAN_ACCEPT;
-+ }
-+ else if ( strcasecmp(result_on_error_str,"reject") == 0 ){
-+ result_on_error = LOCAL_SCAN_REJECT;
-+ }
-+ else if ( strcasecmp(result_on_error_str,"tempfail") == 0 ){
-+ result_on_error = LOCAL_SCAN_TEMPREJECT;
-+ }
-+ else{
-+ logger(LOG_ERR,"Invalid value for parameter on_spamtest_error. Will use 'accept'");
-+ result_on_error = LOCAL_SCAN_ACCEPT;
-+ }
-+}
-+
-+void free_conf(){
-+ free(result_default_domain);
-+ free(result_connect_to);
-+ free(result_on_error_str);
-+}
-+
diff --git a/mail/exim/options b/mail/exim/options
index edc8d9d6bf0c..41389a16d759 100644
--- a/mail/exim/options
+++ b/mail/exim/options
@@ -50,7 +50,7 @@ OPTIONS_DEFAULT+= AUTH_CRAM_MD5 \
OPTIONS_RADIO_TLS= TLS GNUTLS
TLS_DESC= TLS support
-OPTIONS_RADIO_LS= SA_EXIM KAS
+OPTIONS_RADIO_LS= SA_EXIM
LS_DESC= Local scan patch
OPTIONS_RADIO_SRSR= SRS SRS_ALT
SRSR_DESC= Sender Rewriting Scheme
@@ -89,7 +89,6 @@ DSEARCH_DESC= Enable directory-list lookups
EMBEDDED_PERL_DESC= Enable embedded Perl interpreter
EXIMON_DESC= Build eximon monitor (requires X libraries)
ICONV_DESC= Enable header charset conversion
-KAS_DESC= Build with Kaspersky AntiSpam local scan
LISTMATCH_RHS_DESC= Enable pre-4.77 behaviour for match_*
LMTP_DESC= RFC2033 SMTP over command pipe transport
LSEARCH_DESC= Enable wildcarded-file lookups