RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
YandexMoney: 
41001198119846 
E-gold:
5128052

Перевод выполнен Алексеем Паутовым в рамках некоммерческого проекта RussianLDP (http://www.rldp.ru/). Именно на этом сайте и надлежит искать новые версии, если таковые будут.

11. Раскрываемые строки

Mногие строки конфигурации exim раскрываются перед использованием. Одни раскрываются каждый раз при использовании, другие же раскрываются лишь один раз.

Раскрытием строки является дословное копирование её слева направо, исключая символы доллара ($) и обратного слэша. Символ $ задаёт начало части строки, которая интерпретируется и заменяется, как описано ниже в разделе 11.5. Обратный слэш используется как экранирующий символ, как описано в следующем разделе.

11.1. Дословный текст в раскрываемых строках

Неинтерпретируемый $ может быть включен в раскрываемую строку путём помещения перед ним обратного слэша. Обратные слэш может быть использован для экранировки любого специального символа, который может быть развёрнут, включая экранирование самого себя, обратного слша. Если используется строка в кавычках, должны использоваться два обратных слэша, поскольку кавычки сами вызывают интерпретацию обратного слэша при чтении строки (смотрите секцию 6.16).

Часть строки может быть определена как нераскрываемая при помощи помещения её между двумя символами \N. Это необходимо для защиты регулярных выражений, которые часто содержат символы "$" и "\". Например:
deny senders = \N^\d{8}[a-z]@some\.site\.example$\N

При достижении первого символа \N преобразователь копирует последующие символы без интерпретации, пока не достигнет следующего символа \N или новой строки.

11.2. Последовательности с обратным слэшем в расширенных строках

Обратный слэш с последующим за ним символом "n", "r" или "t" это специальная последовательность, означающая новую строку, возврат каретки и табуляцию, соответственно. Если за обратным слэшем следует три восьмеричных цифры, то это расшифровывается как восьмеричная запись символа, а если за обратным слэшем следует символ "x" и до двух шестнадцатеричных цифр, это шестнадцатеричная запись символа.

Эти последовательности распознаются и внутри кавычек. Их интерпретация "как есть" полезна в строках без кавычек и в других случаях поиска строк, которые могут быть раскрыты.

11.3. Тестирование раскрываемых строк

Очень многие раскрываемые строки могут быть проверены путём вызова exim с опцией -be. В этом случае принимаются параметры команды или строки со стандартного ввода, если аргументов нет, выполняет их через код раскрытия строк и пишет результат на стандартный вывод. Переменные, основанные на конфигурации, установлены, но так как не обрабатывается никакое сообщение, переменные типа $local_part не имеют никакого значения. Однако, опцию -be можно применять для проверки файлов и обращений к БД, а также для проверки раскрытия операторов раскрытия, типа sg, substr и nhash.

Exim управляет root-привилегиями при вызове его с опцией -be и выполняется под uid и gid пользователя, вызвавшего его для того, чтобы пользователь, использующий опцию -be не смог получить доступ к файлам, которые ему не принадлежат.

11.4. Принудительный отказ от раскрытия строки

Множество раскрытий, описанных в следующем разделе, имеют подстроки true и false, помещённые в символах фигурных скобок. То, какая из двух строк используется, зависит от условия, которое тоже раскрывается. Если вместо false используется слово fail (не в фигурных скобках), раскрытие строки происходит неудачно и может быть обнаружено кодом, который запрашивал раскрытие. Это называют принудительным отказом раскрытия, его последствия зависят от обстоятельств. В одних случаях это неотличимо от любой другой ошибки раскрытия, но в отдельных случаях может быть предпринято иное действие. Такие варианты упомянуты в документации раскрываемой опции.

11.5. Элементы раскрытия

Следующие элементы распознаются в раскрываемых строках. Пустое пространство может использоваться между подпунктами, которые являются ключевыми словами или подстроками снаружи фигурных скобок, для улучшения читабельности.
$local_part
${domain}

Вторая форма записи может быть использована для отделения от имени переменной последующих алфавитно-цифровых символов. Эта форма (с использованием фигурных скобок) доступна только для переменных: её нельзя применять для заголовков сообщений. Имена переменных приведены в главе 11.9. Если используется имя несуществующей переменной, то раскрытие терпит неудачу.

  • ${op:строка}
    Вначале раскрывается строка, а затем производится заданная op операция. Например:
    ${lc:$local_part}
    
    Строка начинается с первого символа после двоеточия, которое может предваряться пробелом. Список операторов приведен в главе 11.6. Нотация оператора использует простое раскрытие элементов, которые могут иметь один аргумент, поскольку это уменьшает число фигурных скобок и позволяет легче понимать итоговую строку.
  • $bheader_headerаname: или $bh_headerаname:
    Этот элемент вставляет основные строки заголовка. Это описано с элементом раскрытия header ниже.
  • ${acl{name}{arg}...}
    Имя name и от 0 до 9 строк параметров сначала раскрываются отдельно. Раскрытые параметры по порядку будут присвоены переменным $acl_arg1-$acl_arg9. Не пригодившиеся переменными останутся пустыми. Переменная $acl_narg будет установлена в число параметров. ACL с именем name вызывается и может использовать переменные. Если другие ACL используются, значения будут восстановлены после возврата из них. Если ACL устанавливает значение с помощью модификатора "message =" и возвращает accept или deny, это значение становится результатом расширения. Если message не установлено, и ACL возвращает accept или deny, результатом раскрытия является пустая строка. Если ACL возвращает defer, раскрытие принудительно терпит неудачу. Иначе раскрытие терпит неудачу.
  • ${certextract{field}{certificate}{string2} {string3}}
    Здесь certificate должна быть переменной типа сертификата. field раскрывается и приводится к соответствующим полям из сертификата. Поддерживаемые поля:
    version
    serial_number
    subject         RFC4514 DN
    issuer          RFC4514 DN
    notbefore       время
    notafter        время
    sig_algorithm
    signature
    subj_altname    список
    ocsp_uri        список
    crl_uri         список
    

    Если поле найдено, раскрывается string2 и заменяется элементом, иначе используется string3. Во время раскрытия переменная $value содержит извлеченное значение. Потом она вернется к предыдущему значению, которое может быть было.

    Если string3 пропущена, элемент заменен пустой строкой, если не найден ключ. Если string2 также пропущена, используется извлеченное значение. Некоторые имена полей применяют дополнительные модификаторы, разделенные запятыми. Разделители полей обозначаются в соответствии с RFC4514, что не обрабатывается Exim как разделенный запятыми теговый список (исключение: элементы, содержащие запятые). Элементы RDN могут быть выбраны модификатором type, а раз так, то результатом раскрытия является список (разделенный по умолчанию символами новой строки). Разделитель может быть изменен с помощью правой угловой скобки, сопровождаемой новым разделителем. Распознанные типы RDN: "CN", "O", "OU" и "DC".

    Поля, помеченные выше как "время", могут хранить число секунд с начала эпохи, если применен модификатор "int". Значения полей представлены в человеко-читаемой форме.

    Поля, помеченные выше как "список", возвращают список, разделенный символами новой строки по умолчанию (встроенные символы-разделители в элементах будут удвоены). Разделитель может быть изменен модификатором правой угловой скобки, сопровождаемой сразу новым разделителем.

  • ${dlfunc{file}{function}{arg}{arg}...}
    Это раскрытие динамически загружается, а затем вызывает локальную функцию, написанную на C. Такая функциональность доступна лишь в случае, если exim собран со следующим аргументом:
    EXPAND_DLFUNC=yes
    
    заданным в Local/Makefile. Однажды загруженный exim запоминает динамически загруженный объект, так что не требуется перезагружать файлы объектов при работе того же процесса exim (но сам exim часто запускает свои новые копии при работе). У функции может быть от нуля до восьми аргументов. Собирая локальную функцию, вызываемую таким образом, необходимо включить local_scan.h. Переменные и функции exim, определённые в API, также доступны для динамически загружаемых функций. Сама функция должна иметь следующий вид:
    int dlfunction(uschar **yield, int argc, uschar *argv[])
    

    Где uschar является typedef для unsigned char в local_scan.h. Функция должна возвратить одно из следующих значений:
    • OK: Успех. Строка, помещённая в переменную yield, помещена в раскрытую строку и будет построена.
    • FAIL: Непринудительная неудача раскрытия с сообщением об ошибках, взятых из yield, если таковое задано.
    • FAIL_FORCED: Принудительный отказ раскрытия с сообщением об ошибках из yield, если таковое задано.
    • ERROR: То же, что и FAIL, за исключением того, что пишутся ошибки в протокол.
    При использовании gcc для сборки такой функции, необходимо добавить ключ -shared к строке запуска gcc. Также при сборке exim необходимо добавить -export-dynamic в EXTRALIBS.
  • ${extract{key}{string1}{string2}{string3}}
    Вначале раздельно раскрываваются key и string1. Начальные и замыкающие пустые символы (пробелы, табуляции) удаляются из key (но не из строк). Ключ (key) не должен состоять полностью из цифр. Раскрытая строка string1 должна иметь форму:
    key1 = value1 key2 = value2 ...
    
    где знак равенства и пробел (но не оба одновременно) опциональны. Если любое из значений содержит пустые символы, они должны быть помещены в двойные кавычки, чтобы быть обработанными, как описано в разделе 6.16. Раскрытие string1 выполняет поиск значения, соответствующего ключу. Поиск нечувствителен к регистру. Если ключ найден, string2 раскрывается и заменяет элемент, иначе используется string3. В процессе раскрытия string2 переменная $value содержит значение, которое было извлечено. Впоследствии оно восстанавливается до предыдущего значение, которое, возможно, было. Если {string3} отсутствует, элемент заменяется пустой строкой, если ключ не найден. Если {string2} также отсутствует, то используется значение, которое было извлечено. Таким образом, например, эти два раскрытия идентичны и соответствуют 2001:
    ${extract{gid}{uid=1984 gid=2001}}
    ${extract{gid}{uid=1984 gid=2001}{$value}}
    

    Вместо {string3} может быть слово fail (не в фигурных скобках), например:
    ${extract{Z}{A=... B=...}{$value} fail }
    

    Это вызывает принудительный отказ раскрытия (смотрите секцию 11.4). {string2} должна присутствовать, чтобы fail был распознан.
  • ${extract{number}{separators}{string1}{string2}{string3}}
    Аргумент number должен полностью состоять из десятичных цифр, кроме начальных и конечных пустых символов, которые игнорируются. Это то, что отличает эту форму extract от предыдущего вида. Она ведёт себя точно так же, за тем исключением, что вместо того, чтобы извлечь названное поле, извлекает из string1 поле, номер которого задаётся как первый аргумент. Вы можете использовать $value в string2 или fail вместо string3, как и прежде. Поля в строке разделены любым из символов в строке разделителя. Они могут включать пустые символы и табуляцию. Первое поле имеет номер один. Если номер отрицательный, то поля считаются с конца строки, считая что самое правое имеет номер -1. Если задано номер 0, то возвращается вся строка целиком. Если модуль (именно модуль!) числа больше, чем число полей в строке, то результатом будет раскрытие строки string3 или пустая строка, если string1 отсутствует. Например:
    ${extract{2}{:}{x:42:99:& Mailer::/bin/bash}}
    
    вернёт 42 и
    ${extract{-4}{:}{x:42:99:& Mailer::/bin/bash}}
    
    вернёт 99. Два последовательных разделителя означают, что область между ними пуста (например, пятая область в предыдущем примере).

  • ${filter{string}{condition}}
    После раскрытия string интерпретируется как список, разделенный двоеточиями, по умолчанию, но разделитель может быть изменен обычным способом. Для каждого элемента в этом списке его значение помещается в $item, а затем оценено выражение condition. Если условие condition истинно, $item добавлен к выводу как элемент в новом списке. Если condition ложно, от элемента отказываются. Разделитель, используемый для выходного списка, является тем же самым, что и для ввода, но установка разделителя не включена в вывод. Например:
    ${filter{a:b:c}{!eq{$item}{b}}
    
    выдаст a:c. В конце раскрытия значение $item будет восстановлено к тому, чем было прежде.
  • ${hash{string1}{string2}{string3}}
    Это текстовая функция хэширования, она была первой, реализованной в ранних версиях exim. В нынешних версиях добавлены и другие функции работы с хэшами (числовой, MD5 и SHA-1), описанные ниже. Первые две строки после раскрытия должны быть числами. Назовем их m и n. Если Вы используете фиксированные значения для этих чисел, то есть string1 и string2 не изменяются при раскрытии, можете использовать более простой синтаксис оператора, без использования некоторых фигурных скобок:
  • ${hash_n_m: string}
    Второе число является опциональным (в обеих нотациях). Если n больше или равно длине строки, раскрытие строки вернёт саму строку. Иначе будет вычислена новая строка с длиной n с помощью применения функции хэширования к строке. Новая строка состоит из m символов, взятых от начала строки.
    abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQWRSTUVWXYZ0123456789
    

    Если m не задана, то используется значение 26, чтобы были обработаны только строчные буквы. Например:
    $hash{3}{monty}}              результат  jmg
    $hash{5}{monty}}              результат  monty
    $hash{4}{62}{monty python}}   результат  fbWx
    

  • $header_header name: или $h_header name:
    Смотрите $rheader ниже.
  • $bheader_header name: или $bh_header name:
    Cмoтpитe $rheader ниже.
  • $rheader_header name: или $rh_header name:
    Замена заголовка содержанием названной строки. Например:
    $header_reply-to:
    
    Символ новой строки, который завершает строку заголовка не включен в раскрытие, но внутренние символы новой строки (разделяющие заголовок на несколько строк) могут присутствовать. Различие между rheader, bheader и header в способе интерпретации данных в строке заголовка.
  • rheader выдаёт оригинальное содержимое (raw) заголовка, вообще без обработки, без удаления начального и конечного пустого пространства.
  • bheader удаляет пустые символы в начале и конце строки, затем декодирует base64 или экранированные кавычками MIME-слова в пределах заголовка, но не производит трансляции символов. Если расшифровка MIME-слов неудачна, возвращается raw-строка. Если в результате расшифровки появляется символ двоичного нуля, он заменяется вопросительным знаком, это то, что делает exim с бинарными нулями, переданными в строке заголовка.
  • header пробует транслировать строку как bheader, к стандартному набору символов. Это попытка воспроизвести ту же строку, которая была бы отображена MUA пользователю. Если трансляция неудачна, возвращается строка bheader. Попытки трансляции предпринимаются только на OC, которые поддерживают функцию iconv(). Это указано при компиляции макросом HAVE_ICONV в системном Makefile или Local/Makefile. В файле фильтра целевой набор символов для заголовка может быть определен командой следующей формы:
    headers charset "UTF-8"
    
    Эта команда затрагивает все ссылки на расширения $h_ (или $header_ в командах фильтра). В отсутствии этой команды итоговый набор символов устанавливается из опции headers_charset в текущей конфигурации. Значения по умолчанию этих опций: значение HEADERS_CHARSET Local/Makefile. Окончательное значение по умолчанию: ISO-8859-1. Имена заголовков следуют синтаксису RFC 2822 в котором говорится, что они могут содержать любые символы, кроме пробелов и двоеточий. Следовательно, фигурные скобки не заканчивают имена заголовков и не могут использоваться для помещения в начале и в конце, как в переменных. Попытка сделать такое считается ошибкой синтаксиса. Только заголовки, являющиеся общими для всех копий сообщения, видны этому механизму. Тут фигурируют только оригинальные заголовки, переданные с сообщением, и некоторые добавленные правилами warn или системным фильтром. Заголовки, добавленные к особой копии сообщения роутером или транспортом, недоступны. Для входящих SMTP-сообщений никакие заголовки не видны в ACL в правилах до DATA ACL, поскольку структура заголовка не установлена, пока сообщение не получено. Заголовки, добавленные правилами warn, например, в RCPT ACL, сохраняются до тех пор, пока недоступны заголовки входящего сообщения. Однако, когда выполняются DATA ACL, заголовки, добавленные другими ACL, видны. В именах заголовков не имеет значения, какие используются буквы: заглавные или строчные. Если следующий символ является пробелом, завершающее двоеточие может быть пропущено, но это не рекомендуется, поскольку Вы можете забыть об этом, когда оно понадобится. Когда имя заголовка завершается пробелом, оно включается в раскрываемую строку. Если сообщение не содержит данный заголовок, раскрытие заменяется пустой строкой. Смотрите условие определения в главе 11.7 для проверки существования заголовка. Если есть более, чем один заголовок с одинаковым именем, то все они объединяются для формирования строки замены, максимальной длины в 64k. Символ новой строки вставляется перед каждой строкой. Для раскрытия заголовка, для тех заголовков, которые содержат список адресов, также вставляется запятая между строками.
  • ${hmac{hashname}{secret}{string}}
    Эта функция использует криптографическое хэширование (либо MD5, либо SHA-1) для конвертации пароля и текста в код идентификации сообщения, как определено в RFC 2104. Это отличается от ${sha1:secret_text...} или ${sha1:secret_text...}, в этом шаге hmac добавляет в подпись криптографический хэш, допустимый для аутентификации, что невозможно только с MD5 или SHA-1. Имя хэша в настоящее время должно быть либо MD5, либо SHA-1. Например:
    ${hmac{md5}{somesecret}{$primary_hostname $tod_log}}
    
    Для имени хоста mail.example.com и времени 2002-10-17 11:30:59 это будет:
    dd97e3ba5d1a61b5006108f8c8252953
    
    Как пример того, где это можно использовать, Вы могли бы поместить в основной части конфигурации Exim:
    SPAMSCAN_SECRET=cohgheeLei2thahw
    
    В роутере или транспорте можно было бы иметь:
    headers_add = X-Spam-Scanned: \
                  ${primary_hostname} ${message_exim_id} \
                  ${hmac{md5}{SPAMSCAN_SECRET} \
                  {${primary_hostname},${message_exim_id},$h_message-id:}}
    
    Тогда данное сообщение Вы могли бы проверить, где оно было проверено по заголовкам X-Spam-Scanned:. Если Вы знаете секретную строку, можно проверить подлинность этой строки, повторно вычислив опознавательный код из имени хоста, message ID и заголовка Message-id:. Это может быть сделано с использованием опции -be или другими средствами, например, использованием функции hmac_md5_hex() в Perl.
  • ${if condition {string1}{string2}}
    Если condition истинно, то раскрывается string1 и заменяет весь элемент, иначе используется string2. Доступные выражения описаны в главе 11.7. Например:
    ${if eq {$local_part}{postmaster} {yes}{no}}
    
    Вторая строка может не присутствовать, если условие не соответствует и не истинно, элемент ничем не заменяется. Аналогично, слово fail (без фигурных скобок) может быть вместо второй строки. В этом случае происходит принудительный отказ раскрытия, если условие не истинно (смотрите главу 11.4). Если отсутствуют обе строки, результатом станет строка true, если условие истинно, или пустая строка, если условие ложно. Это облегчает написание своих ACL и условий для роутеров. Например, вместо:
    condition = ${if >{$acl_m4}{3}{true}{false}}
    
    Вы можете использовать:
    condition = ${if >{$acl_m4}{3}}
    
  • ${length{string1}{string2}}
    Элемент length используется для извлечения начальной части строки. Обе строки раскрываются, первая должна вернуть число n. Если Вы используете жёстко заданное число, то есть строка string1 при раскрытии не меняется, можете использовать более простую нотацию оператора без некоторых фигурных скобок:
    ${length_n:string}
    
    Результатом будет первые n символов или вся строка string2, смотря что короче. Не путайте length со strlen, возвращающей длину строки.
  • ${lookup{key} search type {file}{string1}{string2}}
    Это первый из двух различных типов поиска отдельных элементов, оба которых описаны в следующем пункте.
  • ${lookup search type {query}{string1}{string2}}
    Две формы поиска определяют поиск данных в БД и файлах, как обсуждается в главе 9. Первая форма использует одноключевой поиск, а вторая использует стиль запросов для поиска. Строки key, file и query раскрываются перед использованием. Если есть пустые символы в элементе поиска как часть команды фильтра, правила повтора или перезаписи, правила роутинга для manualroute или любого другого места, где пустое пространство существенно, элемент поиска должен быть заключён в двойные кавычки. Использование поиска данных в файлах фильтров пользователей может быть заблокировано системным администратором. Если поиск успешен, string1 раскрывается и замещает весь элемент. В процессе его раскрытия переменная $value содержит данные, возвращённые поиском. Впоследствии оно возвращается к предыдущему своему значению. Если поиск неудачен, раскрывается string и замещает элемент. Если string2 пропущена, то заменой будет пустая строка, в случае неудачного поиска. Если string2 присутствует, то она может быть самостоятельным вложенным поиском, таким образом обеспечивая механизм поиска значения по умолчанию в случае неудачи основного поиска. Если вложенный поиск используется как часть string1, $value содержит данные для внешнего поиска, когда параметры второго поиска раскрыты, а также когда string2 второго поиска раскрыта, второй поиск будет неудачен. Вместо string2 можно использовать fail, в этом случае, если поиск неудачен, с раскрытием происходит принудительный отказ при раскрытии строки (смотрите 11.4). Если пропущены обе строки, string1 и string2, то результатом будет искомое значение в случае успешного поиска и ничего в случае неудачи. Для одноключевого поиска "неполной" строке разрешается предшествовать типу поиска, чтобы сделать частичное соответствие, * или *@ могут быть вместе со строкой поиска для поиска по умолчанию, если ключ не совпадает (смотрите детали в 9.6 и 9.7). Если используется частичный поиск, переменные $1 и $2 содержат части ключа в процессе раскрытия текста замены. Они возвращаются к их предыдущим значениям после окончания поиска. Вот пример поиска псевдонима postmaster в обычном файле псевдонимов:
    ${lookup {postmaster} lsearch {/etc/aliases} {$value}}
    
    Этот пример использует NIS+ для поиска полного имени пользователя, соответствующего локальной части адреса, с принудительным отказом раскрытия в случае неудачи.
    ${lookup nisplus {[name=$local_part],passwd.org_dir:gcos} {$value}fail}
    
  • ${map{string1}{string2}}
    После раскрытия string1 интерпретируется как список, разделенный двоеточиями по умолчанию, но разделитель может быть изменен обычным способом. Для каждого элемента в этом списке его значение помещается в $item, затем string2 раскрывается и добавляется к выводу как элемент в новом списке. Разделитель, используемый для выходного списка, является тем же самым, что и для входного, но установка разделителя не включена в вывод. Например:
    ${map{a:b:c}{[$item]}} ${map{<- x-y-z}{($item)}}
    
    выдаст на выходе [a]:[b]:[c] (x)-(y)-(z). В конце работы значение $item будет восстановлено к первоначальному виду.
  • ${nhash{string1}{string2}{string3}}
    Три строки раскрываются: первые две должны вернуть числа. Назовем их n и m. Если Вы используете жёстко заданные значения этих чисел, то есть если string1 и string2 не изменяются при раскрытии, можете использовать более простую форму этого оператора без использования некоторых фигурных скобок:
    ${nhash_n_m:string}
    
    Второе число является опциональным (в обеих нотациях). Если есть только одно число, результатом будет число из диапазона от нуля до n-1. Иначе строка, обработанная функцией хэшрования, вернёт два числа, разделённые слэшем, в диапазонах от нуля до n-1 и от нуля до m-1 соответственно. Например:
    ${nhash{8}{64}{supercalifragilisticexpialidocious}}
    
    вернёт строку 6/33.
  • ${perl{subroutine}{arg}{arg}...}
    Этот элемент доступен лишь в том случае, если exim собран с встроенным интерпретатором perl. Имя подпрограммы и параметры вначале раздельно раскрываются, а затем вызывается подпрограмма perl с этими параметрами. Никакие дополнительные параметры передаваться не должны, максимальное разрешённое число аргументов, включая имя подпрограммы, 9. Значение, возвращённое подпрограммой, вставляется в раскрываемую строку, за тем исключением, если возвращённое значение undef. В этом случае раскрытие неудачно, точно так же, как при fail в поиске. Возвращённое значение представляет собой скалярную величину. Независимо от того, что Вы возвращаете, оно будет скалярной величиной. Например, если Вы вернёте имя вектора perl, возвращённое значение будет размером вектора, а не содержимым. Если подпрограмма выполняется с вызовом функции perl die(), раскрытие неудачно с сообщенем об ошибках, которые были переданы функцией die(). Больше информации о встроенном perl можно получить из части 12. Роутер redirect имеет опцию forbid_filter_perl, которая блокирует использование этого пункта в файлах фильтра.
  • ${prvs{address}{secret}{keynumber}}
    Первый параметр полный e-mail адрес, второй секретная ключевая строка. В третьем аргументе задаётся номер ключа, он является опциональным. При его отсутствии значение по умолчанию 0. Результат раскрытия: prsv-подписанный адрес e-mail, типичное его использование с опцией return_path транспорта smtp как часть проверки схемы адреса возврата (BATV). За дополнительной информацией и примерами обратитесь к главе 39.38.
  • ${prvscheck{address}{secret}{string}}
    Этот пункт дополнение пункта prvs. Он используется для проверки prsv-подписанных адресов. Если раскрытие первого параметра не приводит к синтаксически правильному prsv-подписанному адресу, то всё раскрывается в пустую строку. Когда первый параметр раскрывается в синтаксически правильный prsv-подписанный адрес, второй аргумент раскрывается с prvs-расшифрованным адресом и ключевым числом, в переменных $prvscheck_address и $prvscheck_keynum, соответственно. Эти две переменные могут использоваться в раскрытии второго аргумента для поиска секретного слова. Тогда действительность prsv-подписанного адреса проверяется по нему. Результат сохраняется в переменную $prvscheck_result, пустую при ошибке и 1 при соответствии. Третий параметр является дополнительным, если он отсутствует, то по умолчанию это пустая строка. Теперь этот параметр раскрыт. Если результат пустая строка, то результатом раскрытия будет расшифрованная версия адреса. Проверяется, была ли сигнатура верной. Иначе результатом раскрытия станет раскрытие третьего аргумента. Все три переменные могут использоваться в раскрытии третьего параметра. Тем не менее, по завершении раскрытия остаётся только $prvscheck_result. За дополнительной информацией и примерами обратитесь к главе 39.38.
  • ${readfile{file name}{eol string}}
    Вначале раздельно раскрываются имя файла и набор символов конца строки. Затем читается файл, и его содержимое заменяет весь пункт. Символы новой строки в файле заменяются строкой eol string, если они есть. Иначе, символы перевода строк остаются на месте. Раскрытие строки не применяется к содержимому файла. Если же Вы хотите этого, необходимо поместить элемент в оператор expand. Если файл не может быть прочитан, раскрытие строки неудачно. Роутер redirect имеет опцию forbid_filter_readfile, которая блокирует использование этой возможности в пределах файлов фильтра.
  • ${readsocket{name}{request}{timeout} {eol string}{fail string}}
    Это вставляет данные из UNIX или Internet-сокета в раскрываемую строку. Минимальный способ использования требует только два аргумента, как в этих примерах:
    ${readsocket{/socket/name}{request string}}
    ${readsocket{inet:some.host:1234}{request string}}
    
    Для UNIX-сокета первая подстрока должна быть путём к сокету. Для Internet-сокета первая подстрока должна содержать подстроку inet:, сопровождаемую именем хоста или IP-адресом через двоеточие, порт или имя сервиса, которое должно быть в /etc/services. Опционально IP-адрес может заключаться в квадратные скобки. Адреса IPv6 лучше записывать именно так. Например:
    ${readsocket{inet:[::1]:1234}{request string}}
    
    Можно задать только одно имя хоста, но если поиск по нему приведёт более, чем к одному IP-адресу, будут сделаны попытки соединиться с каждым из них по очереди, пока не получится подключиться. Для обоих видов сокетов exim осуществляет подключение, пишет строку запроса (если она не пустая) и читает из сокета данные, пока не наступит конец файла. Применяется таймаут в 5 секунд. Дополнительные аргументы могут продлить это время. Можно изменить таймаут:
    ${readsocket{/socket/name}{request-string}{3s}}
    
    Четвёртый аргумент позволяет изменить символ перевода строки в читаемых данных таким же образом, как и в readfile (смотрите выше). Этот пример превращает их в пробелы:
    ${readsocket{inet:127.0.0.1:3294}{request-string}{3s}{ }}
    
    Как и во всех раскрытиях, подстроки раскрываются до начала обработки. Ошибки в подраскрытиях приводят к ошибке самого раскрытия. Кроме того, могут встречаться такие ошибки:
    • Ошибка создания дескриптора файла сокета.
    • Ошибка соединения с сокетом.
    • Ошибка записи строки запроса.
    • Таймаут чтения из сокета.
    По умолчанию любая из этих ошибок приводит к ошибке раскрытия. Однако, если Вы используете пятый аргумент, раскрытие происходит, если встречается любая из вышеупомянутых ошибок. Например:
    ${readsocket{/socket/name}{request-string}{3s}{\n}\
                 {socket failure}}
    
    Вы можете проверить существование Unix-сокета, поместив раскрытие в ${if exists, но получается проверка, кто отработает быстрей: открытие сокета или проверка его существования. Таким образом, более корректно использовать пятый параметр, чтобы быть уверенным в том, что будет корректно обработана ошибка раскрытия несуществующего Unix-сокета или ошибка соединения с интернет-сокетом. Роутер redirect имеет опцию forbid_filter_readsocket, которая блокирует использование этой функции в пределах файлов фильтра.
  • $rheader_header name: or $rh_header name:
    Это вставляет необработанные (raw) строки заголовка. Это описано в пункте header выше.
  • ${reduce{string1}{string2}{string3}}
    Уменьшает список до единственной скалярной строки. После раскрытия string1 интерпретируется как список, разделенный по умолчанию двоеточиями, но разделитель может быть изменен обычным способом. Тогда string2 раскрыта и назначена на переменную $value. После этого каждый элемент в списке string1 в свою очередь назначен на $item, а string3 раскрывается для каждого из них. Результат этого раскрытия назначен $value перед следующей итерацией. Когда конец списка достигнут, заключительное значение $value добавлено к выводу раскрытия. Элемент раскрытия reduce может использоваться многими способами. Например, чтобы сложить список чисел:
    ${reduce {<, 1,2,3}{0}{${eval:$value+$item}}}
    
    Результатом этого раскрытия будет 6. Максимум списка чисел может быть найден:
    ${reduce {3:0:9:4:6}{0}{${if >{$item}{$value}{$item}{$value}}}}
    
    В конце работы ${reduce значения $item и $value восстановлены к тому, чем они были прежде.
  • ${run{command args}{string1}{string2}}
    Вначале отдельно раскрываются команда и её параметры, затем команда запускается отдельным процессом, но под теми же gid и uid. Как и во всех других командах, выполняемых exim, по умолчанию shell не используется. Если Вы хотите его использовать, нужно явно указать это в коде. Если команда выполняется успешно (возвращённый код равен нулю), то string1 раскрывается и замещает строку, в процессе этого раскрытия стандартный вывод команды находится в переменной $value. Если команда неудачна, то раскрывается и используется string2. Стандартный вывод команды в процессе раскрытия находится в переменной $value. Если string2 отсутствует, результат пуст. Альтернативно, string2 может быть словом fail (не в фигурных скобках) для принудительного отказа от раскрытия, если команда не была успешно выполнена. Если пусты обе строки, результат содержит стандартный вывод в случае успеха и ничего не содержит в случае неудачи. Код возврата команды помещается в переменную $runrc и впоследствии остаётся установленным, поэтому в файле фильтра можно делать так:
    if "${run{x y z}{}}$runrc" is 1 then ...
    elif $runrc is 2 then ...
    ...
    endif
    
    Если выполнение команды неудачно (например, команда не существет), то код возврата равен 127.
    Предупреждение: в роутере или транспорте Вы не можете установить порядок раскрытия опций, за исключением тех предварительный условий, чей порядок задокументирован. Поэтому нельзя быть уверенным в том, что находится в $runrc, запуская команду в одной опции и используя эту переменную в другой. Роутер redirect имеет опцию forbid_filter_run, которая блокирует использование этой функции в пределах файлов фильтра.
  • ${sg{subject}{regex}{replacement}}
    Этот пункт работает как оператор замены в perl с глобальной опцией /g. Однако, в отличие от perl, exim не изменяет строку, вместо этого он возвращает строку для вставки в общее раскрытие. Есть три парааметра: строка объекта, регулярное выражение, строка замены. Например:
    {sg{abcdefabcdef}{abc}{xyz}}
    
    результат: xyzdefxyzdef. Поскольку все три параметра раскрываются перед использованием, то если в регулярном выражении необходимы символы $ или символы, содержащие обратный слэш, они должны быть экранированы. Например:
    ${sg{abcdef}{^(...)(...)\$}{\$2\$1}}
    
    вернёт "defabc" и
    ${sg{1=A 4=D 3=C}{\N(\d+)=\N}{K\$1=}}
    
    вернёт K1=A K4=D K3=C. Отметьте использование \N для защиты регулярного выражения от раскрытия.
  • ${substr{string1}{string2}{string3}}
    Три строки раскрываются, первые две должны вернуть числа. Назовем их m и n. Если Вы используете фиксированные значения для этих чисел, то есть string1 и string2 не изменяются при раскрытии, можете использовать более простой синтаксис оператора без использования некоторых фигурных скобок:
    ${substr_n_m:string}
    
    Второе число опционально (в обеих нотациях). Если в более простом формате оно отсутствует, то предваряющее подчёркивание должно быть опущено. Элемент substr может использоваться для извлечения более коротких подстрок из более длинной. Первое число n является смещением точки начала, m задает требуемую длину. Например:
    ${substr{3}{2}{$local_part}}
    
    Если стартовое смещение больше длины строки, то результатом будет пустая строка, если сумма старта плюс длина больше смещения, результатом будет правая часть строки, начинающаяся с точки старта. Первый символ строки имеет позицию 0. Элемент substr может иметь отрицательные значения смещения, чтобы рассчитать позицию с правой стороны строки. Последний символ имеет значение смещения -1, предпоследний -2 и так далее. Вот пример:
    ${substr{-5}{2}{1234567}}
    
    результат: 34. Если абсолютное значение отрицательного смещения больше, чем длина строки, то подстрока начинается с начала строки, а её длина уменьшается на величину разницы. Например:
    ${substr{-5}{2}{12}}
    
    вернёт пустую строку, но
    ${substr{-3}{2}{12}}
    
    вернёт 1. Когда второй параметр substr опущен, то берётся остаток строки при положительном смещении. Если же смещение отрицательно, то берутся все символы строки, предшествующие точке смещения. Например, смещение -1 и никакая (нулевая) длина в этих одинаковых примерах:
    ${substr_-1:abcde}
    ${substr{-1}{abcde}}
    
    вернёт всю строку, кроме последнего символа, то есть abcd.
  • ${tr{subject}{characters}{replacements}}
    Этот элемент посимвольная замена строки объекта. Второй аргумент список символов, которые будут заменены в строке объекта. Каждый совпадающий символ заменяется соответствующим символом из списка замены. Например:
    ${tr{abcdea}{ac}{13}}
    
    вернёт 1b3de1. Если во второй строке символов есть повторения, используется последний из символов. Если третья строка короче, чем вторая, последний символ копируется. Однако, если она пуста, замена не производится.

11.6. Операторы раскрытия

Для раскрывающихся элементов, которые выполняют преобразования на одном аргументе строки, используется нотация оператора, поскольку это проще и используется меньше фигурных скобок. Подстрока раскрывается до того, как над ней будет проведена операция. Следующие операции могут быть выполнены:

  • ${address:string}
    Строка интерпретируется как адрес, согласно RFC 2822, а поскольку может фигурировать в строках заголовков, то из неё извлекается эффективный адрес. Если строку не удаётся успешно разобрать, то результат пуст.
  • ${addresses:string}
    Строка интерпретируется как список адресов формата RFC 2822, как это могло бы появиться в строке заголовка, эффективный адрес будет извлечен из этого. Если строка не раскрывается успешно, результат пуст.
  • ${base62:digits}
    Строка должна полностью состоять из десятичных цифр. Число конвертируется к основанию 62 и выводится как строка из шести символов, включая ведущие нули. В некоторых окружениях, где exim использует основание 36 вместо 62 для идентификаторов сообщений (поскольку эти системы не учитывают регистр символов в имени файла), основание 36 используется этим оператором, несмотря на его название. Отметьте: чтобы было абсолютно ясно: это не кодирование в base64!
  • ${base62d:base-62 digits}
    Строка должна полностью состоять из цифр с основанием 62 или, в операционных системах где exim использует основание 36 вместо 62, из цифр с основанием 36. Число преобразуется в десятичные цифры и выводится как строка.
  • ${domain:string}
    Строка интерпретируется как адрес, в соответствии с RFC 2822, и из неё извлекается домен. Если строка не может быть корректно разобрана, то результат пуст.
  • ${escape:string}
    Если строка содержит какие-то непечатные символы, то они будут преобразованы к их escape-последовательностям, начинающимся с символа обратного слэша (\). Символы с установленным битом значимости (так называемые 8-битные символы) считаются печатными и не контролируются опцией print_topbitchars.
  • ${eval:string} и ${eval10:string}
    Эти пункты поддерживают простейшие арифметические операции, а также одноместное отрицание, поразрядные логические операторы и сдвиг в раскрываемых строках. Строка после раскрытия должна быть обычным арифметическим выражением, но оно ограничено пятью основными операторами (+, -, *, div и mod), логическими операциями и круглыми скобками. Также допустимо использовать операторы сдвига влево и вправо. Все операции выполняются с использованием арифметики целых чисел. Плюс и минус имеют меньший приоритет, чем умножение, деление и остаток. Операторы с одинаковым приоритетом оцениваются слева направо. В eval числа могут быть десятичными, восьмеричными (начинаются с 0) или шестнадцатеричными (начинаются с 0x). В eval10 все числа считаются десятичными, даже если они начинаются с 0. Это может оказаться полезным при обработке чисел, извлечённых из дат и времени, они часто содержат ведущие нули. Число может сопровождаться K или M для умножения его на 1024 или 1024*1024 соответственно. В eval допустимо также использовать 64-битные значения, но только на платформах, которые поддерживают их аппаратно. Суффикс G означает умножение на 1024^3. Для обоих вариантов поддерживаются отрицательные числа. Результат вычисления: десятичное число (без K, M или G). Например:
    ${eval:1+1}              результат 2
    ${eval:1+2*3}            результат 7
    ${eval:(1+2)*3}          результат 9
    ${eval:2+42%5}           результат 4
    ${eval:0xc&5}            результат 4
    ${eval:0xc|5}            результат 13
    ${eval:0xc^5}            результат 9
    ${eval:0xc>>1}           результат 6
    ${eval:0xc<<1}           результат 24
    ${eval:~255&0x1234}      результат 4608
    ${eval:-(~255&0x1234)}   результат -4608
    

    Как более реалистичный пример, в ACL можно использовать:
    deny message = Too many bad recipients
    condition = ${if and {{>{$rcpt_count}{10}} { \
                < {$recipients_count} \
                {${eval:$rcpt_count/2}}}}{yes}{no}}
    
    Условие верно в случае, если было более 10 команд RCPT и меньше половины из них привели к правильному получателю.

  • ${expand:string}
    Оператор expand заставляет раскрыть строку второй раз. Например:
    ${expand:${lookup{$domain}dbm{/some/file}{$value}}}
    
    вначале ищет строку в файле в процессе раскрытия оператора expand, а затем снова раскрывает то, что было найдёно.
  • ${from_utf8:string}
    Мир медленно (увы, очень медленно) движется в сторону Unicode, и хотя для электронной почты стандартов нет, она тоже сдвигается туда же. Многие другие приложения (включая некоторые БД) начинают сохранять данные в Unicode, используя кодировку UTF-8. Этот оператор конвертирует строку UTF-8 в строки ISO-8859-1. Коды символов UTF-8 более 255 преобразуются в подчёркивания. Ввод должен быть корректной строкой UTF-8. Если это не так, то результатом будет неопределённая последовательность символов. Точки кодов Unicode со значениями меньше 256 совместимы с ASCII и ISO-8859-1 (также известной как Latin-1). Для примера, символ 169 это символ копирайта в обоих случаях, хотя способ, которым он закодирован, различен. В режиме UTF-8 более, чем один байт необходим для символов с кодом более 127, тогда как в ISO-8859-1 используется однобайтное кодирование (таким образом, оно ограничено 256 символами). Это позволяет сделать прямой перевод из UTF-8 в ISO-8859-1.
  • ${hash_n_m:string}
    Оператор hash это более простой интерфейс к функции хэширования, которая может использоваться, когда два её параметра фиксированные числа (в противоположность строкам, динамически строящимся при раскрытии). Эффект тот же самый, что и:
    ${hash{n}{m}{string}}
    

    Для дополнительных подробностей, посмотрите описание главного оператора hash выше. Аббревиатура h может быть применена, когда hash используется как оператор.

  • ${hex2b64:hexstring}
    Этот оператор используется для преобразования шестнадцатеричной строки в кодировку base64. Это бывает полезно при обработке вывода функций хэширования md5 и sha-1.
  • ${hexquote:string}
    Этот оператор преобразует непечатаемые символы в строке в шестнадцатеричную форму Escape. Символы с кодами от 33 (!) до 126 (~) включительно остаются как есть, а другие значения будут преобразованы в \xNN. Например, байт со значением 127 будет записан как \x7f.
  • ${lc:string}
    Это переводит буквы в нижний регистр. Например:
    ${lc:$local_part}
    
  • ${length_number:string}
    Оператор length это более простой интерфейс к функции length, которая может использоваться, когда её параметр фиксированное число (в противоположность строкам, динамически строящимся при раскрытии). Эффект тот же самый, что и:
    ${length{number}{string}}
    

    Для получения дополнительной информации, смотрите примечания к основной функции length. Заметьте: length не то же самое, что и strlen. Аббревиатура l может применяться при использовании length в качестве оператора.

  • ${listcount:string}
    Строка интерпретируется как список, будет возвращено число элементов.
  • ${listnamed:name}
    ${listnamed_type:name}
    Здесь name интерпретируется как именованный список, и содержание списка будет возвращено с раскрытием любых списков, на которые ссылаются, с повторным заключением в кавычки по мере необходимости для разделения двоеточий. Если опционально указан type, это должно быть одним из "a", "d", "h" или "l". Этот параметр указывает, в каком списке искать: address, domain, host или localpart. Если это не сделано, все списки просматриваются в случайном порядке и будет возвращен первый соответствующий.
  • ${local_part:string}
    Строка интерпретируется как адрес в соответствии с RFC 2822 и из неё извлекается локальная часть адреса. Если строка не может быть корректно разобрана, то результат пуст.
  • ${mask:IP address/bit count}
    Если формат строки не соответсвует адресу IP и маске через слэш (то есть, сетевой адрес в CIDR-нотации), раскрытие будет неудачным. Иначе этот оператор преобразует IP-адрес в двоичный вид, считая маску от наименьших битов, и проеобразует результат обратно в текстовый вид с прилагаемой маской. Например:
    ${mask:10.111.131.206/28}
    
    вернёт строку 10.111.131.192/28. Так как предполагается, что эта операция, главным образом, будет использоваться для поиска адресов в файлах, результат для IPv6 использует точки для разделения компонентов адреса вместо двоеточий, поскольку двоеточия используются для разделения ключевых строк в lsearch-файлах. Например:
    ${mask:3ffe:ffff:836f:0a00:000a:0800:200a:c031/99}
    
    вернёт строку
    3ffe.ffff.836f.0a00.000a.0800.2000.0000/99
    

    Буквы в адресах IPv6 всегда выводятся в строчном виде.
  • ${md5:string}
    Оператор md5 вычисляет значение хэша MD5-строки и возвращает его как шестнадцатеричное число с 32 цифрами, в котором все буквы в строчном виде.
  • ${nhash_n_m:string}
    Оператор nhash это простой интерфейс к функции числового хэширования, которая может использоваться, когда оба параметра фиксированные числа (в противоположность строкам, динамически строящимся при раскрытии). Эффект точно такой же, как и:
    ${nhash{n}{m}{string}}
    
    Для дополнительных подробностей смотрите описание главного оператора nhash выше.
  • ${quote:string}
    Оператор quote помещает переданный ему параметр в двойные кавычки, если это пустая строка, или содержит что-либо кроме букв, цифр, символа подчёркивания, точек или дефисов. Любые вхождения двойных кавычек и обратного слэша экранируются обратным слэшем. Символы новой строки и возврата каретки преобразуются в \n и \r соответственно. Например,
    ${quote:ab"*"cd}
    
    становится
    "ab\"*\"cd"
    
    Это полезно в местах, где аргументом является замена из переменной или заголовок сообщения.
  • ${quote_local_part:string}
    Этот оператор похож на предыдущий quote за тем исключением, что в кавычки он заключает по правилам RFC 2822 для локальных частей адреса. Например, символ + не вызвал бы заключение в кавычки (но при использовании quote строка была бы помещена в кавычки). Если Вы создаёте новый адрес e-mail из содержимого $local_part (или других неизвестных данных), то всегда должны использовать этот оператор.
  • ${quote_lookup-type:string}
    Этот оператор применяет специфические правила экранирования, помещения в кавычки и замены к строке. Каждый тип запроса имеет свои правила, описанные в главе 9. Например:
    ${quote_ldap:two * two}
    
    вернёт
    two%20%5C2A%20two
    
    Для одноключевых поисков нет необходимости в кавычках и этот оператор вернёт неизменную строку.
  • ${randint:n}
    Этот оператор возвращает случайное число, не меньше 0, которое меньше, чем n. Качество этой хаотичности зависит от того, как Exim был собран. Если Exim собран с OpenSSL, тогда используется RAND_pseudo_bytes(). Иначе может быть выполнен вызов arc4random(), random(), srandomdev(), srandom() или другой вариант, еще более слабый, чем random(). Для генерации ключей не подходит. Если Exim собран с GnuTLS, используется gnutls_rnd(GNUTLS_RND_NONCE).
  • ${reverse_ip:ipaddr}
    Этот оператор полностью инвертирует IP-адрес. Для адресов IPv4 результат будет в форме четырех разделенных точками десятичных чисел. Для IPv6 он будет в шестанадцатеричной форме с точками-разделителями. В обоих случаях это "естественная" форма для DNS. Например:
    ${reverse_ip:192.0.2.4}
    4.2.0.192
    
    ${reverse_ip:2001:0db8:c42:9:1:abcd:192.0.2.3}
    3.0.2.0.0.0.0.c.d.c.b.a.1.0.0.0.9.0.0.0.2.4.c.0.8.b.d.0.1.0.0.2
    
  • ${rfc2047:string}
    Этот оператор кодирует текст, согласно RFC 2047. Это кодирование используется в строках заголовков для кодирования символов не-ASCII. Предполагается, что входная строка находится в кодировке, определённой опцией headers_charset с умолчанием ISO-8859-1. Строки, содержащие символы только в диапазоне 33-126 и не содержащие символов типа:
    ? = ( ) < > @ , ; : \ " . [ ] _
    
    не модифицирутся. В противном случае разультат строка, закодированная в соответствии с RFC 2047, содержащая так много закодированных букв, сколько нужно для кодирования строки.
  • ${rfc2047d:string}
    Этот оператор декодирует строки, которые закодированы согласно RFC 2047. Байты двоичного нуля заменены вопросительными знаками. Символы преобразованы в набор символов, определенный headers_charset. Слишком длинные "слова" RFC 2047 не распознаются, если check_rfc2047_length не установлен в false.
  • ${rxquote:string}
    Оператор rxquote экранирует слэшем все символы, не являющиеся алфавитно-цифровыми. Это применяется, например, для замены значений переменных или заголовков внутри регулярных выражений.
  • ${sha1:string}
    Оператор shal вычисляет хэш SHA-1 строки и возвращает это значение как шестнадцатеричное число с 40 цифрами, в котором все буквы находятся в верхнем регистре.
  • ${sha256:certificate}
    Оператор вычисляет хеш SHA256 сертификата и возвращает его как 64-разрядное шестнадцатеричное число, в котором любые символы находятся в верхнем регистре. Допустима только одна переменная, которая задает сертификат.
  • ${stat:string}
    Строка после раскрытия должна представлять собой путь к файлу. Для этого пути делается вызов функции stat(). Если stat() вернёт ошибку, происходит ошибка раскрытия. Если же она отрабатывает успешно, данные от stat() заменяют элемент в виде ряда пар name=value, где все значения числовые, за исключением значения smode. Имена: mode (даёт режим в виде восьмеричного числа с четыремя цифрами), smode (даёт режим в символическом формате как 10-ти символьную строку, примерно как команда ls), inode, device, links, uid, gid, size, atime, mtime и ctime. Вы можете извлечь отдельные поля с использованием оператора extract. Использование функции stat в файлах фильтров пользователей может быть заблокировано системным администратором. Предупреждение: размер файла может быть неправильным на 32-х разрядных системах для файлов больше 2 Gb размером.
  • ${str2b64:string}
    Этот оператор кодирует строку в кодировку base64.
  • ${strlen:string}
    Этот пункт заменяется длиной строки в десятичном виде. Отметьте: не путайте strlen с length!
  • ${substr_start_length:string}
    Оператор substr это простой интерфейс к функции substr, который может использоваться, когда оба параметра функции представляют собой фиксированные числа (в отличие от раскрываемых строк). Эффект точно такой же, как:
    ${substr{start}{length}{string}}
    
    За дополнительными деталями обратитесь к описанию функции substr. Аббревиатура s может использоваться, когда substr используется как оператор.
  • ${time_eval:string}
    Этот элемент преобразует временные интервалы exim, типа 2d4h5m, в число секунд.
  • ${time_interval:string}
    Параметр (после раскрытия подстроки) должен представлять собой последовательность десятичных цифр, которая представляет собой временной интервал в секундах. Число преобразуется к формату времени exim, например, 1w3d4h2m6s.
  • ${uc:string}
    Преобразует буквы в верхний регистр.
  • ${utf8clean:string}
    Заменяет любую недопустимую последовательность utf-8 в строке символом ?.

11.7. Условия раскрытия

Следующие условия доступны для проверки конструкции ${if при раскрытиии строк:

  • !condition
    Восклицательный знак перед любым условием приводит результат условия к противоположному.
  • symbolic operator {string1}{string2}
    Есть несколько символических операторов для проведения операций сравнения:
    ОператорЗначение
    =равно
    ==равно
    >больше
    >=больше или равно
    <меньше
    <=меньше или равно
    Например:
    ${if >{$message_size}{10M} ...
    
    Заметьте, что можно проверять неравенство оператором отрицания (!). Обе строки должны принимать форму десятичных чисел опционально используя K или M (в заглавном или строчном виде), что будет означать умножение на 1024 или на 1024*1024 соответственно.
  • bool {string}
    Это условие конвертирует строку, содержащую истинное или ложное представление в булево значение. Распознаются (без учета регистра) true, false, yes и no. Также положительные целые числа отображаются на истину, если отличны от нуля, и на ложь, если ноль. Пробелы игнорируются. Все другие строковые значения приведут к отказу раскрытия. Когда объединено с переменными ACL, это позволит Вам принимать решения в одном месте и воздействовать на те решения в другом месте. Например:
    ${if bool{$acl_m_privileged_sender} ...
    
  • bool_lax {string}
    Как и bool, превращает строку в булево значение. Но где bool принимает строгий набор строк, bool_lax использует то же самое свободное определение, которое использует опция condition маршрутизации. Пустая строка и "ложные" значения (false, no и 0) превратятся в ложь, все другие отображаются на истину. Заметьте что, bool{00} false, но bool_lax{00} тем не менее true. Пробелы игнорируются.
  • crypteq {string1}{string2}
    Это сравнение включено в исполняемый файл exim, если он собран с поддержкой механизмов аутентификации (смотрите часть 33). Иначе необходимо определить SUPPORT_CRYPTEQ в Local/Makefile для включения crypteq в исполняемый файл exim. Оператор crypteq имеет два аргумента. Содержимое первого шифруется и сравнивается с вторым, который уже зашифрован. Вторая строка может быть в форме хранения шифрованных строк в LDAP, которые начинаются с фигурных скобок, содержащих условие (алгоритм). Если вторая строка не начинается с {, предполагается, что алгоритм шифрования crypt() или crypt16() (смотрите ниже), так как такие строки не могут начинаться на {. Обычно это поле из файла паролей. Пример зашифрованной строки в формате LDAP:
    {md5}CY9rzUYh03PK3k6DJie09g==
    
    Если такая строка появляется непосредственно в раскрытой строке, то фигурные скобки должны быть указаны, поскольку они часть синтаксиса. Например:
    ${if crypteq {test}{\{md5\}CY9rzUYh03PK3k6DJie09g==}{yes}{no}}
    
    Следующие типы шифрования (их имена не зависят от регистра) поддерживаются:
    • {md5} вычисляет MD5-сумму первой строки и представляет её в виде набора печатных символов для сравнения с остатком от второй строки. Если длина сравниваемой строки 24 символа, exim предполагает, что она закодирована base64 (как в примере выше). Если длина 32 символа, exim предполагает, что это шестнадцатиричное кодирование MD5. Если же длина не 24 и не 32, сравнение оканчивается неудачей.
    • {sha1} вычисляет SHA-1-сумму первой строки, представляет её в печатном виде и сравнивает с остатком от второй строки. Если длина сравнения 28 символов, exim предполагает, что это закодировано base64. Если длина 40 символов, предполагается, что это шестнадцатиричное кодирование суммы SHA-1. Если же длина не 28 и не 40, сравнение оканчивается неудачей.
    • {crypt} вызывает функцию crypt(), которая традиционно использовала только первые восемь символов пароля. Однако, во многих современных ОС это уже не так и используется весь пароль, несмотря на его длину.
    • {crypt16} вызывает функцию crypt16() (также известную как bigcrypt()), которая изначально была создана для использования первых 16 символов пароля. Опять же, в современных ОС может использоваться больше символов. Exim имеет собственную версию crypt16() (которая является просто двойным вызовом функции crypt()). Для ОС, которые имеют свою версию, установка HAVE_CRYPT16 в Local/Makefile при сборке exim заставляет его использовать версию из ОС, а не собственную. Эта опция включена по умолчанию в ОС-зависимом Makefile для тех операционных систем, про которые известно, что они поддерживают crypt16(). Если Вы не помещаете тип криптования в фигурные скобки при сравнении crypteq, значение по умолчанию также {crypt} или {crypt16}, как определено установкой опции DEFAULT_CRYPT в Local/Makefile. Значение по умолчанию {crypt}. Вне зависимости от значения по умолчанию, Вы можете использовать любую функцию явно указав её в фигурных скобках. Заметьте, что если пароль не более восьми символов длинной, то результат его шифрования функциями crypt() и crypt16() идентичен. Это означает что crypt16() обратно совместим до тех пор, пока ему не передадут пароль длинней восьми символов.
  • def:variable name
    Условие def может содержать имя одной из раскрываемых переменных, заданных в главе 11.9. Условие истинно, если переменная не содержит пустую строку. Например:
    ${if def:sender_ident {from $sender_ident}}
    
    Заметьте, что имя переменной задаётся без начального символа $. Если переменная не существует, то раскрытие неудачно.
  • def:header_header name: или def:h_header name:
    Это условие истинно, если сообщение обрабатывается, а указанный заголовок в нём существует. Например:
    ${if def:header_reply-to:{$h_reply-to:}{$h_from:}}
    
    Заметьте: символ $ появляется в условии до header_ или h_, и имя заголовка должно оканчиваться заголовком, если за ним не идёт пустое место (пробелы и прочее).
  • eq {string1}{string2}
    Вначале раскрываются подстроки. Условие истинно, если получившиеся подстроки идентичны, в том числе и в регистре букв.
  • eqi {string1}{string2}
    Вначале раскрываются подстроки. Условие истинно, если получившиеся подстроки идентичны, сравнение проводится без учёта регистра букв.
  • exists {file name}
    Подстрока раскрывается, затем интерпретируется как абсолюный путь. Условие истинно, если существует указанный каталог или файл. Проверка существования осуществляется вызовом функции stat(). Использование проверки exists в пользовательских фильтрах может быть отключено системным администратором.
  • first_delivery
    Это условие, не имеющее никаких данных, является истинным в течение первой попытки доставки сообщения. Во время любых последующих попыток доставки оно будет ложным.
  • forall {список}{выражение}
    Смотрите forany.
  • forany {список}{выражение}
    Эти условия повторяют по списку. Первый параметр раскрыт, чтобы сформировать список. По умолчанию, разделителем элементов списка является двоеточие, но это может быть изменено нормальным методом. Второй параметр интерпретируется как условие, которое должно быть применено к каждому элементу в списке. Во время интерпретации условия текущий элемент списка помещен в переменную $item. Для forany интерпретация останавливается, если условие истинно для какого-либо элемента, и результат всего условия также истина. Если условие ложно для всех элементов в списке, все условие ложно. Для forall интерпретация останавливается, если условие ложно для какого-либо элемента, и результат всего условия ложен. Если условие истинно для всех элементов в списке, то и все условие истинно. Заметьте, что отрицание forany означает, что условие должно быть ложным для всех элементов, а вот отрицание forall означает, что условие должно быть ложным по крайней мере для одного элемента. В этом примере разделитель элементов списка изменен на запятую:
    ${if forany{<, $recipients}{match{$item}{^user3@}}{yes}{no}}
    
    Значение $item сохранено и восстановлено, в то время как forany или forall обрабатываются, чтобы позволить этим элементам расширения быть вложенными.
  • ge {string1}{string2}
    Смотрите gei.
  • gei {string1}{string2}
    Вначале раскрываются обе подстроки. Условие истинно, если первая строка лексически больше второй или равна ей. Для ge сравнение производится с учётом регистра, а для gei сравнение не зависит от регистра букв.
  • gt {string1}{string2}
    Смотрите gti.
  • gti {string1}{string2}
    Вначале раскрываются обе подстроки. Условие истинно, если первая строка лексически больше второй. Для gt сравнение производится с учётом регистра, а для gti сравнение не зависит от регистра букв.
  • inlist {string1}{string2}
    Смотрите inlisti.
  • inlisti {string1}{string2}
    Раскрыты обе строки. Вторая строка обработана как список простых строк. Если первая строка член списка из второй, то условие истина. Это более простая в применении версия более мощного forany. Например:
    ${if inlist{needle}{foo:needle:bar}}
    ${if forany{foo:needle:bar}{eq{$item}{needle}}}
    
    ${if inlisti{Needle}{fOo:NeeDLE:bAr}}
    ${if forany{fOo:NeeDLE:bAr}{eqi{$item}{Needle}}}
    
  • isip {string}
    Смотрите isip6.
  • isip4 {string}
    Смотрите isip6.
  • isip6 {string}
    Вначале подстрока раскрывается, затем проверяется, имеет ли она форму адреса IP. Оба адреса, IPv4 и IPv6, действительны для isip, тогда как isip4 и isip6 проверяют лишь адреса IPv4 и IPv6 соответственно. Например, можно использовать:
    ${if isip4{$sender_host_address}...
    
    для проверки версии протокола IP хоста, с которого осуществляется входящее SMTP-подключение.
  • ldapauth {ldap query}
    Это условие поддерживает пользовательскую аутентификацию с использованием LDAP. Смотрите главу 9.13 для получения дополнительных деталей о том, как использовать LDAP в поисках, и каков синтаксис запросов. Для этого использования запрос должен содержать имя пользователя и пароль. Сам запрос не используется, он может быть пустым. Условие истинно, если пароль не пуст, а имя пользователя и пароль приняты сервером LDAP. Пустой пароль отбрасывается без вызова LDAP, поскольку LDAP считает соединения с пустым паролем анонимными, вне зависимости от имени пользователя, согласно настройкам в большинстве конфигураций. Смотрите раздел 33 для получения дополнительных деталей о SMTP-аутентификации и раздел 34 для примеров использования.
  • le {string1}{string2}
    Смотрите lei.
  • lei {string1}{string2}
    Вначале раскрываются обе подстроки. Условие истинно, если первая строка лексически меньше или равна второй. Для le сравнение производится с учётом регистра, а для lei сравнение не зависит от регистра букв.
  • lt {string1}{string2}
    Смотрите lti.
  • lti {string1}{string2}
    Вначале раскрываются обе подстроки. Условие истинно, если первая строка лексически меньше второй. Для lt сравнение производится с учётом регистра, а для lti сравнение не зависит от регистра букв.
  • match {string1}{string2}
    Вначале раскрываются обе подстроки. Вначале вторая обрабатывается как регулярное выражение. Из-за предварительного раскрытия, если регулярное выражение содержит символ $ или символы, начинающиеся с обратного слэша, они должны быть экранированы. Также следует проявить внимание, если регулярное выражение содержит фигурные скобки. Закрывающая скобка должна стоять так, чтобы не вызывать преждевременного завершения string2. Самый лёгкий подход заключается в использовании \N для отключения раскрытия регулярного выражения. Например:
    ${if match {$local_part}{\N^\d{3}\N} ...
    
    Если вся раскрываемая строка находится в двойных кавычках, требуется дальнейшее экранирование обратных слэшей. Условие истинно, если регулярное выражение срабатывает. Регулярное выражение не обязано начинаться с метасимвола циркумфлекса (^), но если его нет, выражение не поставлено на якорь и может соответствовать не только в начале строки, но и где-то в другом месте. Если Вы хотите добиться соответствия шаблона в конце объекта, необходимо включить метасимвол $ в соответствующем месте. В начале раскрытия if запоминаются значения числовых переменных ($1). Удовлетворение условия match сбрасывает их к подстрокам этого условия, они будут иметь эти значения в процессе раскрытия успешной подстроки. В конце if предыдущие значения будут восстановлены. После проверки комбинации использования условий or последующие значения числовых переменных взяты из условия, которое было успешным.
  • match_address {string1}{string2}
    Смотрите match_local_part.
  • match_domain {string1}{string2}
    Смотрите match_local_part.
  • match_ip {string1}{string2}
    Это условие проверяет IP-адрес на соответствие списку шаблонов IP-адресов. Оно должно содержать два параметра. Первый параметр после раскрытия должен быть IP-адресом или пустой строкой. Второй (после раскрытия) ограниченным списком хостов, который может соответствовать только IP-адресу, но не имени хоста. Например:
    ${if match_ip{$sender_host_address}{1.2.3.4:5.6.7.8}{...}{...}}
    
    В списке разрешаются определённые типы элементов, согласно списку:
    • Адрес IP опционально с маской CIDR.
    • Отдельная звёздочка, соответствующая любому IP-адресу.
    • Пустой пункт, который совпадает только в случае, если IP-адрес пуст. Это может быть полезным для проверки локально отправленных сообщений или одного из специфических хостов в одной проверке, типа:
      ${if match_ip{$sender_host_address}{:4.3.2.1:...}{...}{...}}
      
      где первый элемент в списке пустая строка.
    • Элемент @[] совпадает с любым из адресов на интерфейсах локальной машины.
    Поиск предполагает стиль поиска net-, даже если net- не задан. Таким образом, следующие два примера эквивалентны:
    ${if match_ip{$sender_host_address}{lsearch;/some/file}...
    ${if match_ip{$sender_host_address}{net-lsearch;/some/file}...
    
    Вам нужно использовать приставку net- в случае, если нужно задать определённую маску, например, при использовании net24. Просмотрите раздел 10.11 для получения дополнительных деталей по этим шаблонам.
  • match_local_part {string1}{string2}
    Это условие вместе с match_address и match_domain позволяет проверить домен, адрес и локальную часть. Каждое условие требует двух аргументов: элемент и список соответствия. Тривиальный пример:
    ${if match_domain{a.b.c}{x.y.z:a.b.c:p.q.r}{yes}{no}}
    
    В каждом случае второй аргумент может содержать любой из допустимых пунктов для списка соответствующего типа. Кроме того, поскольку второй параметр представляет собой список стандартной формы, можно обратится к именованному списку. Таким образом, можно использовать такие условия:
    ${if match_domain{$domain}{+local_domains}{...}}
    
    Для списка адресов совпадения не зависят от регистра, но может использоваться элемент +caseful, как во всех списках, если хотите, чтобы локальная часть совпадала регистрозависимо. Имя домена всегда сравнивается регистронезависмо.
    Отметьте: списки хостов тут не поддерживаются. Причина в том, что хост имеет два идентификатора: имя и IP-адрес, и не ясно, какой из них тут использовался бы для проверки. Тем не менее, проверку IP-адресов можно провести, используя match_ip.
    Отметьте: string2 самостоятельно не раскрывается, чтобы представить расширение в виде строки, если Exim не был создан с опцией EXPAND_LISTMATCH_RHS.
  • pam {string1:string2:...}
    Подключаемые Модули Аутентификации (Pluggable Authentication Modules http://www.kernel.org/pub/linux/libs/pam/) представляют собой средство, которое стало доступно в последних выпусках Solaris, некоторых реализациях GNU/Linux и во FreeBSD. Exim поддерживает PAM для использования с командой SMTP AUTH только в случае, если он собран с SUPPORT_PAM=yes в Local/Makefile. Вероятно, будет необходимо добавить -lpam к EXTRALIBS, а в некоторых реализациях GNU/Linux также будет необходим -ldl. Вначале раскрываются аргументы строки, результатом должен быть список, разделённый двоеточиями. Начальное и конечное пустое пространство игнорируется. Модуль PAM инициализируется с сервисным именем exim и именем пользователя, взятым из первого элемента списка в строке, разделённой двоеточиями (string1). Остающиеся в строке пункты передаются в ответ на запросы функции опознания. В простом случае будет лишь один запрос пароля, таким образом данные будут содержать лишь две строки. Могут быть проблемы, если в любой из строк разрешено содержатся двоеточию. Обычно они должны быть удвоены, чтобы избежать возможности быть разделителями. Если данные вставляются из переменной, может использоваться функция sg для удвоения любых существующих двоеточий. Например, конфигурация аутентификатора LOGIN может содержать эти настройки:
    server_condition = ${if pam{$1:${sg{$2}{:}{::}}}{yes}{no}}
    
    Для PLAIN-аутентификатора можно использовать:
    server_condition = ${if pam{$2:${sg{$3}{:}{::}}}{yes}{no}}
    
    В некоторых операционных системах PAM-аутентификация может быть сделана только от процесса, работающего от пользователя root. Так как exim выполняется от пользователя exim при приёме сообщений, то это означает, что PAM не может непосредствено использоваться в таких системах. Пропатченная версия модуля pam_unix, который идёт с пакетом Linux PAM, доступна на http://www.e-admin.de/pam_exim/. Пропатченный модуль разрешает одной специальной комбинации uid/gid, дополнительно к root, аутентифицироваться. Если Вы собираете пропатченный модуль для того, чтобы разрешить пользователя и группу exim, PAM сможет использоватся в аутентификаторе exim.
  • pwcheck {string1:string2}
    Это выражение поддерживает аутентификацию пользователей с использованием демона аутентификации Cyrus pwcheck. Это один из способов проверить пароли процессом, не запущенным от root. Заметьте: сейчас использование pwcheck не рекомендуется. Его замена saslauthd (смотрите ниже). Поддержка pwcheck не включена в exim по умолчанию. Вы должны задать местоположение сокета демона pwcheck в Local/Makefile до сборки exim. Например:
    CYRUS_PWCHECK_SOCKET=/var/pwcheck/pwcheck
    
    Нет необходимости устанавливать всё программное обеспечение Cyrus для использования демона pwcheck. Вы можете собрать и установить только демон из библиотеки Cyrus SASL. Обеспечьте, чтобы пользователь exim был единственным пользователем, имеющим доступ к каталогу, где лежит сокет демона pwcheck. У условия pwcheck один аргумент, который является именем пользователя и паролем, разделёнными двоеточием. Например, для аутентификации типа LOGIN можно сделать так:
    server_condition = ${if pwcheck{$1:$2}{1}{0}}
    
  • queue_running
    Это условие не имеет данных и является истинным в течение попыток доставки сообщения, инициированными процессом доставки, и ложным в другие моменты.
  • radius {authentication string}
    Аутентификация Radius (RFC 2865) поддерживается похожим на PAM способом. Вы должны определить опцию RADIUS_CONFIG_FILE в Local/Makefile для задания местоположения конфигурационного файла Radius при сборке exim. При установке только этой опции exim ожидает, что будет скомпонован с библиотекой radiusclient с использованием оригинального API. Если же используется релиз этой библиотеки 0.4.0 или более поздний, то нужно установить опцию:
    RADIUS_LIB_TYPE=RADIUSCLIENTNEW
    
    в Local/Makefile при сборке exim. Также можно скомпоновать exim с библиотекой libradius, идущей в составе FreeBSD. Для использования этого установите:
    RADIUS_LIB_TYPE=RADLIB
    
    в Local/Makefile в дополнение к установленной опции RADIUS_CONFIG_FILE. Также, вероятно, надо будет настроить EXTRALIBS, чтобы библиотека Radius была найдена при компоновке exim. Строка, определённая в RADIUS_CONFIG_FILE, раскрывается и передаётся клиентской библиотеке Radius, которая связывается с сервером Radius. Условие истинно, если аутентификация успешна. Например:
    server_condition = ${if radius{arguments}{yes}{no}}
    
  • saslauthd {{user}{password}{service}{realm}}
    Это выражение поддерживает аутентификацию пользователей с использованием демона Cyrus saslauthd. Он заменяет демон pwcheck, который больше не поддерживается. Использование этого демона один из способов проверки паролей процессом, работающим не от root. Поддержка saslauthd не включена в exim по умолчанию. Вы должны указать местоположение сокета демона saslauthd в Local/Makefile до сборки exim. Например:
    CYRUS_SASLAUTHD_SOCKET=/var/state/saslauthd/mux
    
    Нет необходимости устанавливать всё программное обеспечение Cyrus для использования демона saslauthd. Вы можете собрать и установить только демон из библиотеки Cyrus SASL. До четырёх аргументов могут использоваться с выражением saslauthd, но только два обязательны. Например:
    server_condition = ${if saslauthd{{$1}{$2}}{1}{0}}
    
    Сервис и окружение являются опциональными параметрами (поэтому их параметры находятся в собственной паре фигурных скобок). Для деталей по этой службе и о том, как запустить демона, обратитесь к документации по Cyrus.

11.8. Комбинирование условий раскрытия

Несколько условий могут быть проверены за один раз, объединив их условиями and и or. Заметьте, что условия and и or представляют собой самостоятельные полноценные условия и предшествуют своим спискам шаблонов. Каждое подусловие должно находится внутри фигурных скобок вместе с общими фигурными скобками, в которых находится список. Не должно быть повторений, если используется условие if.

  • or {{cond1}{cond2}...}
    Подусловия оцениваются слева направо. Условие истинно, если одно из подусловий истинно. Например:
    ${if or {{eq{$local_part}{spqr}}{eq{$domain}{testing.com}}}...
    
    Когда находится истинное подусловие, то остальные парсятся, но не оцениваются. Если имеется несколько подусловий match, значения числовых переменных берутся от того, которое первым будет успешно.
  • and {{cond1}{cond2}...}
    Подусловия оцениваются слева направо. Условие истинно, если все подусловия верны. Если есть несколько подусловий match, значения числовых переменных берутся от последнего. Если найдено ложное подусловие, остальные парсятся, но не оцениваются.
  • 11.9. Переменные раскрытия

    Этот раздел содержит алфавитный список всех переменных раскрытия. Некоторые из них доступны только тогда, когда exim собран со специфическими опциями, типа поддержки TLS или опцией контентного сканирования.

  • $0, $1, и т.д.
    Когда успешно условие match, эти переменные содержат фиксированные подстроки, идентифицированные по регулярному выражению в ходе последующего анализа успешной строки, содержащей элемент if. Также они могут быть установлены внешне некоторыми другими процессами, предшествующими раскрытию строки. Например, команды доступные в файлах фильтрa exim, включают команду if с её собственным регулярным выражением, соответствующим условию.
  • $acl_c0 - $acl_c19
    Значения могут быть помещены в эти переменные при помощи модификатора set в ACL. Значения сохраняются на протяжении всей жизни SMTP-подключения. Они могут использоваться для передачи информации между ACL и различными запросами того же самого ACL. После получения сообщения, значения переменных сохраняются вместе с сообщением и могут использоваться в фильтрах, роутерах и транспортах в течение последующей доставки.
  • $acl_m0 - $acl_m19
    Значения могут быть помещены в эти переменные при помощи модификатора set в ACL. Они сохраняют их значения, пока сообщение в процессе получения, но сбрасываются после получения. Они также сбрасываются командами MAIL, RSET, EHLO, HELO и после начала сессии TLS. После получения сообщения значения переменных сохраняются вместе с сообщением и могут использоваться в фильтрах, роутерах и транспортах в течение последующей доставки.
  • $acl_narg
    Эта переменная хранит число параметров раскрываемого элемента, выражения или правила acl.
  • $acl_verify_message
    После неудачной проверки адреса эта переменная содержит сообщение об отказе. Она сохраняет своё значение для использования в последующих модификаторах. Сообщение может быть использовано в коде, типа такого:
    warn !verify = sender
         set acl_m0 = $acl_verify_message
    
    Вы можете использовать $acl_verify_message в процессе раскрытия модификаторов message или log_message для включения информации о причине отказа.
  • $address_data
    Эта переменная устанавливается посредством опции address_data в роутере. В процессе обработки последующими маршрутизаторами и транспортами значение остаётся с адресом. Если транспорт обрабатывает много адресов, используется значение первого адреса. Смотрите главу 15 для получения дополнительных деталей. Отметьте: содержимое переменной $address_data доступно в файлах пользовательских фильтров. Если $address_data установлена, когда роутер вызывает ACL для проверки адреса получателя, конечное значение всё ещё находится в переменной для последующих условий и модификаторов ACL. Если роутинг сделал переадресацию только к одному адресу, дочерний адрес также роутится как часть проверки, и в этом случае окончательное содержимое $address_data получено из дочернего процесса. Если $address_data установлена, когда роутер вызывает ACL для проверки адреса отправителя, окончательное значение также сохраняется, но на этот раз в переменной $sender_address_data, чтобы можно было отличить от данных адреса получателя. В обоих случаях (проверки получателя и отправителя), значение не сохраняется после конца текущей проверки ACL. Если необходимо сохранить их дальше, то можно сохранить их в переменных ACL.
  • $address_file
    Когда в результате алиасинга, форвардинга или фильтрации сообщение направлено в специфический файл, эта переменная содержит имя файла, пока выполняется транспортировка. В другое время переменная пуста. Например, используя конфигурацию по умолчанию, у пользователя r2d2 в файле .forward содержится:
    /home/r2d2/savemail
    
    То, когда работает транспорт address_file, переменная $address_file содержит /home/r2d2/savemail. Для фильтров Sieve значение может быть inbox или относительным именем каталога. Так продолжается до запуска транспорта, который построит абсолютный путь к необходимому файлу.
  • $address_pipe
    Когда в результате алиасинга или форвардинга сообщение направляется в канал (pipe), переменная содержит команду канала, пока работает транспорт.
  • $auth1 - $auth3
    Эти переменные используются в SMTP-аутентификаторах (смотрите разделы 34-37). В других местах они пусты.
  • $authenticated_id
    Когда сервер полностью аутентифицирует клиента, то это может быть сконфигурировано для сохранения части аутентификационной информации в переменной $authenticated_id (смотрите раздел 33). Например, конфигурация аутентификатора user/password могла бы сохранить имя пользователя для использования в роутерах. Отметьте, что это не та же самая информация, которая сохраняется в $sender_host_authenticated. Когда сообщение посылается локально, а не через TCP-соединение, переменная $authenticated_id содержит имя пользователя, вызвавшего процесс.
  • $authenticated_fail_id
    Когда попытка аутентификации терпит неудачу, переменная $authenticated_fail_id будет содержать id неудачной аутентификации. Если был предпринят больше, чем один id аутентификации, то переменная будет содержать только последний. Переменная доступна для обработки в ACL, обычно quit или notquit ACL. Сообщение локальному получателю тем не менее может быть принято не требуя аутентификации, что означает, что эта переменная также видима во всех ACL вообще.
  • $authenticated_sender
    Когда exim работает как сервер, он берёт во внимание параметр AUTH= для поступающей SMTP-команды MAIL, если отправителю можно доверять, как описано в 33.2. Если данные не являются строкой, устанавливается, что сообщение шлёт аутентифицированный отправитель, а значение доступно в процессе доставки в переменной $authenticated_sender. Если отправитель не доверенный, exim принимает синтаксис AUTH=, но игнорирует данные. Когда сообщение отправляется локально (не через TCP-соединение), значение переменной $authenticated_sender является адресом, сконструированным из имени пользователя и значения переменной $qualify_domain.
  • $authentication_failed
    Эта переменная устанавливается в 1 в сервере exim, если клиент использует команду AUTH, которая не успешна. Иначе она устанавливается в 0. Это позволяет различить "did not try to authenticate" (не пробовал провести аутентификацию: $sender_host_authenticated пуста, $authentication_failed равна нулю) и "tried to authenticate but failed" (пробовал провести аутентификацию, но безуспешно: $sender_host_authenticated пуста, а $authentication_failed равна единице). Отказ включает любой отрицательный ответ на команду AUTH, включая (к примеру) попытку использовать неизвестный/неопределённый аутентификационный механизм.
  • $av_failed
    Эта переменная доступна, когда Exim собран с расширением контентного сканирования. Это установлено в 0 по умолчанию, но будет установлено в 1, если какая-либо проблема происходит с вирусным сканером (определенным av_scanner) во время ACL malware.
  • $body_linecount
    Когда сообщение передаётся или принимается, эта переменная содержит число строк тела сообщения. Смотрите также $message_linecount.
  • $body_zerocount
    Когда сообщение передаётся или принимается, эта переменная содержит число нулевых байт в теле сообщения.
  • $bounce_recipient
    В этой переменной устанавливатеся адрес получателя рикошета, когда exim его создаёт. Полезно, если используется настраиваемый текстовый файл (смотрите раздел 45).
  • $bounce_return_size_limit
    Эта переменная содержит значение опции bounce_return_size_limit, округлённой к числу, кратному 1000. Полезно, если используется настраиваемый текстовый файл ошибок сообщений (смотрите раздел 45 ).
  • $caller_gid
    Содержится реальный id той группы, под которой выполнялся процесс exim. Это не тоже самое, что и gid создателя сообщения (смотрите $originator_gid). Если exim перезапускает себя, эта переменная в нормальном состоянии содержит gid exim.
  • $caller_uid
    Реальный uid пользователя, под которым выполняется процесс exim. Это не тоже самое, что и uid создателя сообщения (смотрите $originator_uid). Если exim перезапускает себя, эта переменная в нормальнос состоянии содержит uid exim.
  • $compile_date
    Дата, когда был скомпилирован двоичный файл exim.
  • $compile_number
    Процесс сборки exim сохраняет число раз, сколько он был скомпилирован. Это позволяет отличить другие компиляции одной и той же версии программы.
  • $demime_errorlevel
    Эта переменная доступна, когда exim собран с поддержкой контентного сканирования и вышедшим из употребления условием demime. Детали смотрите в 40.6.
  • $demime_reason
    Эта переменная доступна, когда exim собран с поддержкой контентного сканирования и вышедшим из употребления условием demime. Детали смотрите в 40.6.
  • $dnslist_domain
    Когда для клиентского хоста найдена запись в списке DNS, имя домена помещается в эту переменную, чтобы можно было включить эту информацию в сообщение об ошибке.
  • $dnslist_text
    Когда для клиентского хоста найдена запись в списке DNS, содержание любой ассоциированной TXT-записи помещается в эту переменную.
  • $dnslist_value
    Когда для клиентского хоста найдена запись в списке DNS, IP-запись для ресурса помещается в эту переменную. Если запесей много, то все адреса включаются, разделённые запятыми с пробелами.
  • $domain
    Когда адрес маршрутизируется или самостоятельно доставляется, эта переменная содержит имя домена. Глобальная перезапись адреса происходит когда сообщение получено, таким образом значение $domain в течение марщрутизации и доставки задает значение после перезаписи. Переменная $domain установлена во время пользовательской фильтрации, но не во время системной фильтрации, поскольку сообщение может иметь много получателей, а системный фильтр вызывают только один раз. Когда доставляется больше одного адреса за раз (например, несколько команд RCPT в одном SMTP-соединении), $domain установлена лишь в случае, если все они имеют один и тот же домен. Транспорты могут быть ограничены обработкой только одного домена за раз, если значение $domain требуется во время работы транспорта: это значение по умолчанию для локальных транспортов. Для дополнительных деталей о переменных окружения во время выполнения транспортировки смотрите главу 23. В конце доставки, если все отсроченные адреса имеют один домен, он помещается в $domain в процессе раскрытия delay_warning_condition. Переменная $domain также используется при некоторых других обстоятельствах:
    • Когда выполняется ACL для команды RCPT, переменная $domain содержит домен адреса получателя. Домен адреса отправителя находится в $sender_address_domain во время команд MAIL и RCPT. Переменная $domain обычно не устанавливается во время работы MAIL ACL. Однако, если адрес отправителя проверен при помощи callout в процессе MAIL ACL, домен отправителя помещается в $domain в процессе раскрытия hosts, interface и port в транспорте smtp.
    • Во время обработки перезаписи (смотрите раздел 31) переменная $domain содержит доменную часть адреса, который перезаписывается. Это может быть использовано в раскрытии адреса замены, например, для замены домена поиском по файлу.
    • Каждый раз когда просматривается список доменов, за одним исключением, $domain содержит обрабатываемый домен. Исключение: Когда список доменов в условии sender_domains обрабатывается в ACL, обрабатываемый домен содержится в $sender_address_domain, а не в $domain. Так сделано для того, чтобы в RCPT ACL список доменов отправителя мог зависеть от домена получателя (который в это время содержится в $domain).
    • Когда раскрывается опция smtp_etrn_command, переменная $domain содержит полный параметр команды ERTN (смотрите раздел 44.8).
  • $domain_data
    Когда опция domains на маршрутизаторе совпадает с доменом, найденным поиском, данные, прочитанные поиском, доступны во время работы роутера как $domain_data. Кроме того, если драйвер направляет адрес в транспорт, то значение доступно и в транспорте. Если транспорт обрабатывает много адресов, используется значение из первого адреса. Переменная $domain_data также устанавливается, когда выражение domains в ACL совпадает с доменом, найденным поиском. Данные, прочитанные поиском, доступны в остальной части условия ACL. Во всех других случаях эта переменная ничего не содержит.
  • $exim_gid
    Эта переменная содержит числовое значение gid группы от имени которой работает exim.
  • $exim_path
    Эта переменная содержит путь к двоичному файлу exim.
  • $exim_uid
    Эта переменная содержит числовое значение uid пользователя от имени которого работает exim.
  • $found_extension
    Эта переменная доступна, когда exim собран с поддержкой контентного сканирования и устаревшим условием demime. За дополнительными деталями обратитесь к разделу 40.6.
  • $header_ name
    Это не строгая переменная раскрытия. Это синтаксис раскрытия для вставки строки заголовка сообщения с указанным именем. Заметьте, что имя может оканчиватся двоеточием или пробелом, поскольку оно может содержать разнообразные символы. Также заметьте, что фигурные скобки не должны использоваться.
  • $headers_added
    В пределах ACL эта переменная содержит заголовки, добавленные до сих пор модификатором ACL add_header в виде списка. Разделителем элементов является новая строка.
  • $home
    Когда в роутере установлена опция check_local_user, в случае успешной проверки домашний каталог пользователя помещается в переменную $home. В частности, это означает, что она установлена в процессе выполнения фалов фильтров пользователей. Роутер также может явно установить основной домашний каталог для использования транспортом. Это может быть отменено непосредственной установкой транспорта. Когда работает тест фильтра, через опцию -bf в $home устанавливается значение перемeнной окружения HOME.
  • $host
    Когда транспорт smtp раскрывает опции для шифрования с использованием TLS, $host содержит имя приконнектившегося хоста. Аналогично, когда используется клиентская часть конфигурации аутентификации (смотрите раздел 33), переменная $host содержит имя сервера, к которому подключился клиент. Когда используется транспортный фильтр (смотрите раздел 24), $host содержит участвующий в текущем соединении. Когда локальный транспорт запущен как результат роутера, который устанавливает список хостов, $host содержит имя первого хоста.
  • $host_address
    Эта переменная содержит IP-адрес удалённого хоста каждый раз, когда устанавливается $host для удалённого соединения. Также в неё устанавливается IP-адрес, проверяемый в опции ignore_target_hosts.
  • $host_data
    Если выражение $hosts в ACL удовлетворяется посредством поиска, результат поиска становится доступен в переменной $host_data. Это позволяет делать, например, такие вещи:
    deny hosts = net-lsearch;/some/file
    message = $host_data
    
  • $host_lookup_deferred
    В нормальном состоянии эта переменная содержит 0, что делает $host_lookup_failed. Когда сообщение приходит с удалённого хоста и производится попытка поиска имени хоста по его IP-адресу, и если попытка безуспешна, эта переменная устанавливается в 1. Если поиск получает какой-то отрицательный ответ (например, поиск в DNS успешен, но записей не найдено), $host_lookup_failed устанавливается в 1. Если во время поиска происходят какие-то проблемы, такие, что в итоге exim не может утверждать, задано ли имя хоста (например, таймаут поиска в DNS), $host_lookup_failed устанавливается в 1. Поиск имени хоста по его IP-адресу содержит больше, чем просто один обратный поиск. Exim проверяет полученное имя в обратную сторону: приведёт ли оно к оригинальному IP-адресу. Если это не так, exim не принимает найденное имя, а переменная $host_lookup_failed устанавливается в 1. Таким образом, возможность находить имя по IP-адресу (например, PTR-запись в DNS) не является достаточным условием для успешного поиска имени хоста. Если обратный поиск успешен, но есть проблемы с прямым поиском, например, таймаут, то имя не принимается, и $host_lookup_deferred устанавливается в 1. Смотрите также $sender_host_name.
  • $host_lookup_failed
    Смотрите $host_lookup_deferred.
  • $inode
    Единственный момент времени, когда эта переменная установлена: раскрытие опции directory_file в транспорте appendfile. Переменная содержит номер индекса временного файла, который должен быть переименован. Это может использоваться для создания уникального имени файла.
  • $interface_address
    Ныне эта опция устарела и оставлена только для совместимости. Вместо нее надлежит использовать $received_ip_address.
  • $interface_port
    Ныне эта опция устарела и оставлена только для совместимости. Вместо нее надлежит использовать $received_port.
  • $ldap_dn
    Эта переменная доступна, лишь если exim собран с поддержкой LDAP и содержит DN для последнего успешного поиска в LDAP.
  • $load_average
    Эта переменная содержит среднюю загрузку системы, умноженную на 1000, и является целым числом. Например, если загрузка 0.21, то значение переменной 210. Значение пересчитывается каждый раз, когда ссылаются на эту переменную.
  • $local_part
    Когда адрес маршрутизируется или доставляется владельцу, эта переменная содержит локальную часть адреса. Когда идёт одновременная доставка нескольких адресов (например, несколько команд RCPT в SMTP-сессии), переменная $local_part не задана. Глобальная перезапись адресов происходит при получении сообщения, таким образом, значение $local_part в ходе маршрутизации и доставки представляет собой значение после перезаписи. $local_part устанавливается во время работы пользовательского фильтра, но не во время работы системного, потому что сообщение может иметь много получателей, а системный фильтр вызывается лишь один раз. Если локальная часть префикса или суффикса была успешно разобрана, то это не включается в значение $local_part в процессе маршрутизации и последующей доставки. Значения любой приставки или суффикса находятся в $local_part_prefix и $local_part_suffix соответственно. Когда сообщение доставляется в файл, канал или транспорт автоответа в результате алиасинга или форвардинга, $local_part устанавливается в локальную часть родительского адреса, а не в имя файла или команды (смотрите $address_file и $address_pipe). Когда ACl запускается для команды RCPT, $local_part содержит локальную часть адреса получателя. Когда срабатывает перезапись (смотрите раздел 31), $local_part содержит локальную часть адреса, который перезаписывается, это может быть использовано, например, в раскрытиях замены адреса. Во всех регистрах все кавычки удаляются из локальной части. Например, оба адреса
    "abc:xyz"@test.example
    abc\:xyz@test.example
    
    дадут значение $local_part.
    abc:xyz
    
    Если Вы используете $local_part для создания других адресов, Вы всегда должны обрабатывать его в операторе quote. Например, в переадресовывающем роутере можно сделать так:
    data = ${quote_local_part:$local_part}@new.domain.example
    
    Отметьте: обычно значение $local_part в нижнем регисте, если Вы хотите обрабатывать локальные части в роутере в регистрозависимой манере, Вы должны установить опцию caseful_local_part (смотрите раздел 15).
  • $local_part_data
    Когда опция local_part на роутере совпадает с локальной частью, найденной поиском, данные, прочитанные поиском, доступны в ходе выполнения роутара как $local_part_data. Кроме того, если драйвер маршрутизирует адрес в транспорт, значение доступно и в транспорте. Если транспорт обрабатывает много адресов, используется значение первого адреса. Переменная $local_part_data также устанавливается, когда local_part в ACL совпадает с локальной частью, найденной поиском. Данные, прочитанные поиском, доступны в остальной части ACL. Во всех других ситуациях значение переменной пустое.
  • $local_part_prefix
    Когда адрес маршрутизируется или доставляется владельцу, и распознан специфический префикс для локальной части, он доступен в этой переменной, удалённой из $local_part.
  • $local_part_suffix
    Когда адрес роутится или доставляется владельцу и распознан специфический суффикс для локальной части, он доступен в этой переменной, удалённой из $local_part.
  • $local_scan_data
    Эта переменная содержит текст, возвращённый функцией local_scan() при получении сообщения. За дополнительными деталями обратитесь к разделу 41.
  • $local_user_gid
    Смотрите $local_user_uid.
  • $local_user_uid
    В эту переменную и $local_user_gid устанавливаются значения uid и gid после успешного предварительного условия check_local_user в роутере. Это означает, что их значения доступны для остальных, неотработавших, предварительных условий (senders, require_files и condition) для раскрытия address_data и других, специфичных для роутера условий. В любой другой момент времени значения в этих переменных (uid_t)(-1) и (gid_t)(-1), соответственно.
  • $localhost_number
    Тут содержится раскрытое значение опции localhost_number. Это раскрытие происходит после прочтения основных опций.
  • $log_inodes
    Число свободных inode в дисковом разделе, куда пишутся протоколы exim. Это значение пересчитывается каждый раз, когда ссылаются на эту переменную. Если файловая система не знает, что такое inode, значение переменной равно -1. Также смотрите опцию check_log_inodes.
  • $log_space
    Размер свободного места (в килобайтах) на дисковом разделе, в который пишутся протоколы exim. Это значение пересчитывается каждый раз, когда ссылаются на эту переменную. Если операционная система не имеет понятия "размер свободного пространства" (истинно для экспериментальных систем), значение переменной равно -1. Также смотрите опцию check_log_space.
  • $mailstore_basename
    Эта переменная устанавливается только при работе доставки в формате mailstore в транспорт appendfile. В процессе раскрытия опций mailstore_prefix, mailstore_suffix, message_prefix и message_suffix она содержит имена записываемых файлов, то есть имя без суффикса .tmp, .env или .msg. В любое другое время переменная пуста.
  • $malware_name
    Эта переменная доступна, когда exim скомпилирован с поддержкой контентного сканирования. Она устанавливается в имя вируса, который был найден, когда условие malware ACL истинно (глава 40.1).
  • $max_received_linelength
    Эта переменная содержит число байт в самой длинной строке, которая была получена как часть сообщения, не считая символы завершения строки.
  • $message_age
    Эта переменная устанавливается в начале попытки доставки сообщения в число секунд с тех пор, как сообщение было получено. Оно не изменяется в течение одной попытки доставки.
  • $message_body
    Во время доставки эта переменная содержит начальную часть сообщения и предназначена, главным образом, для файлов фильтра пользователей. Максимальное число символов тела сообщения, помещаемое в переменную, устанавливается конфигурационной опцией message_body_visible, по умолчанию это 500. Символы новой строки преобразуются в пробелы для облегчения поиска фраз, которые были разбиты по переводу строки. Двоичные нули также преобразовываются в пробелы.
  • $message_body_end
    Во время доставки эта переменная содержит конец тела сообщения. Формат и максимальный размер такой же, как и у $message_body.
  • $message_body_size
    Во время доставки эта переменная содержит размер тела сообщения в байтах. Счёт начинается с символа после пустой строки, отделяющей заголовки от сообщения. Смотрите также $message_size, $body_linecount и $body_zerocount.
  • $message_exim_id
    Когда сообщение получается или доставляется, эта переменная содержит уникальный идентификатор сообщения, генерируемый и используемый exim для идентификации сообщения. Идентификатор не создаётся для сообщения до тех пор, пока его заголовок не получен. Заметьте: это не содержимое строки заголовка Message-ID:, а локальный идентификатор, назначаемый exim сообщению, например, 1BXTIK-0001yO-VA.
  • $message_headers
    Эта переменная содержит все строки заголовка во время обработки сообщения, за исключением строк, добавленных роутерами и транспортами. Строки заголовка разделены символами новой строки.
  • $message_headers_raw
    Эта переменная содержит все строки заголовка во время обработки сообщения, за исключением строк, добавленных роутерами и транспортами. Строки заголовка разделены символами новой строки. Отличие от $message_headers в том, что там выполняется декодирование контента, согласно RFC2047. Здесь никакого декодирования не выполняется.
  • $message_id
    Это старое название $message_exim_id, которое теперь не используется.
  • $message_linecount
    Эта переменная содержит общее количество строк в заголовке и теле сообщения. Сравните с $body_linecount, содержащей лишь число строк в теле сообщения. В процессе DATA и ACL занимающихся контентным сканированием $message_linecount содержит число полученных строк. До доставки (перед фильтрами, маршрутизаторами, роутерами и транспортами) счётчик увеличен, чтобы включить строку заголовка Received: стандартно добавляемую exim, и любые другие заголовки, добавляемые ACL. Пустая строка, отделяющая заголовки от тела сообщения, не подсчитывается. Вот пример использования этой переменной в DATA ACL:
    deny message = Too many lines in message header
    condition = ${if <{250} \
                {${eval:$message_linecount - $body_linecount}}}
    
    В MAIL и RCPT ACL значение этой переменной ноль, поскольку на этих стадиях сообщение ещё не получено.
  • $message_size
    Когда сообщение находится в процессе обработки, эта переменная содержит число байт. В большинстве случаев размер включает те заголовки, которые были получены с сообщением, но не те (типа Envelope-to:), которые были добавлены индивидуальными доставкми. Однако, есть один специальный случай: в процессе раскрытия опции maildir_tag в транспорте appendfile, когда доставка происходит в формате maildir, значение $message_size задает точный размер файла, который был записан на диск. Смотрите также $message_body_size, $body_linecount и $body_zerocount. При выполнении ACL во время команды SMTP RCPT $message_size содержит размер, предоставленный командой MAIL, или -1, если он не был предоставлен. Разумеется, значение может быть неверным или заведомо ложным.
  • $mime_xxx
    Множество переменных с именами, начинающимися на $mime, доступны в случае, если exim собран с поддержкой контентного сканирования. Для дополнительных делалей смотрите раздел 40.4.
  • $n0 - $n9
    Эти переменные пердставляют собой счётчики, которые могут быть увеличены при помощи команды add в файлах фильтров.
  • $original_domain
    Когда адрес верхнего уровня обрабатывается для доставки, эта переменная содержит то же самое значение, что и $domain. Однако, если "дочерний" адрес (например, сгенерированный алиасом, форвардом или файлом фильтра) обрабатывается, эта переменная содержит доменную часть оригинального адреса. Это отличается от $parent_domain только когда здесь больше одного уровня алиасинга или форвардинга. Когда происходит доставка более чем по одному адресу в одном транспорте, переменная $original_domain не установлена. Если новый адрес создан с помощью команды deliver в системном фильтре, то эта переменная установлена с искусственным "родительским" адресом. В таком случае локальная часть system-filter, а доменная является доменом по умолчанию из настроек.
  • $original_local_part
    Когда адрес верхнего уровня обрабатывается для доставки, эта переменная содержит то же самое значение, что и $local_part за исключением ситуации, если суффикс или префикс были удалены из локальной части, поскольку $original_local_part всегда содержит полную локальную часть. Когда дочерний адрес (например, сгенерированный алиасом, форвардом или файлом фильтра) обрабатывается, эта переменная содержит полную локальную часть оригинального адреса. Если роутер (процесс переназначения) нечувствителен к регистру локальной части адреса, значение $original_local_part в нижнем регистре букв. Эта переменная отличается от $parent_local_part только в случае, если больше одного уровня алиасинга или форвардинга. Когда происходит доставка более чем по одному адресу в одном транспорте, переменная $original_local_part не установлена. Если новый адрес создан с помощью команды deliver в системном фильтре, эта переменная установлена с искусственным родительским адресом. В таком случае локальная часть system-filter, а доменная является доменом по умолчанию из настроек.
  • $originator_gid
    Эта переменная содержит значение переменной $caller_uid, установленной при получении сообщения. Для сообщений, полученных через командную строку, это gid пославшего его пользователя. Для сообщений, полученных через TCP/IP, это обычно gid пользователя от которого работает exim.
  • $parent_domain
    Эта переменная подобна $original_domain (смотрите выше) за исключением того, что относится непосредственно к предыдущему родительскому адресу.
  • $parent_local_part
    Эта переменная подобна $original_local_part (смотрите выше) за исключением того, что относится непосредственно к предыдущему родительскому адресу.
  • $pid
    Эта переменная содержит идентификатор процесса текущего процесса.
  • $pipe_addresses
    Это не раскрываемая переменная, но она упомянута тут, поскольку строка $pipe_addresses обрабатывается специально в командной спецификации для транспорта pipe (раздел 29) и в транспортных фильтрах (описанных как transport_filter в разделе 24 ). Она не может использоваться в основных строках раскрытия и вызывает ошибку "неизвестная переменная", если с ней там сталкиваются.
  • $primary_hostname
    Эта переменная содержит значение, установленное пунктом primary_hostname в конфигурационном файле или прочитанное функцией uname(). Если uname() возвращает однокомпонентное имя, то exim вызывает функцию gethostbyname() (или getipnodebyname(), какая доступна) в попытке получить полное имя хоста. Смотрите также $smtp_active_hostname.
  • $prvscheck_address
    Эта переменная используется вместе с элементом раскрытия "prvscheck", который описан в разделах 11.5 и 39.38.
  • $prvscheck_keynum
    Эта переменная используется вместе с элементом раскрытия prvscheck, который описан в разделах 11.5 и 39.38.
  • $prvscheck_result
    Эта переменная используется вместе с элементом раскрытия prvscheck, который описан в разделах 11.5 и 39.38.
  • $qualify_domain
    Значение этой переменной устанавливается опцией qualify_domain из конфигурационного файла.
  • $qualify_recipient
    Значение этой переменной устанавливается опцией qualify_recipient из конфигурационного файла или, если там не задано, значением $qualify_domain.
  • $rcpt_count
    Когда сообщение получается по SMTP, эта переменная содержит число команд RCPT, переданных для текущего сообшения. Если эта переменная используется в RCPT ACL, то её значение включает текущую команду.
  • $rcpt_defer_count
    Когда сообщение получается по SMTP, эта переменная содержит число команд RCPT в текущем сообщении, которые были ранее отклонены с временным (4xx) ответом.
  • $rcpt_fail_count
    Когда сообщение получается по SMTP, эта переменная содержит число команд RCPT в текущем сообщении, которые были ранее отклонены с постоянным (4xx) ответом.
  • $received_count
    Эта переменная содержит число заголовков Received: в сообщении, включая один, добавленный exim (таким образом, это значение всегда больше нуля). Оно доступно в DATA ACL, в не-SMTP ACL и во время роутинга и доставки.
  • $received_for
    Если во входящем сообщении только один адрес получателя, то эта переменная содержит адрес из строки заголовка Received: после её получения. Значение копируется после перезаписи адреса получателя, но до запуска функции local_scan().
  • $received_ip_address
    Как только сервер начинает обрабатывать TCP/IP соединение, эта переменная принимает значение IP-адреса локального интерфейса, а в переменную $received_port пишется номер порта. Поэтому эти значения доступны для использования в connect ACL. Также смотрите опцию командной строки -oMi. Как присутствующая в ACL, эта переменная может использоваться, например, для создания имени файла для сертификата TLS, зависящего от того, какой порт/интерфейс используется.
  • $received_port
    См. подробности в описании опции $received_ip_address.
  • $received_protocol
    При обработке сообщения эта переменная содержит имя протокола по которому получено сообщение. Большинство имён, используемых exim, определено RFC 821, RFC 2821 и RFC 3848. Они начинаются с smtp (клиент использовал HELO) или esmtp (клиент использовал EHLO). Они могут содержать s, если было безопасное (шифрованное) соединение и/или a для аутентифицированных. Таким образом, если получается протокол esmtpsa, то сообщение было передано по шифрованному SMTP-соединению, а клиент был успешно аутентифицирован. Exim использует имя протокола smtps для случая, когда шифрование автоматически включается при соединении без использования STARTTLS (смотрите tls_on_connect_ports, а клиент использует HELO для начала шифрованного сеанса SMTP. Имя smtps также используется для редкой ситуации, когда клиент первоначально использует EHLO, устанавливает шифрованное соединение, используя STARTTLS, а затем использует HELO. Опция -oMr обеспечивает возможность определить имя протокола для сообщений, которые отправлены локально от доверенных отправителей. Обычно это используется для идентификации сообщений, которые повторно иньектятся после сканирования.
  • $received_time
    Эта переменная содержит дату и время, когда текущее сообщение было получено, в виде секунд с начала эпохи Unix.
  • $recipient_data
    Эта переменная устанавливается после успешного индексного поиска в выражении ACL recipients. Она содержит данные из поиска, значение остаётся установленным до следующей проверки recipients. Таким образом, можно делать такие вещи:
    require recipients = cdb*@;/some/file
    deny some further test involving $recipient_data
    
    Внимание; Эта переменная установлена только в случае, если поиск как метод индексации в списке адресов с использованием синткаксиса точки с запятой, как в примере. Переменная не установлена для поиска, который используется как часть раскрытия строки, которому все такие списки подвергаются до интерпретации.
  • $recipient_verify_failure
    В ACL, когда проверка получателя неудачна, эта переменная содержит информацию об ошибке. Это может быть одно из следующих слов:
    • qualify: Адрес был неполный (нет домена), сообщение не являлось ни локальным, ни прибывшим от неучтённого хоста.
    • route: Неудачная маршрутизация.
    • mail: Маршрутизация была удачной и был предпринят обратный вызов, а отклонение произошло до команды MAIL (при начальном подключении, HELO или MAIL).
    • recipient: Команда RCPT в обратном вызове была отклонена.
    • postmaster: Была отклонена проверка postmaster в обратном вызове.
    Ожидаемое главное использование этой переменной: для различения режектов MAIL и режектов RCPT.
  • $recipients
    Эта переменная содержит список получателей сообщения. Адреса разделяются запятыми и пробелами в тексте замены. Однако, переменная не является общедоступной для предотвращения просмотра Bcc-получателей в непривелигированных пользовательских фильтрах. Вы можете использовать $recipients только в этих двух случаях:
    • 1. В файле системного фильтра.
    • 2. В ACL ассоциированных с командой DATA, то есть ACL определённые как acl_smtp_predata и acl_smtp_data.
  • $recipients_count
    В процессе обработки сообщения эта переменная содержит число получателей сообщения, которые шли с сообщением (имеется в виду, что тут не учтены получатели, добавленные в процессе обработки). Дубликаты не исключаются из подсчёта. Во время приёма сообщения по SMTP число увеличивается для каждого принятого получателя.
  • $reply_address
    В процессе обработки сообщения в этой переменной находится содержимое строки заголовка Reply-To:, если она существует и не пуста, иначе она содержит значение из строки заголовка From:. Кроме удаления начального пустого пространства, эта переменная никак не обрабатывается. В частности, не производится расшифровка по RFC 2047 или символьная замена кода.
  • $return_path
    Во время доставки сообщения, эта переменная содержит обратный путь (поле отправителя), посылаемый как часть конверта. Оно не заключено в символы "<>". В начале маршрутизации адреса $return_path установлена в то же значение, что и $sender_address, но если, например, входящее сообщение листа рассылки раскрыто роутером, определяющим другой адрес для возврата, то впоследствии $return_path содержит другой адрес возврата, тогда как $sender_address всегда содержит оригинальный адрес отправителя, полученный с сообщением. Если сказать по-другому, $sender_address содержит адрес отправителя входящего конверта, а $return_path содержит адрес исходящего конверта.
  • $return_size_limit
    Это устаревшее название $bounce_return_size_limit.
  • $router_name
    Во время выполнения маршрутизатора эта переменная содержит его имя.
  • $runrc
    Эта переменная содержит код возврата команды, выполненой в элементе раскрытия "${run...}". Предупреждение: В роутере или транспорте Вы не можете предположить порядок раскрытия опций за исключением тех предварительных условий, чей порядок тестирования задокументирован. Поэтому невозможно ожидать установки $runrc в раскрытии одной опции и использовать её в другой.
  • $self_hostname
    Когда адрес направлен к возможному удалённому хосту, тут устанавливается локальный хост, этот случай контролируется общей опцией self роутера. Одно из его значений заставляет передать адрес другому роутеру. Когда такое происходит, значение $self_hostname будет именем локального хоста, с которым столкнулся роутер. При других обстоятельствах оно будет пустым (null).
  • $sender_address
    При обработке сообщения эта переменная содержит адрес отправителя, полученный в конверте сообщения. Для возвращаемых сообщений значение будет пустой строкой. Смотрите также $return_path.
  • $sender_address_data
    Если переменная $address_data установлена, когда роутеры вызываются из ACL для проверки адреса отправителя, то окончательное значение сохраняется в $sender_address_data для возможности отличить его от адреса получателя. Значение не сохраняется после окончания текущей ACL. Если необходимо сохранять его дольше, то Вы можете сохранить его в переменных ACL.
  • $sender_address_domain
    Доменная часть $sender_address.
  • $sender_address_local_part
    Локальная часть $sender_address.
  • $sender_data
    Эта переменная устанавливается после успешного поиска в условии ACL senders или в опции senders роутера. Оно содержит данные поиска, и значение остаётся установленным до следующей проверки senders. Таким образом, можно делать такие вещи:
    require senders = cdb*@;/some/file
    deny some further test involving $sender_data
    
    Внимание: Эта переменная установлена только в случае, если поиск используется как метод индексации в списке адресов, используя синтаксис точки с запятой, как в примере выше. Переменная не установлена для поиска, который использует часть строки раскрытия, которому подвергаются все списки, до интерпретации.
  • $sender_fullhost
    Когда сообщение получено от удалённого хоста, эта переменная содержит имя хоста и адрес IP в одной строке. Она заканчиватся IP-адресом в квадратных скобках с номером порта через двоеточие, если включено логирование портов. Формат остальной части строки зависит от того, какая была SMTP-команда хоста: HELO или EHLO, и было ли подверждено имя хоста поиском по его IP-адресу. Поиск IP-адреса модет быть вызыван опцией host_lookup, независимой от проверки. Простое имя хоста в начале строки задает проверенное имя хоста: если оно отсутствует, проверка не проводилась или не требовалась. Имя хоста в круглых скобках задает параметр команды HELO или EHLO. Оно пропущено, если оно идентично проверенному имени хоста или IP-адресу в квадратных скобках.
  • $sender_helo_name
    Когда сообщение получено с удалённого хоста, давшего команду HELO или EHLO, аргумент этой команды помещается в эту переменную. Также оно устанавливается, если HELO или EHLO использовалось при локальном SMTP с опциями -bs или -bS.
  • $sender_host_address
    Когда сообщение получено от удалённого хоста, эта переменная содержит IP-адрес удалённого хоста. Для локальных сообщений значение пустое.
  • $sender_host_authenticated
    Эта переменная содержит имя (не публичное имя) драйвера аутентификации, который успешно подтвердил подлинность клиента, от которого получено сообщение. Оно пустое, если аутентификации не было. Смотрите также $authenticated_id.
  • $sender_host_name
    Когда сообщение передаётся с удалённого хоста, эта переменная содержит имя хоста, полученное поиском по его IP-адресу. Для сообщений, полученных другими способами, эта переменная пуста. Если имя хоста предварительно не искалось, ссылка на $sender_host_name вызывает поиск (для сообщений с удалённых хостов). Найденное имя принимается только если оно, при прямом поиске по нему, возвращает оригинальный IP. Если прямой или обратный поиск не могут найти какие-то данные, или если прямой поиск не приводит к первоначальному IP, то $sender_host_name остаётся пустым, а $host_lookup_failed устанавливается в 1. Однако, если любой из поисков не может быть завершён (например, произошёл таймаут DNS), $host_lookup_deferred устанавливается в 1, а $host_lookup_failed остаётся установленным в 0. Когда $host_lookup_failed установлена в 1, exim не пробует снова найти имя хоста при наличии информации о $sender_host_name в другом процессе exim, но он пробует ещё раз, если $host_lookup_deferred установлена в 1. Exim не ищет автоматически каждое имя хоста. Если Вы хотите максимальной эффективности, Вы должны упорядочить Вашу конфигурацию так, чтобы вообще избежать этого поиска. Поиск происходит лишь в случае, если одно или больше условий истинны:
    • Строка, содержащая $sender_host_name, раскрыта.
    • Хост, с которого идёт запрос, совпадает со списком host_lookup. В конфигурации по умолчанию эта опция установлена в *, для устранения поиска надо этот пункт изменить (закомментировать, в самом коде эта опция по умолчанию не включена).
    • Exim нуждается в имени хоста для проверки элемента в списке хостов. Пункты, которые требуют этого, описаны в разделах 10.13 и 10.15.
    • Хост запроса соответствует helo_try_verify_hosts или helo_verify_hosts. В этом случае имя хоста требует сравнения с именем, указанным в командах EHLO или HELO, отданных клиентом.
    • Удалённый хост даёт команду EHLO или HELO, которая содержит один из доменов в helo_lookup_domains. Значение по умолчанию этой опции:
      helo_lookup_domains = @ : @[]
      
      и она вызывает поиск лишь в случае, если удалённый хост некорректно отдал имя сервера или IP-адрес в команде EHLO или HELO.
  • $sender_host_port
    Когда сообщение получено с удалённого хоста, эта переменная содержит номер порта, использовавшегося удалённым хостом.
  • $sender_ident
    Когда сообщение получено с удалённого хоста, эта переменная содержит идентификацию переданную в ответ на запрос по RFC 1413. Когда сообщение получено локально, эта переменная содержит имя пользователя вызвавшего exim.
  • $sender_rate_xxx
    Множество переменных, имена которых начинаются с $sender_rate_, установленных как часть условия ACL ratelimit. Детали смотрите в главе 39.30.
  • $sender_rcvhost
    Это необходимо для использования в заголовках Received:. Она начинается с любого проверенного имени хоста (полученного обратным поиском в DNS) или, если нет проверенного имени, IP-адресом в квадратных скобках. После этого в круглых скобках может быть текст. Когда первый пункт задает проверенное имя хоста, первый элемент в круглых скобках явно IP-адрес в квадратных скобках с номером порта через двоеточие, если разрешено логирование портов. Когда первый элемент IP-адрес, то порт записывается внутри круглых скобок, в виде "port=xxxx". Также могут быть пункты вида "helo=xxxx", если использовались HELO или EHLO, и их параметр не был идентичен реальному имени хоста или IP, или "ident=xxxx", если доступна строка ident из RFC 1413. Если все три элемента присутствуют в круглых скобках, в строку вставляется символ новой строки и символ табуляции для улучшения читабельности заголовка Received:.
  • $sender_verify_failure
    В ACL, когда проверка отправителя неудачна, эта переменная содержит информацию об ошибке. Детали такие же, как и у $recipient_verify_failure.
  • $sending_ip_address
    Эта переменная установлена всякий раз, когда было установлено исходящее SMTP-соединение с другим узлом. Это содержит IP-адрес локального интерфейса, который для этого используется. Это полезно, если узел, у которого есть больше одного IP-адреса, хочет использовать разную логику для интерфейсов. Для входящих соединений см. $received_ip_address.
  • $sending_port
    Эта переменная установлена всякий раз, когда было установлено исходящее SMTP-соединение с другим узлом. Это содержит локальный порт соединения. Для входящих соединений см. $received_port.
  • $smtp_active_hostname
    Во время сеанса SMTP эта переменная содержит значение имени активного хоста, определённого опцией smtp_active_hostname. Значение $smtp_active_hostname сохраняется с любым переданным сообщением и его значение можно использовать во время роутинга и доставки.
  • $smtp_command
    В процессе обработки входящей SMTP команды эта переменная содержит всю команду. Это позволяет различать HELO и EHLO в ACL, а иакже различать команды, типа:
    MAIL FROM:<>
    MAIL FROM: <>
    
    Для команды MAIL могут быть просмотрены дополнительный параметры, типа SIZE. Для команды RCPT адрес в $smtp_command задает оригинальный адрес до любой перезаписи, тогда как значения в $local_part и $domain взяты из адреса после SMTP-перезаписи.
  • $smtp_count_at_connection_start
    Эта переменная установлена более, чем в 0 только в процессах, порожденных демоном Exim для того, чтобы обработать поступающие соединения SMTP. Имя сознательно длинное, чтобы подчеркнуть содержание. Когда демон принимает новое соединение, он увеличивает эту переменную. Копию переменной передают дочернему процессу, который обрабатывает соединение, но его значение никогда не меняется. Это только приближение того, сколько фактически было поступающих соединения, потому что много соединений могут прийти и уйти в то время, как единственное соединение обрабатывается. Когда дочерний процесс заканчивается, демон уменьшает значение своей копии переменной.
  • $sn0 - $sn9
    Эти переменные представляют собой копии значений $n0-$n9, сумматоры, бывшие в конце файла системного фильтра. Это позволяет системному фильтру устанавливать значения, которые могут быть проверены в файлах фильтров пользователей. Например, системный фильтр мог установить значение, указывающее, что это сообщение, вероятно, является спамом.
  • $spam_xxx
    Множество переменных с именами, начинающимися с $spam, доступны, если exim скомпилирован с расширением контентного сканирования. Для дополнительных деталей смотрите секцию 40.2.
  • $spool_directory
    Имя каталога спула для exim.
  • $spool_inodes
    Число свободных inоde в дисковом разделе, где exim держит свои spool-файлы. Значение пересчитывается каждый раз, когда к нему обращаются. Если файловая система не имеет понятия inode, то значение будет -1. Также смотрите опцию check_spool_inodes.
  • $spool_space
    Количество свободного места (как число килобайт) в дисковом разделе, где пишутся spool-файлы exim. Значение пересчитывается каждый раз, когда на переменную ссылаются. Если операционная система не может подсчитать количество свободного места (истинно для экспериментальных систем), то значение будет -1. Например, чтобы проверить в ACL, что есть хотя бы 50 мегабайт свободного места в спуле можно написать:
    condition = ${if > {$spool_space}{50000}}
    
    Также смотрите опцию "check_spool_space".
  • $thisaddress
    Эта переменная установлена только в процессе обработки команды foranyaddress в файле фильтра. Её использование объясняется в описании той команды, которая может быть найдена в документации на интерфейс фильтрации почты exim.
  • $tls_in_bits
    Содержит приближение разрядности шифра TLS на входящем соединении, значение этого зависит от используемой реализации TLS. Если о TLS не договорились, значение будет 0. Значение этого автоматически берется из аутентификатора Cyrus SASL, работающего как сервер, чтобы определить "внешний SSF" (термин SASL).

    Устаревшая переменная $tls_bits относится к входящей стороне кроме тех случаев, когда используется в контексте исходящей доставки SMTP, тогда это относится к исходящему трафику.

  • $tls_out_bits
    Содержит приближение разрядности шифра TLS на исходящем соединении, значение этого зависит от используемой реализации TLS. Если о TLS не договорились, значение будет 0. Значение этого автоматически берется из аутентификатора Cyrus SASL, работающего как сервер, чтобы определить "внешний SSF" (термин SASL).

  • $tls_in_ourcert
    Когда сообщение было получено, эта переменная обращается к сертификату входящего соединения. Это полезно только как параметр элемента раскрытия certextract, операторов md5, sha1 или условия def.
  • $tls_in_peercert
    Когда сообщение было получено, эта переменная обращается к сертификату входящего соединения. Это полезно только как параметр элемента раскрытия certextract, операторов md5, sha1 или условия def.
  • $tls_out_ourcert
    Когда сообщение было получено, эта переменная обращается к сертификату входящего соединения. Это полезно только как параметр элемента раскрытия certextract, операторов md5, sha1 или условия def.
  • $tls_out_peercert
    Когда сообщение было получено, эта переменная обращается к сертификату входящего соединения. Это полезно только как параметр элемента раскрытия certextract, операторов md5, sha1 или условия def.
  • $tls_in_certificate_verified
    Эта переменная установлена в 1, если при приёме сообщения сертификат TLS проверен и 0 в обратном случае.

    Устаревшая переменная tls_certificate_verified относится к входящей стороне кроме тех случаев, когда используется в контексте исходящей доставки SMTP, тогда это относится к исходящему трафику.

  • $tls_out_certificate_verified
    Эта переменная установлена в 1, если сертификат TLS проверен при исходящем соединении SMTP и 0 в обратном случае.
  • $tls_in_cipher
    Когда сообщение получено с удалённого хоста по шифрованному SMTP-подключению, эта переменная содержит использовавшийся тип шифрования, например, DES-CBC3-SHA. При других обстоятельствах, в частности, для сообщения, полученного по незашифрованным подключениям, переменная пуста. Смотрите главу 38 для подробностей о поддержке TLS. Тестирование $tls_cipher на пустоту является одним из способов различить зашифрованные и незашифрованные соединения во время обработки ACL.

    Устаревшая переменная $tls_cipher совпадает с $tls_in_cipher во время приема сообщений, но в контексте исходящей доставки SMTP, имеющей место через транспорт smtp, становится тем же самым, что и $tls_out_cipher.

  • $tls_out_cipher
    Эта переменная очищена, прежде чем сделано соединение SMTP, а затем установлена в коммуникабельный набор шифров, если они согласованы.
  • $tls_in_ocsp
    Когда сообщение получено, результат любого запроса OCSP от клиента закодирован в этой переменной:
    0 OCSP не запрошен (значение по умолчанию).
    1 Нет ответа на запрос.
    2 Ответ не верифицирован.
    3 Ошибка верификации.
    4 Верификация успешно проведена.
    
  • $tls_out_ocsp
    Когда сообщение отправлено, результат любого запроса OCSP от клиента закодирован в этой переменной. См. подробности в описании $tls_in_ocsp.
  • $tls_in_peerdn
    Когда сообщение получено с удалённого хоста по шифрованному SMTP-подключению, и exim сконфигурирован для запроса сертификата с клиента, значение переменной определяет имя сертификата, доступное в ней в процессе последующей обработки.

    Устаревшая переменная $tls_peerdn относится к входящей стороне кроме тех случаев, когда используется в контексте исходящей доставки SMTP, тогда это относится к исходящему трафику.

  • $tls_out_peerdn
    Когда сообщение передано удалённому хосту по зашифрованному SMTP-подключению, а exim сконфигурирован для запроса сертификата с клиента, значение переменной определяет имя сертификата, доступное в ней в процессе последующей обработки.
  • $tls_in_sni
    Когда сеанс TLS устанавливается, если клиент пошлет расширение Server Name Indication, то значение будет помещено в эту переменную. Если переменная появится в tls_certificate, то эта опция и некоторые другие, будут повторно раскрыты в сеансе TLS, чтобы разрешить использовать другой сертификат (и опционально будет использован другой ключ) клиенту, основанному на значении SNI. Значение будет сохранено для всей жизни сообщения.

    Устаревшая переменная $tls_sni относится к входящей стороне кроме тех случаев, когда используется в контексте исходящей доставки SMTP, тогда это относится к исходящему трафику.

  • $tls_out_sni
    Во время исходящих доставок SMTP эта переменная отражает значение опции tls_sni на транспорте.
  • $tod_bsdinbox
    Время и дата в формате почтового ящика BSD, например: Thu Oct 17 17:14:09 1995.
  • $tod_epoch
    Время и дата в виде числа секунд с начала эпохи Unix.
  • $tod_epoch_l
    Время и дата в виде числа микросекунд с начала эпохи Unix.

  • $tod_full
    Полная версия времени и даты, например: Wed, 16 Oct 1995 09:51:40 +0100. Временной пояс всегда даётся как часовое смещение от UTC с положительными значениями для поясов, которые впереди (к востоку), и отрицательных значений для тех, которые позади (на западе).
  • $tod_log
    Время и дата в формате используемом exim в его протоколах, например: 1995-10-12 15:32:29, но без временной зоны.
  • $tod_logfile
    Эта переменная содержит дату в формате yyyymmdd. Этот формат используется для штампа даты в файлах протоколов, когда log_file_path содержит флаг %D.
  • $tod_zone
    Эта переменная содержит числовое значение локальной временной зоны, например: -0500.
  • $tod_zulu
    Эта переменная содержит дату и время в формате Zulu, как задано в ISO 8601, например: 20030221154023Z.
  • $transport_name
    Во время выполнения транспорта эта переменная содержит его имя.
  • $value
    Эта переменная содержит результат раскрытия поиска, операции извлечения или внешней команды, как описано выше.
  • $version_number
    Номер версии exim.
  • $warn_message_delay
    Эта переменная установлена только в течение создания предупредительного сообщения о задержке доставки. Детали по её использованию раскрыты в разделе 45.2.
  • $warn_message_recipients
    Эта переменная установлена только в течение создания предупредительного сообщения о задержке доставки. Детали по её использованию раскрыты в разделе 45.2.
  • Поиск

     

    Найди своих коллег!