dnl dnl проверка писем на вирусы dnl dnl # dnl # поля переменной $acl_m_avir_notification для передачи параметров dnl # антивирусной квитанции в системный фильтр: dnl # 1. список получателей квитанции dnl # 2. название антивируса dnl # 3. название вируса dnl # 4. имя файла в каратине dnl # 5. адрес антивирусного администратора, которому пользователи dnl # могут отсылать запросы на получение писем из карантина dnl # 6. полный список получателей зараженного письма dnl # 7. boundary для квитации dnl # ifelse_strstr(SECTION, `ACL_CHECK_RCPT', `dnl ifelse_strstr(confAV_NOTIFY, `RCPT', `dnl ifelse(confAV_NOTIFY_SKIP_RCPT, `YES', `dnl _ARG_ ! recipients = @@wildlsearch;CONFDIR/skip_avir_notify_rcpt set acl_m_avir_notification = ${if eq{$acl_m_avir_notification}{}{<$local_part@$domain>}\ {$acl_m_avir_notification, <$local_part@$domain>}} ') ') dnl ifelse_strstr(confAV_NOTIFY, `RCPT', `') ') dnl ifelse_strstr(SECTION, `ACL_CHECK_RCPT', `') ifelse(SECTION, `ACL_CHECK_DATA', `dnl ifdef(`_AV_NO', ` define(`_AV_TMP', `eval(_AV_NO + 1)') define(`_AV_NO', _AV_TMP) ',` define(`_AV_NO', `0') define(`_AV_DEFER_NEXT_PREV', `') ') define(`_AV_DLFUNC_NAME', `confANTIVIRUS'_AV_NO`_DLFUNC_NAME')dnl define(`_AV_DLFUNC_PARAM', `confANTIVIRUS'_AV_NO`_DLFUNC_PARAM')dnl define(`_AV_ACT', `confANTIVIRUS'_AV_NO`_ACT')dnl define(`_AV_NAME', `confANTIVIRUS'_AV_NO`_NAME')dnl define(`_AV_SCAN', `confANTIVIRUS'_AV_NO`_SCAN')dnl define(`_AV_OPT', `confANTIVIRUS'_AV_NO`_OPT')dnl dnl define(`_AV_NAME_CMD', `confANTIVIRUS'_AV_NO`_NAME_CMD')dnl undefine(`_AV_NAME_CMD_TMP')dnl define(`_AV_NAME_CMD_TMP', `confANTIVIRUS'_AV_NO`_NAME_CMD')dnl define(`_AV_NAME_CMD', `truncate_by_char(_AV_NAME_CMD_TMP, chr10)')dnl dnl define(`_AV_NAME_DEFAULT', `confANTIVIRUS'_AV_NO`_NAME_DEFAULT')dnl undefine(`_AV_NAME_DEFAULT_TMP')dnl define(`_AV_NAME_DEFAULT_TMP', `confANTIVIRUS'_AV_NO`_NAME_DEFAULT')dnl define(`_AV_NAME_DEFAULT', `truncate_by_char(_AV_NAME_DEFAULT_TMP, chr10)')dnl dnl define(`_AV_MAX_SIZE', `confANTIVIRUS'_AV_NO`_MAX_SIZE')dnl undefine(`_AV_MAX_SIZE_TMP')dnl define(`_AV_MAX_SIZE_TMP', `confANTIVIRUS'_AV_NO`_MAX_SIZE')dnl define(`_AV_MAX_SIZE', `truncate_by_char(_AV_MAX_SIZE_TMP, chr10)')dnl ifelse_strstr(_AV_OPT,`defer_next',` define(`_AV_DEFER_NEXT_', `YES') ',` define(`_AV_DEFER_NEXT_', `NO') ') ifelse_strstr(_AV_OPT,`defer_no_mbox_unspool',` define(`_AV_DEFER_NO_MBOX_UNSPOOL_', `YES') ',` define(`_AV_DEFER_NO_MBOX_UNSPOOL_', `NO') ') ifelse_strstr(_AV_OPT,`defer_freeze',` define(`_AV_DEFER_FREEZE_', `YES') ',` define(`_AV_DEFER_FREEZE_', `NO') ') ifelse_strstr(_AV_OPT,`defer_ok',` define(`_AV_DEFER_OK_', `YES') ',` define(`_AV_DEFER_OK_', `NO') ') ifelse(_AV_OPT,`confANTIVIRUS'_AV_NO`_OPT', `define(`_AV_OPT',`')', `ifelse(_AV_DEFER_OK_,`YES', `define(`_AV_OPT',`/defer_ok')', `define(`_AV_OPT',`')' )' ) ifelse(_AV_ACT,`confANTIVIRUS'_AV_NO`_ACT',`',` ifelse(_AV_NO, `0', ` # Антивирусные проверки ifdef(`confRECIPIENTS_ANTIVIRUS_HATERS', `ifelse(confRECIPIENTS_ANTIVIRUS_HATERS, `NO', `dnl', `dnl warn set acl_m_recipients_antivirus_flags = antivirus_haters=0 antivirus_friends=0 acl = acl_check_recipients_antivirus_haters "$recipients" ')') dnl ifdef(`confRECIPIENTS_ANTIVIRUS_HATERS', `ifelse(confRECIPIENTS_ANTIVIRUS_HATERS, `NO', `')') # Присвоение значения флагу warn set acl_m_av_result = clean ') define(`_AV_ACT', _AV_ACT` ') dnl deprecated значение WARN заменяем на DISCARD+QUARANTINE ifelse(_AV_ACT, `WARN ', `define(`_AV_ACT', `DISCARD QUARANTINE ')') dnl если указано действие DROP, заменяем (доплняем список дейтсвий) его на DISCARD ifelse_strstr(_AV_ACT, `DROP ', `define(`_AV_ACT', _AV_ACT` DISCARD ')') dnl если указано действие DROP_MAILLIST, заменяем (доплняем список дейтсвий) его на DISCARD ifelse_strstr(_AV_ACT, `DROP_MAILLIST ', `define(`_AV_ACT', _AV_ACT` DISCARD_MAILLIST ')') ifelse(confQUARANTINE_MAILDIR,`',`undefine(`confQUARANTINE_MAILDIR')') ifelse(_AV_DLFUNC_NAME,`',`undefine(`_AV_DLFUNC_NAME')') define(`_AV_NOTIFICATION_PARAMETERS', `ifelse(confAV_NOTIFY_SKIP_RCPT, `YES', `$acl_m_avir_notification', `$recipients')\ |_AV_NAME\ |$acl_m_malware_name\ ifdef(`confQUARANTINE_MAILDIR', ` |confQUARANTINE_MAILDIR\', ` |confQUARANTINE_DIR/_AV_NAME/${acl_m_malware_name}/${message_id}\') |confAV_ADMIN\ |$recipients\ |NEXT_PART_${sg{${tod_log}.${message_id}.${qualify_domain}._AV_NAME}{\N\s\N}{.}}\ |${sg{CONFDIR/template.antivir_notification}{CONFDIR}{confCONFDIR}} ') undefine(`_AV_NAME_MSG')dnl ifdef(`_AV_NAME_DEFAULT',`define(`_AV_NAME_MSG', _AV_NAME_DEFAULT)')dnl ifelse(_AV_NAME_MSG, `', `undefine(`_AV_NAME_MSG')')dnl ifdef(`_AV_NAME_MSG', `', `define(`_AV_NAME_MSG', _AV_NAME)')dnl ifdef(`_AV_NAME_CMD', `ifelse(_AV_NAME_CMD, `', `', `define(`_AV_NAME_MSG', `esyscmd(_AV_NAME_CMD)')')')dnl # Проверка письма warn set acl_m_av_prev_result = $acl_m_av_result set acl_m_av_result = clean dnl если для предыдущего демона был указан параметр defer_next ifelse(_AV_DEFER_NEXT_PREV,`YES',` condition = ${if eq{$acl_m_av_prev_result}{defer}{no}{yes}} set acl_m_av_result = skip ') ifdef(`_AV_MAX_SIZE',`dnl ifelse(len(X`'_AV_MAX_SIZE), `1', `', `dnl warn condition = ${if eq{$acl_m_av_result}{skip}{no}{yes}} condition = ${if >{$message_size}{_AV_MAX_SIZE}{yes}{no}} set acl_m_av_result = skip add_header = X-AV-Status: _AV_NAME_MSG on confCONTENT_SCANNING_HOSTNAME at $tod_log: skip checks for large message ($message_size>_AV_MAX_SIZE) log_message = _AV_NAME: skip checks for large message ($message_size>_AV_MAX_SIZE) ') dnl ifelse(len(X`'_AV_MAX_SIZE), `1', `', `') ') dnl ifdef(`_AV_MAX_SIZE',`') ifdef(`confRECIPIENTS_ANTIVIRUS_HATERS', `ifelse(confRECIPIENTS_ANTIVIRUS_HATERS, `NO', `dnl', `dnl warn condition = ${if eq{$acl_m_av_result}{skip}{no}{yes}} condition = ${if eq{${extract{antivirus_friends}{$acl_m_recipients_antivirus_flags}}}{}{no}{yes}} condition = ${if eq{${extract{antivirus_friends}{$acl_m_recipients_antivirus_flags}}}{0}{yes}{no}} condition = ${if >{${extract{antivirus_haters}{$acl_m_recipients_antivirus_flags}}}{0}{yes}{no}} set acl_m_av_result = skip add_header = X-AV-Status: _AV_NAME_MSG on confCONTENT_SCANNING_HOSTNAME at $tod_log: skip checks for recipients antivirus haters log_message = _AV_NAME: skip checks for recipients antivirus haters ')') dnl ifdef(`confRECIPIENTS_ANTIVIRUS_HATERS', `ifelse(confRECIPIENTS_ANTIVIRUS_HATERS, `NO', `')') ifdef(`_AV_DLFUNC_NAME', ` FEATURE(`dlfunc_`'_AV_DLFUNC_NAME') ', ` dnl ifdef(`_AV_DLFUNC_NAME') warn condition = ${if eq{$acl_m_av_result}{skip}{no}{yes}} set acl_m0 = _AV_SCAN acl = acl_check_data_av ') dnl ifdef(`_AV_DLFUNC_NAME') warn condition = ${if eq{$acl_m_av_result}{clean}{yes}{no}} add_header = X-AV-Status: _AV_NAME_MSG on confCONTENT_SCANNING_HOSTNAME at $tod_log: clean ifelse_strstr(_AV_DEFER_NO_MBOX_UNSPOOL_`'_AV_DEFER_FREEZE_, `YES', ` # Отмена удаления проверяемого письма из /var/spool/exim/scan в случае # DEFERа от антивируса # в параметреах был указан defer_no_mbox_unspool warn condition = ${if eq{$acl_m_av_result}{defer}{yes}{no}} ifelse(_AV_DEFER_NO_MBOX_UNSPOOL_, `YES', ` control = no_mbox_unspool ') ifelse(_AV_DEFER_FREEZE_, `YES', ` control = freeze ') log_message = _AV_NAME: error while scanning message\ `'ifelse(_AV_DEFER_NO_MBOX_UNSPOOL_, `YES', `, spool files will not be deleted')\ `'ifelse(_AV_DEFER_FREEZE_, `YES', `, message will be freeze') add_header = X-AV-Status: _AV_NAME_MSG on confCONTENT_SCANNING_HOSTNAME at $tod_log: deferred\ `'ifelse(_AV_DEFER_NO_MBOX_UNSPOOL_, `YES', `, mbox will not be unspooled')\ `'ifelse(_AV_DEFER_FREEZE_, `YES', `, message will be freeze') ',` warn condition = ${if eq{$acl_m_av_result}{defer}{yes}{no}} log_message = _AV_NAME: error while scanning message add_header = X-AV-Status: _AV_NAME_MSG on confCONTENT_SCANNING_HOSTNAME at $tod_log: deferred ') ifelse_strstr(_AV_ACT, `SUBMIT_MYSQL ', `ENTERPRISE(`mysql', `submit_av')') ifelse_strstr(_AV_ACT, `SUBMIT_SQLITE ', `ENTERPRISE(`sqlite', `submit_av')') ifelse_strstr(_AV_DEFER_OK_`'_AV_DEFER_NEXT_`'_AV_DEFER_FREEZE_,`YES',`',` # Возврат SMTP клиенту мягкой ошибки в случае DEFERа от антивируса # в параметреах не был указан defer_ok или defer_next defer condition = ${if eq{$acl_m_av_result}{defer}{yes}{no}} message = Antivirus unreachable. Please try again later ($message_exim_id) log_message = _AV_NAME: error while scanning message. Message deferred ') ifelse_strstr(_AV_ACT, `DISCARD ', ` dnl ifelse_strstr(_AV_ACT, `QUARANTINE ', ` # Пометка зараженного письма для помещения в карантин # DISCARD, QUARANTINE warn condition = ${if eq{$acl_m_av_result}{infected}{yes}{no}} set acl_m_av_result = quarantine log_message = _AV_NAME found a virus: $acl_m_malware_name add_header = X-AV-Status: _AV_NAME_MSG on confCONTENT_SCANNING_HOSTNAME at $tod_log: \ infected, $acl_m_malware_name has been found\n\ X-Original-Recipients: $recipients logwrite = original recipients: $recipients set acl_m_avir_notification = _AV_NOTIFICATION_PARAMETERS accept condition = ${if eq{$acl_m_av_result}{quarantine}{yes}{no}} ',` # Удаление зараженного письма # DISCARD discard condition = ${if eq{$acl_m_av_result}{infected}{yes}{no}} set acl_m_av_result = discard log_message = _AV_NAME found a virus: $acl_m_malware_name ') dnl ifelse_strstr(_AV_ACT, `QUARANTINE ', `', `') dnl ',` dnl ifelse_strstr(_AV_ACT, `DISCARD ', `') dnl ifelse_strstr(_AV_ACT, `DISCARD_MAILLIST ', ` # Удаление зараженного письма # DISCARD_MAILLIST discard condition = ${if eq{$acl_m_av_result}{infected}{yes}{no}} condition = ${if or{{!eq{$h_List-Id:}{}}{eq{$h_Precedence:}{list}}}{yes}{no}} set acl_m_av_result = discard log_message = _AV_NAME found a virus: $acl_m_malware_name ') dnl ifelse_strstr(_AV_ACT, `DROP_MAILLIST ', `', `') dnl ifelse_strstr(_AV_ACT, `QUARANTINE_MAILLIST ', ` # Фиктивный отказ от приема зараженного письма с пометкой письма # для помещения в карантин # QUARANTINE_MAILLIST warn condition = ${if eq{$acl_m_av_result}{infected}{yes}{no}} condition = ${if or{{!eq{$h_List-Id:}{}}{eq{$h_Precedence:}{list}}}{yes}{no}} set acl_m_av_result = quarantine logwrite = original recipients: $recipients add_header = X-AV-Status: _AV_NAME_MSG on confCONTENT_SCANNING_HOSTNAME at $tod_log: \ infected, $acl_m_malware_name has been found\n\ X-Original-Recipients: $recipients log_message = _AV_NAME found a virus: $acl_m_malware_name set acl_m_avir_notification = _AV_NOTIFICATION_PARAMETERS accept condition = ${if eq{$acl_m_av_result}{quarantine}{yes}{no}} ') dnl ifelse_strstr(_AV_ACT, `QUARANTINE_MAILLIST ', `', `') dnl ifelse_strstr(_AV_ACT, `QUARANTINE ', ` # Фиктивный отказ от приема зараженного письма с пометкой письма # для помещения в карантин # REJECT, QUARANTINE warn condition = ${if eq{$acl_m_av_result}{infected}{yes}{no}} set acl_m_av_result = quarantine control = fakereject/_AV_NAME found a virus: $acl_m_malware_name logwrite = original recipients: $recipients add_header = X-AV-Status: _AV_NAME_MSG on confCONTENT_SCANNING_HOSTNAME at $tod_log: \ infected, $acl_m_malware_name has been found\n\ X-Original-Recipients: $recipients log_message = _AV_NAME found a virus: $acl_m_malware_name set acl_m_avir_notification = _AV_NOTIFICATION_PARAMETERS accept condition = ${if eq{$acl_m_av_result}{quarantine}{yes}{no}} ',` # Отказ от приема зараженного писема # REJECT deny condition = ${if eq{$acl_m_av_result}{infected}{yes}{no}} message = _AV_NAME found a virus: $acl_m_malware_name ') dnl ifelse_strstr(_AV_ACT, `QUARANTINE ', `', `') dnl ') dnl ifelse_strstr(_AV_ACT, `DISCARD ', `') define(`_AV_DEFER_NEXT_PREV', _AV_DEFER_NEXT_) FEATURE(`antivirus') ') dnl ifelse(_AV_ACT,`confANTIVIRUS'_AV_NO`_ACT',`',`') ') dnl ifelse(SECTION, `ACL_CHECK_DATA', `') ifelse(SECTION, `ACLS_ADDITIONAL', `dnl acl_check_data_av: warn set acl_m_av_result = defer accept ! malware = * set acl_m_av_result = clean warn set acl_m_av_result = infected set acl_m_malware_name = $malware_name accept ifdef(`confRECIPIENTS_ANTIVIRUS_HATERS', `ifelse(confRECIPIENTS_ANTIVIRUS_HATERS, `NO', `dnl', `dnl acl_check_recipients_antivirus_haters: # acl_arg1 - список адресов получателей # acl_m_recipients_antivirus_flags - результат accept condition = ${if eq{$arg1}{}{yes}{no}} warn set acl_m_item = ${sg{$arg1}{\N^([^,\s]+)(,\s*\S+)*$\N}{\$1}} set acl_m_items = ${sg{$arg1}{\N^\S+ *\N}{}} accept condition = ${lookup{$acl_m_item}wildlsearch{CONFDIR/recipients_antivirus_haters}{yes}{no}} set acl_m_recipients_antivirus_flags = \ antivirus_haters=${eval:${extract{antivirus_haters}{$acl_m_recipients_antivirus_flags}}+1} \ antivirus_friends=${extract{antivirus_friends}{$acl_m_recipients_antivirus_flags}} acl = acl_check_recipients_antivirus_haters "$acl_m_items" accept set acl_m0 = ${lookup{${domain:$acl_m_item}}wildlsearch{CONFDIR/recipients_antivirus_haters}{$value}{}} condition = ${if eq{$acl_m0}{}{no}{yes}} # condition = ${if match_local_part{${local_part:$acl_m_item}}{$acl_m0}{yes}{no}} condition = ${if forany{$acl_m0}{eq{$item}{${local_part:$acl_m_item}}}{yes}{no}} set acl_m_recipients_antivirus_flags = \ antivirus_haters=${eval:${extract{antivirus_haters}{$acl_m_recipients_antivirus_flags}}+1} \ antivirus_friends=${extract{antivirus_friends}{$acl_m_recipients_antivirus_flags}} acl = acl_check_recipients_antivirus_haters "$acl_m_items" accept set acl_m_recipients_antivirus_flags = \ antivirus_haters=${extract{antivirus_haters}{$acl_m_recipients_antivirus_flags}} \ antivirus_friends=${eval:${extract{antivirus_friends}{$acl_m_recipients_antivirus_flags}}+1} acl = acl_check_recipients_antivirus_haters accept ')') dnl ifdef(`confRECIPIENTS_ANTIVIRUS_HATERS', `ifelse(confRECIPIENTS_ANTIVIRUS_HATERS, `NO', `')') ') dnl ifelse(SECTION, `ACLS_ADDITIONAL', `')