Sisyphus repositório
Última atualização: 1 outubro 2023 | SRPMs: 18631 | Visitas: 37731592
en ru br
ALT Linux repositórios
S:8.16-alt1
5.0: 5.0.90-alt0.20090320.3
4.1: 5.0.90-alt0.20090320.0.M41.3
4.0: 4.0-alt2.M40.2

Group :: Sistema/Servidores
RPM: mailfromd

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs e FR  Repocop 

/* This file is part of mailfrom filter
Copyright (C) 2005, 2006 Sergey Poznyakoff

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA


This file is default configuration for mailfrom in Alt Linux.
It is targeted at Sendmail's configuration in ALT Linux. In other
distributions or with Postfix make sure what all needed MTA's
variables enabled for Milter.
Configuration modified by Sergey Afonin.
*/

#include_once <status.mfh>
require 'status'

require 'dns'
require 'match_cidr'
require 'rateok'
require 'poll'
require 'callout'

require 'sa'
require 'spf'

#pragma regex +extended +icase

set mailfrom_address ""

/*
Enable MTA-specific functions. Values:
sendmail - can be used
meta1 - not used now
postfix - not used now
*/
set mta ""

set graylistactive 0
set graylistused 0
set greylisted 0
set greylist_msg "Bad greylist processing. Call to postmaster, sorry"
set gltime interval("10 minutes")

set msg_header ""
set msg_header_last_received ""

set message_received_from ""

set mail_from ""
set rcpt_to ""
set queue_id ""
set queue_id_connect ""
set helo_from_remote ""

set virusmaster ""
set callback_chk_exclude "\n"
set massallocated_chk_exclude "\n"
set graylist_exclude "\n"
set explain_msg ""

set spam_verification_needed 0
set spamreject 0
set spammaster "spamalert@localhost"
set spamd_port ""
set explain_msg_spam ""
set X_Spam_Suffix ""
set cur_hostname ""

set ma_check 2
set spf_pass 0
set l2dom_pass 0

set bad_mail_from ".*\\|.*"
set good_relay "^((.*\\.)?(mx|mail|mta|relay|list|smtp|srv|server|dot|web|forward|backend|cgp).*\\..*)|(.*\\.(google|obsmtp|subscribe|yahoo|hotmail|mail|hp|depo)\\.(com|ru|fr)|ripe.net)$"
set not_verifiable_mx "(\\.mx\\.mail\\.yahoo\\.com|\\.namaeserver\\.com|\\.mail\\.ru|\\.gmx\\.com)$"

/* Note: ClamAV's Default - 25M */
set ClamdStreamMaxLength 25000000

set SpamAssassinStreamMaxLength 131072

#include_once </etc/mailfromd/localconf.mf>
#include_once </etc/mailfromd/userfunctions.mf>

prog connect
do
set queue_id_connect $i
set cur_hostname hostname(${client_addr})

if ma_check = 1
and
not match_cidr_list(${client_addr}, massallocated_chk_exclude) = 1
and
not dbmap("/etc/mailfromd/whitelist.db", "massallocated:" . $client_addr, 1)
and
not cur_hostname matches good_relay

set ma_hit_num massallocated_hit(${client_ptr}, massallocated_regexps)
echo "%queue_id: ma_hit_num:" . ma_hit_num

if ma_hit_num > 0
echo "%queue_id_connect: client's IP [" . ${client_ptr} . "]. Hit to R" . ma_hit_num . "."
reject
fi
fi
done

prog helo
do
# Save the helo of host for further use
set helo_from_remote $1
echo "%queue_id_connect: helo=" . helo_from_remote . " client_addr=" . ${client_addr}
done

prog envfrom
do
set queue_id $i

if not queue_id = queue_id_connect
echo "%queue_id_connect: new message with queue id: " . queue_id
fi

if mta = "sendmail"
access_db_check("/etc/mail/access.db", "connect:" . $client_addr)
access_db_check("/etc/mail/access.db", tolower("from:" . $f))
fi

whitelist_chk_global($client_addr, $f)

if not match_cidr(${client_addr}, "127.0.0.0/8")
and
helo_from_remote matches $j
echo "%queue_id: WARNING: helo matches local hostname: " . helo_from_remote . " " . $j . " " . ${client_addr}
fi

if not match_cidr(${client_addr}, "127.0.0.0/8")
and
cur_hostname matches "^localhost$"
echo "%queue_id: messages from localhost is not accepted"
reject 550 5.7.1 "messages from localhost is not accepted"
fi

set msg_header_last_received "Received: from " . helo_from_remote . " ("
. cur_hostname . " [" . ${client_addr} . "])\r\n\t"
. "by " . ehlo_domain . " (" . %__package__ . "/" . %__version__ . ") id " . $i . ";\r\n\t"
. strftime('%a, %d %b %Y %T %z (%Z)', time())

set message_received_from cur_hostname . " [" . ${client_addr} . "]"

set mail_from "<" . $f . ">"

if macro_defined("auth_authen")
echo "%queue_id: sender was authenticated as " . ${auth_authen}
if mta = "sendmail"
header_add("X-authenticated", "as \"" . ${auth_authen} . "\" on host \"" . $j . "\"", 0)
fi
continue
fi

if $f matches bad_mail_from
echo "%queue_id: bad mail from <$f>"
reject 550 5.1.0 "bad mail from <$f>"
fi

if ma_check = 2
and
not match_cidr_list(${client_addr}, massallocated_chk_exclude) = 1
and
not dbmap("/etc/mailfromd/whitelist.db", "massallocated:" . $client_addr, 1)
and
not cur_hostname matches good_relay

set ma_hit_num massallocated_hit(${client_ptr}, massallocated_regexps)
echo "%queue_id: ma_hit_num:" . ma_hit_num

if ma_hit_num > 0
reject 550 5.7.1
"Your reverse name is " . ${client_ptr}
. "\nAccess from pppoe/cable/e.t.c. relays denied, client's IP [" . ${client_addr} . "]. Hit to R" . ma_hit_num . ". " . explain_msg
fi

fi

if graylistused = 1
if cur_hostname = ${client_addr}
#pragma regex push -icase
if $f matches "[A-Z].*[A-Z].*@"
echo "%queue_id: relay [" . ${client_addr} . "] without reverce name and bad e-mail: " . $f
reject 550 5.7.1 "relay does not have a reverse name and you have bad e-mail"
else
echo "%queue_id: relay does not have a reverse name but possible good e-mail: " . $f
fi
#pragma regex pop
echo "%queue_id: relay does not have a reverse name, graylistactive set to 1."
set graylistactive 1
elif helo_from_remote matches "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$"
or
not helo_from_remote matches "\\."
or
helo_from_remote matches "localhost"
echo "%queue_id: bad helo, graylistactive set to 1."
set graylistactive 1
fi
fi

if not spamd_port = ""
if graylistactive = 1
or
cur_hostname = ${client_addr}
or
helo_from_remote matches "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$"
or
not helo_from_remote matches "\\."
or
helo_from_remote matches "localhost"
set SpamAssassinStreamMaxLength 1048576
fi
if not cur_hostname matches good_relay
echo "%queue_id: bad reverse name for smtp relay (" . cur_hostname . "), spam_verification_needed set to 1"
set spam_verification_needed 1
else
echo "%queue_id: smtp relay (" . cur_hostname . "), matches good_relay"
fi
fi

echo "%queue_id: mail from: " . $f

catch failure or e_temp_failure or e_io
do
echo "%queue_id: Caught exception: " . $2 . ", graylistactive set to 1."
set graylistactive 1
continue
done

switch check_host($client_addr, domainpart($f), $f, $s)
do
case Fail:
string text ""
if spf_explanation != ""
set text "%text\n%spf_explanation"
fi
reject 550 5.7.1 "SPF MAIL FROM check failed: %text"
case Pass:
echo "%queue_id: spf_mechanism: %spf_mechanism"
if spf_mechanism matches "\\+all"
echo "%queue_id: SPF check passed, but mechanism +all, so ignored"
elif spf_mechanism matches "ip4:.*\\/\(.*\)$" /* ip4:xxx.xxx.xxx.xxx/24 */
and
( \1 < 24 )
echo "%queue_id: SPF check passed, but CIDR is too small (/\1), so ignored"
else
set spam_verification_needed 0
set graylistactive 0
set spf_pass 1
echo "%queue_id: SPF check passed, graylist and Spamassassin are disabled"
fi
done

if cur_hostname matches "(.*\\.)?\([^\\.]*)\\.([^\\.]*\)$"
set l2dom ".*" . \2 . "\\\." . \3 . "\\\.?"
/* echo "%queue_id: PTR's L2 domain: %l2dom, sender: $f" */
if $f mx matches l2dom
set spam_verification_needed 0
set graylistactive 0
set l2dom_pass 1
echo "%queue_id: L2 domain of MX matches L2 domain of sender's relay, graylist and Spamassassin are disabled"
fi
fi

if $f = ""
or
dbmap("/etc/mailfromd/whitelist.db", "from:" . $client_addr, 1)
or
dbmap("/etc/mailfromd/whitelist.db", tolower("from:" . $client_addr . "-" . $f), 1)
or
dbmap("/etc/mailfromd/whitelist.db", tolower("from:" . $f), 1)
pass
elif $f mx matches "localhost"
echo "%queue_id: MX of sender is localhost, mail rejected"
reject 550 5.7.1 "MX of sender is localhost, mail rejected"
elif $f mx matches not_verifiable_mx
if graylistused = 1
and
spf_pass = 0
and
l2dom_pass = 0
echo "%queue_id: MX for $f is negative for smtp callback, so graylisted."
set graylistactive 1
fi
else
if match_cidr_list(${client_addr}, callback_chk_exclude) = 0
echo "%queue_id: callback process started"
on poll $f do
when success:
pass
echo "%queue_id: callback process passed"
when not_found:
if last_poll_recv = ""
if cache_used
/*
"not_found" placed to the cache when the MX is not responding
too. SMTP reply 5xx must not be returned at this case. This
behavior discovered in 7.99.92 (git 2012-03-21).
So, "reject" changed to "tempfail" temporary.
*/
/* reject 550 5.1.0 */
tempfail 450 4.7.1
"E-mail <" . $f . "> hasn't been confirmed by its MX, data has been cached in a previous attempt."
. "\nCache time " . n_cache_time . " sec since first attempt. Check a previous reject."
else
echo "%queue_id: last_poll_recv empty, \"" . $f . "\" is not in cache"
reject 550 5.1.0
"Unspecified error; E-mail <" . $f . "> can not be checked"
fi
else
reject 550 5.1.0
"Your MX replied \"" . last_poll_recv . "\""
. "\nE-mail <" . $f . "> from host [" . ${client_addr} ."] hasn't been confirmed by its MX \"" . last_poll_host . "\""
fi
when failure:
echo "%queue_id: last_poll_recv = " . last_poll_recv . " last_poll_host = " . last_poll_host
reject 550 5.1.0 "E-mail <" . $f . "> can't be verified, permanent error occurred"
when temp_failure:
if last_poll_recv = ""
tempfail 450 4.4.1 "E-mail <" . $f . "> hasn't been confirmed by its MX, MX does not respond"
elif last_poll_recv = "nothing"
tempfail 450 4.4.1
"Your MX not responded to some command. Possibly a long timeout."
. "\nE-mail <" . $f . "> hasn't been confirmed by its MX \"" . last_poll_host . "\""
else
tempfail 450 4.7.1
"Your MX replied \"" . last_poll_recv . "\""
. "\nE-mail <" . $f . "> hasn't been confirmed by its MX \"" . last_poll_host . "\""
fi
done
fi
fi

catch e_dbfailure
do
echo "%queue_id: RUNTIME ERROR in rateok, caught exception $1: $2"
stack_trace()
continue
done

if not rateok(tolower($f) . "-" . ${client_addr}, interval("1 hour 30 minutes"), 100, 90)
echo "%queue_id: WARNING: Too big rate for E-Mail:IP pair $f-${client_addr}"
/* tempfail 450 4.7.0 "Mail sending rate exceeded. Try again later" */
fi

done

prog envrcpt
do
set rcpt_to rcpt_to . $1 . "\r\n"
if graylistused = 1
and
graylistactive = 1
and
not dbmap("/etc/mailfromd/whitelist.db", "graylist:" . $client_addr, 1)
and
not match_cidr_list(${client_addr}, graylist_exclude) = 1
if greylist($client_addr . "-" . $f . "-" . $rcpt_addr, gltime)
set greylisted 1
if greylist_seconds_left = gltime
set greylist_msg "You are greylisted for " . gltime . " seconds"
else
set greylist_msg "Still greylisted for " . greylist_seconds_left . " seconds"
fi
fi
fi
done

prog data
do
if greylisted = 1
echo "%queue_id: " . greylist_msg
tempfail 451 4.7.0 greylist_msg
fi
done

func log_header_line(string hdr_line)
do
set idx index(hdr_line, "\n")-1
if idx < -1
set idx -1
fi
set str1 substring(hdr_line, 0, idx)
if index(hdr_line, "\n") = -1
echo "%queue_id: " . str1
else
echo "%queue_id: " . str1
set str2 substring(hdr_line, index(hdr_line, "\n")+1, -1)
log_header_line(str2)
fi
done

prog header
do
set msg_header msg_header . $1 . ": " . $2 . "\r\n"
set full_header_line $1 . ": " . $2
log_header_line(full_header_line)

/*
catch failure
do
echo "%queue_id: error decoding string of header, caught exception: $2"
# reject 554 5.7.0 "error decoding string of header; $2"
continue
done

if message_header_decode($2, "KOI8-R") matches "ò A ó ó ù ì ï þ ë é"
reject 554 5.7.0 "Spam messages rejected"
fi
*/
done

prog eom
do

catch failure
do
echo "%queue_id: ERROR: mailfromd can not access to clamd, caught exception: $2"
tempfail 451 4.3.0 "mailfromd can not access to clamd; please try again later"
# continue
done

if message_size(current_message()) < ClamdStreamMaxLength
and
clamav(current_message(),clamd_port)
set message <<- EOT
Subject: Virus intercepted
To: <%virusmaster>
From: <MAILER-DAEMON@%ehlo_domain>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
X-Agent: %__package__ (%__version__)
X-Infected-Received-From: %message_received_from

The message %queue_id that sent from %mail_from to

%rcpt_to
contained a virus "%clamav_virus_name"
and has not been delivered.

Message tested by ClamAV: http://www.clamav.net

----- The original (infected) message headers here:

%msg_header_last_received
%msg_header
EOT

echo "%queue_id: Virus founded: %clamav_virus_name from ${client_addr}"

catch *
do
echo "%queue_id: WARNING: message from daemon was not been sent to administrator, caught exception: $2"
reject 554 5.7.0 "virus %clamav_virus_name detected by ClamAV - http://www.clamav.net"
done

send_mail(message, virusmaster)
reject 554 5.7.0 "virus %clamav_virus_name detected by ClamAV - http://www.clamav.net"
fi

if not spamd_port = ""
and
spam_verification_needed = 1
and
message_size(current_message()) < SpamAssassinStreamMaxLength
set prec 3
catch failure
do
echo "%queue_id: ERROR: mailfromd can not access to Spamassasin, caught exception: $2"
tempfail 451 4.3.0 "mailfromd can not access to Spamassasin; please try again later"
done
if sa(spamd_port,prec,1)
if spamreject = 1
set sa_keywords_string sa_format_report_header(sa_keywords)
set message <<- EOT
Subject: spam blocked
To: <%spammaster>
From: <MAILER-DAEMON@%ehlo_domain>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
X-Agent: %__package__ (%__version__)
X-Spam-Received-From: %message_received_from

The message %queue_id that sent from %mail_from to

%rcpt_to
detected as spam and blocked.

----- SA report

%sa_keywords_string

----- The original message headers here:

%msg_header_last_received
%msg_header
EOT

catch *
do
echo "%queue_id: WARNING: message from daemon was not been sent to administrator, caught exception: $2"
reject 554 5.7.0 "Spam detected by Spamassassin." . explain_msg_spam
done

send_mail(message, spammaster)
reject 554 5.7.0 "Spam detected by Spamassassin. " . explain_msg_spam
else
if mta = "sendmail"
header_add("X-Spamd-Flag" . X_Spam_Suffix, "YES")
fi
fi
fi
echo "%queue_id: INFO: message processed by Spamassassin, sa_score=" . sa_score . " sa_threshold=" . sa_threshold
if mta = "sendmail"
header_add("X-Spamd-Score" . X_Spam_Suffix, to_double_str(sa_score, prec))
header_add("X-Spamd-Threshold" . X_Spam_Suffix, to_double_str(sa_threshold, prec))
header_add("X-Spamd-Keywords" . X_Spam_Suffix, sa_format_report_header(sa_keywords))
fi
fi

done
 
projeto & código: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
mantenedor atual: Michael Shigorin
mantenedor da tradução: Fernando Martini aka fmartini © 2009