divert(-1) # # Copyright (c) 2003, 2004 Victor Ustugov # This hack is under BSD License # Redistributions of source code must retain the above copyright notice # # hacks disscussion's maillist - http://www.mta.org.ua/mailman/listinfo/sendmail-conf # # # Check value of EHLO/HELO command # Проверка аргумента команды EHLO/HELO # dnl # для проверки аргумента команды EHLO/HELO по access_db надо внести в sendmail.mc: dnl # define(`confCHECK_HELO', `ACCESS_DB')dnl dnl # dnl # в access_db значения helo вносятся в следующем виде: dnl # Helo:mail.yahoo.com REJECT dnl # Helo:www.mail.ru REJECT dnl # Helo:compuserve.com ERROR Forged helo used dnl # Helo:DFGDFG DISCARD dnl # dnl # для проверки использования в качестве HELO PTR или A записей локальных интерфейсов dnl # или доменов надо в sendmail.mc внести: dnl # define(`confCHECK_HELO', `OWN')dnl dnl # dnl # для проверки отсутствия точки в HELO надо в sendmail.mc внести: dnl # define(`confCHECK_HELO', `SYNTAX')dnl dnl # dnl # для проверки корректности HELO, указанных в виде IP адреса в квадратных скобках dnl # надо в sendmail.mc внести: dnl # define(`confCHECK_HELO', `IP_SYNTAX')dnl dnl # dnl # для запрета приема писем с HELO, указанными в виде IP адреса без квадратных скобок dnl # надо в sendmail.mc внести: dnl # define(`confCHECK_HELO', `IP')dnl dnl # dnl # dnl # исключения сделаны для ${client_addr}, находящихся в $w в виде IP адреса в квадратных скобках, dnl # т. е. если клиент находится на том же хосте, что и сервер dnl # dnl # для исключения из проверки сообщений от аутентифицированных отправителей надо в sendmail.mc внести: dnl # define(`confCHECK_HELO_SKIP', `AUTH')dnl dnl # dnl # для исключения из проверки исходящих сообщений надо в sendmail.mc внести: dnl # define(`confCHECK_HELO_SKIP', `OUTGOING')dnl dnl # dnl # подробнее о понятии "исходящим сообщений см. HACK(`is_outgoing') dnl # dnl # в случае использования define(`confCHECK_HELO_SKIP', `OUTGOING') в access_db есть смысл внести: dnl # - свои домены dnl # - свои IP адреса в квадратных скобках dnl # - все имена своего хоста dnl # dnl # dnl # в confCHECK_HELO и confCHECK_HELO_SKIP можно указывать несколько значений через пробел: dnl # define(`confCHECK_HELO', `ACCESS_DB OWN SYNTAX')dnl dnl # define(`confCHECK_HELO_SKIP', `AUTH OUTGOING')dnl dnl # dnl # dnl ###### функциональность, перенесенная из check_fake_helo.m4 dnl # dnl # проверяется соответствие суффикса HELO и доменной зоны PTR записи рилея dnl # dnl # пример: если HELO заканчивается на yahoo.com, то и PTR запись рилея dnl # должна оканчиваться на yahoo.com dnl # dnl # если у отправителя в MUA прописан адрес из домена yahoo.com dnl # и MUA в качестве HELO использует домен из обратного адреса, dnl # то такой отправитель должен отправлять почту через SMTP сервер своего провайдера, dnl # MTA которого уже будет использовать FQDN одного из своих интерфейсов dnl # dnl # examples: dnl # примеры использования: dnl # HACK(`check_helo', `hotmail.com')dnl dnl # HACK(`check_helo', `yahoo.com')dnl dnl # HACK(`check_helo', `msn.com')dnl dnl # HACK(`check_helo', `aol.com')dnl dnl # HACK(`check_helo', `compuserve.com')dnl dnl # HACK(`check_helo', `rambler.ru')dnl dnl # HACK(`check_helo', `mail.ru')dnl dnl # HACK(`check_helo', `yandex.ru')dnl dnl # HACK(`check_helo', `chat.ru')dnl dnl # HACK(`check_helo', `gala.net')dnl dnl # ifdef(`_CHECK_HELO_', `dnl', `dnl divert(0) VERSIONID(`$Id: check_helo.m4,v 8.13-0.11 2004/08/03 09:37:17 corvax Exp $')dnl divert(-1) dnl define(`_CHECK_HELO_')dnl dnl dnl LOCAL_CONFIG dnl dnl ifdef(`_ACCESS_TABLE_', `', ` errprint(`*** ERROR: HACK(check_helo) requires FEATURE(access_db) ')') dnl HACK(`cfhead')dnl HACK(`precheck_envelope')dnl HACK(`check_ip')dnl dnl dnl # default settings # значения по умолчанию ifdef(`confCHECK_HELO', `', `define(`confCHECK_HELO', `ACCESS_DB')') ifdef(`confCHECK_HELO_SKIP', `', `define(`confCHECK_HELO_SKIP', `AUTH')') dnl dnl LOCAL_RULESETS dnl dnl SLocal_check_mail R $* $: $1 $| $>CheckHelo $&s $| $&{client_name} $| $&{client_addr} R $* $| $#$* $#$2 R $* $| $* $: $1 SCheckHelo R . $| $* $| $* $#error $@ 5.7.1 $: "554 HELO Error" # подставляем IP адрес рилея в квадратных скобках R $* $| $* $| $* $: $1 $| $2 $| [ $3 ] # делаем исключение из проверки, если IP адрес рилея в квадратных скобках # присутствует в $w (т. е. является адресом интерфеса этого же хоста) R $* $| $* $| $=w $@ SKIP_LOCAL # делаем исключение из проверки, если IP адрес рилея в квадратных скобках # является адресом loopback интерфейса R $* $| $* $| [127.0.0.1] $@ SKIP_LOCAL # убираем квардратные скобки R $* $| $* $| [ $+ ] $: $1 $| $2 $| $3 dnl ifelse_strstr(confCHECK_HELO_SKIP, `AUTH', `dnl # skip checks for authentificated senders # делаем исключение из проверки для аутентифицированных отправителей R $* $| $* $| $* $: $&{auth_type} $| $1 $| $2 $| $3 R $+ $| $* $| $* $| $* $@ SKIP_AUTH R $* $| $* $| $* $| $* $: $2 $| $3 $| $4 ') dnl ifelse_strstr(confCHECK_HELO_SKIP, `OUTGOING', `dnl # skip checks for outgoing messages # делаем исключение из проверки для исходящих сообщений R $* $| $* $| $* $: $&{IsOutgoing} $| $1 $| $2 $| $3 R YES $| $* $| $* $| $* $@ SKIP_OUTGOING R $* $| $* $| $* $| $* $: $2 $| $3 $| $4 ') dnl ifelse_strstr(confCHECK_HELO, `OWN', `dnl # check if HELO in $w class # проверяем наличие HELO в классе $w R $=w $| $* $| $* $#error $@ 5.7.1 $: "554 Misconfigured SMTP client detected" ') dnl ifelse_strstr(confCHECK_HELO, `SYNTAX', `dnl # check if HELO have no any dots # проверяем наличие хотя бы одной точки в HELO R $- $| $* $| $* $#error $@ 5.7.1 $: "554 Misconfigured SMTP client (may be MUA) detected" ') dnl ifelse_strstr(confCHECK_HELO, `ACCESS_DB', `dnl # check HELO in access_db # проверяем HELO по access_db R $+ $| $* $| $* $: < ? > $1 $| $2 $| $3 R $+ $| $* $| $* $: < $(access Helo:$1 $: ? $) > $1 $| $2 $| $3 R < REJECT > $* $#error $@ 5.7.1 $: "554 Untrusted HELO rejected" R < REJECT:$* > $* $#error $: $1 R < REJECT $* > $* $#error $: $1 R < DISCARD:$* > $* $#discard $: $1 R < DISCARD $* > $* $#discard $: $1 R < TEMP:$* > $* $#error $@ TEMPFAIL $: $1. " Try again later" R < TEMP $* > $* $#error $@ TEMPFAIL $: $1. " Try again later" R < ERROR:$* > $* $#error $@ UNAVAILABLE $: $1 R < ERROR $* > $* $#error $@ UNAVAILABLE $: $1 dnl R <$*> $+ $| $* $| $* $: $2 $| $3 $| $4 ') dnl ifelse_strstr(confCHECK_HELO, `IP_SYNTAX', `dnl # check IP syntax in HELO # проверка синтаксиса IP адреса в HELO R [$-.$-.$-.$-] $| $* $| $* $: [$1.$2.$3.$4] $| $5 $| $6 $| $>CheckIPsyntax $1.$2.$3.$4 R [$-.$-.$-.$-] $| $* $| $* $| FAILED $#error $@ 5.7.1 $: "554 Incorrect IP syntax" R [$-.$-.$-.$-] $| $* $| $* $| $* $: [$1.$2.$3.$4] $| $5 $| $6 ') dnl ifelse_strstr(confCHECK_HELO, `IP', `dnl # check HELO as IP without brackets # проверяем, не является ли HELO IP адресом без квадратных скобок R $-.$-.$-.$- $| $* $| $* $: $1.$2.$3.$4 $| $5 $| $6 $| $(ippat $1.$2.$3.$4 $: IP $) R $-.$-.$-.$- $| $* $| $* $| IP $#error $@ 5.7.1 $: "554 Incorrect FQDN in HELO" R $-.$-.$-.$- $| $* $| $* $| $| $: $1.$2.$3.$4 $| $5 $| $6 ') dnl ifelse_strstr(confCHECK_HELO, `DIALUP', `dnl # check HELO by dial-up/dsl/cable regexp pattern # проверяем HELO по регулярному выражению на принадлежность diul-up/dsl/cable сетям R $* $| $* $| $* $: $1 $| $2 $| $3 $| $>Local_check_dialup_helo $&s R $* $| $* $| $* $| $#$* $#$4 R $* $| $* $| $* $| $* $: $1 $| $2 $| $3 dnl SLocal_check_dialup_helo dnl # check for HELO exclusion in access_db # проверяем, не указано ли HELO в списке исключений в access_db R $* $: $1 $| $>D <$1> <> R $* $| <$={Accept}> <> $@ $1 R $* $| $* $: $1 dnl # check HELO by regexp # проверка HELO по регулярному выражению R $* $: $(dulpat $1 $: $1 $) R @MATCH $#error $@ 5.7.1 $: 550 Access from dsl/dial-up/cable relays denied according to the local policy ') ') dnl ifelse(len(X`'_ARG_), `1', `dnl', `dnl dnl dnl LOCAL_RULESETS dnl dnl SCheckHelo dnl # check for forged HELO # проверка поддельных HELO R $+ $| $* $| $* $: < ? > $1 $| $2 $| $3 R $* _ARG_ $| $+ . _ARG_ $| $* $: $1 _ARG_ $| $2 . _ARG_ $| $3 R $* _ARG_ $| $+ $| $* $#error $@ 5.7.1 $: "554 Forged HELO string " $1 _ARG_ R <$*> $* $| $* $| $* $: $2 $| $3 $| $4 ')