]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Minor] Update plugins that are using headers modifications 5604/head
authorVsevolod Stakhov <vsevolod@rspamd.com>
Fri, 5 Sep 2025 10:00:13 +0000 (11:00 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Fri, 5 Sep 2025 10:00:13 +0000 (11:00 +0100)
lualib/plugins/dmarc.lua
src/plugins/lua/arc.lua
src/plugins/lua/bimi.lua
src/plugins/lua/dmarc.lua
src/plugins/lua/gpt.lua
src/plugins/lua/milter_headers.lua

index f69016b741ab4dee2b772142918f4c754d83ab6e..fdb8d46cb265ba772310db0cf351fe86516d31b4 100644 (file)
@@ -13,7 +13,7 @@ distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-]]--
+]] --
 
 -- Common dmarc stuff
 local rspamd_logger = require "rspamd_logger"
@@ -80,7 +80,7 @@ exports.dmarc_report = function(task, settings, data)
   local ip = task:get_from_ip()
   if not ip or not ip:is_valid() then
     rspamd_logger.infox(task, 'cannot store dmarc report for %s: no valid source IP',
-        data.domain)
+      data.domain)
     return nil
   end
 
@@ -88,7 +88,7 @@ exports.dmarc_report = function(task, settings, data)
 
   if rspamd_lua_utils.is_rspamc_or_controller(task) and not settings.reporting.report_local_controller then
     rspamd_logger.infox(task, 'cannot store dmarc report for %s from IP %s: has come from controller/rspamc',
-        data.domain, ip)
+      data.domain, ip)
     return
   end
 
@@ -106,13 +106,12 @@ exports.dmarc_report = function(task, settings, data)
 end
 
 exports.gen_munging_callback = function(munging_opts, settings)
-  local rspamd_util = require "rspamd_util"
   local lua_mime = require "lua_mime"
   return function(task)
     if munging_opts.mitigate_allow_only then
       if not task:has_symbol(settings.symbols.allow) then
         lua_util.debugm(N, task, 'skip munging, no %s symbol',
-            settings.symbols.allow)
+          settings.symbols.allow)
         -- Excepted
         return
       end
@@ -124,7 +123,7 @@ exports.gen_munging_callback = function(munging_opts, settings)
 
       if not has_dmarc then
         lua_util.debugm(N, task, 'skip munging, no %s symbol',
-            settings.symbols.allow)
+          settings.symbols.allow)
         -- Excepted
         return
       end
@@ -143,7 +142,7 @@ exports.gen_munging_callback = function(munging_opts, settings)
 
       if not seen_strict then
         lua_util.debugm(N, task, 'skip munging, no strict policy found in %s',
-            settings.symbols.allow)
+          settings.symbols.allow)
         -- Excepted
         return
       end
@@ -152,7 +151,7 @@ exports.gen_munging_callback = function(munging_opts, settings)
       local accepted, trace = munging_opts.munge_map_condition:process(task)
       if not accepted then
         lua_util.debugm(N, task, 'skip munging, maps condition not satisfied: (%s)',
-            trace)
+          trace)
         -- Excepted
         return
       end
@@ -194,14 +193,10 @@ exports.gen_munging_callback = function(munging_opts, settings)
       via_name = string.format('%s via %s', from.name, via_user)
     end
 
-    local encoded_via_name = rspamd_util.mime_header_encode(via_name)
-    local via_from_folded = rspamd_util.fold_header('From',
-        string.format('%s <%s>', encoded_via_name, via_addr),
-        task:get_newlines_type())
-    local encoded_orig_name = rspamd_util.mime_header_encode(from.name or '')
-    local orig_from_folded = rspamd_util.fold_header('X-Original-From',
-        string.format('%s <%s>', encoded_orig_name, from.addr),
-        task:get_newlines_type())
+    local via_from_folded = lua_util.fold_header_with_encoding(task, 'From',
+      string.format('%s <%s>', via_name, via_addr), { structured = true })
+    local orig_from_folded = lua_util.fold_header_with_encoding(task, 'X-Original-From',
+      string.format('%s <%s>', from.name or '', from.addr), { structured = true })
     local add_hdrs = {
       ['From'] = { order = 1, value = via_from_folded },
       ['X-Original-From'] = { order = 0, value = orig_from_folded },
@@ -231,7 +226,7 @@ exports.gen_munging_callback = function(munging_opts, settings)
       add = add_hdrs
     })
     lua_util.debugm(N, task, 'munged DMARC header for %s: %s -> %s',
-        from.domain, via_from_folded, from.addr)
+      from.domain, via_from_folded, from.addr)
     rspamd_logger.infox(task, 'munged DMARC header for %s', from.addr)
     task:insert_result('DMARC_MUNGED', 1.0, from.addr)
   end
@@ -287,7 +282,7 @@ local function dmarc_check_record(log_obj, record, is_tld)
 
   local elts = dmarc_grammar:match(record)
   lua_util.debugm(N, log_obj, "got DMARC record: %s, tld_flag=%s, processed=%s",
-      record, is_tld, elts)
+    record, is_tld, elts)
 
   if elts then
     elts = dmarc_key_value_case(elts)
index 954583ed06242fbb48eac42daaa5e75569222cca..30a61326f03b14811e42c3cb96814fa8568c93f6 100644 (file)
@@ -588,14 +588,16 @@ local function arc_sign_seal(task, params, header)
     end
   end
 
-  header = lua_util.fold_header(task,
+  header = lua_util.fold_header_with_encoding(task,
     'ARC-Message-Signature',
-    header)
+    header,
+    { structured = true, encode = false })
 
   cur_auth_results = string.format('i=%d; %s', cur_idx, cur_auth_results)
-  cur_auth_results = lua_util.fold_header(task,
+  cur_auth_results = lua_util.fold_header_with_encoding(task,
     'ARC-Authentication-Results',
-    cur_auth_results, ';')
+    cur_auth_results,
+    { stop_chars = ';', structured = true, encode = false })
 
   local s = dkim_canonicalize('ARC-Authentication-Results',
     cur_auth_results)
@@ -631,8 +633,9 @@ local function arc_sign_seal(task, params, header)
       ['ARC-Message-Signature'] = { order = 1, value = header },
       ['ARC-Seal'] = {
         order = 1,
-        value = lua_util.fold_header(task,
-          'ARC-Seal', cur_arc_seal)
+        value = lua_util.fold_header_with_encoding(task,
+          'ARC-Seal', cur_arc_seal,
+          { structured = true, encode = false })
       }
     },
     -- RFC requires a strict order for these headers to be inserted
index 78949a5c046c708c2a94ec57adcffe7654fb0fb6..bb848b1fe39d4672fb65ea15b6f6cc446497499b 100644 (file)
@@ -12,7 +12,7 @@ distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-]]--
+]] --
 
 local N = "bimi"
 local lua_util = require "lua_util"
@@ -63,7 +63,7 @@ local function check_dmarc_policy(task)
 
   if policy ~= 'reject' and policy ~= 'quarantine' then
     lua_util.debugm(N, task, "DMARC policy for domain %s is not strict: %s",
-        dom, policy)
+      dom, policy)
     return nil
   end
 
@@ -92,7 +92,7 @@ local function check_bimi_record(task, rec)
 
   if elts then
     lua_util.debugm(N, task, "got BIMI record: %s, processed=%s",
-        rec, elts)
+      rec, elts)
     local res = {}
 
     if type(elts.l) == 'string' then
@@ -112,14 +112,13 @@ local function insert_bimi_headers(task, domain, bimi_content)
   local hdr_name = 'BIMI-Indicator'
   -- Re-encode base64...
   local content = rspamd_util.encode_base64(rspamd_util.decode_base64(bimi_content),
-      73, task:get_newlines_type())
+    73, task:get_newlines_type())
   lua_mime.modify_headers(task, {
     remove = { [hdr_name] = 0 },
     add = {
       [hdr_name] = {
         order = 0,
-        value = rspamd_util.fold_header(hdr_name, content,
-            task:get_newlines_type())
+        value = lua_util.fold_header_with_encoding(task, hdr_name, content, { encode = false })
       }
     }
   })
@@ -132,14 +131,14 @@ local function process_bimi_json(task, domain, redis_data)
 
   if err then
     rspamd_logger.errx(task, "cannot parse BIMI result from Redis for %s: %s",
-        domain, err)
+      domain, err)
   else
     local d = parser:get_object()
     if d.content then
       insert_bimi_headers(task, domain, d.content)
     elseif d.error then
       lua_util.debugm(N, task, "invalid BIMI for %s: %s",
-          domain, d.error)
+        domain, d.error)
     end
   end
 end
@@ -148,17 +147,17 @@ local function make_helper_request(task, domain, record, redis_server)
   local is_sync = settings.helper_sync
   local helper_url = string.format('%s/v1/check', settings.helper_url)
   local redis_key = string.format('%s%s', settings.redis_prefix,
-      domain)
+    domain)
 
   local function http_helper_callback(http_err, code, body, _)
     if http_err then
       rspamd_logger.warnx(task, 'got error reply from helper %s: code=%s; reply=%s',
-          helper_url, code, http_err)
+        helper_url, code, http_err)
       return
     end
     if code ~= 200 then
       rspamd_logger.warnx(task, 'got non 200 reply from helper %s: code=%s; reply=%s',
-          helper_url, code, http_err)
+        helper_url, code, http_err)
       return
     end
     if is_sync then
@@ -167,46 +166,46 @@ local function make_helper_request(task, domain, record, redis_server)
 
       if err then
         rspamd_logger.errx(task, "cannot parse BIMI result from helper for %s: %s",
-            domain, err)
+          domain, err)
       else
         local d = parser:get_object()
         if d.content then
           insert_bimi_headers(task, domain, d.content)
         elseif d.error then
           lua_util.debugm(N, task, "invalid BIMI for %s: %s",
-              domain, d.error)
+            domain, d.error)
         end
 
         local ret, upstream
         local function redis_set_cb(redis_err, _)
           if redis_err then
             rspamd_logger.warnx(task, 'cannot get reply from Redis when storing image %s: %s',
-                upstream:get_addr():to_string(), redis_err)
+              upstream:get_addr():to_string(), redis_err)
             upstream:fail()
           else
             lua_util.debugm(N, task, 'stored bimi image in Redis for domain %s; key=%s',
-                domain, redis_key)
+              domain, redis_key)
           end
         end
 
         ret, _, upstream = lua_redis.redis_make_request(task,
-            redis_params, -- connect params
-            redis_key, -- hash key
-            true, -- is write
-            redis_set_cb, --callback
-            'PSETEX', -- command
-            { redis_key, tostring(settings.redis_min_expiry * 1000.0),
-              ucl.to_format(d, "json-compact") })
+          redis_params,   -- connect params
+          redis_key,      -- hash key
+          true,           -- is write
+          redis_set_cb,   --callback
+          'PSETEX',       -- command
+          { redis_key, tostring(settings.redis_min_expiry * 1000.0),
+            ucl.to_format(d, "json-compact") })
 
         if not ret then
           rspamd_logger.warnx(task, 'cannot make request to Redis when storing image; domain %s',
-              domain)
+            domain)
         end
       end
     else
       -- In async mode we skip request and use merely Redis to insert indicators
       lua_util.debugm(N, task, "sent request to resolve %s to %s",
-          domain, helper_url)
+        domain, helper_url)
     end
   end
 
@@ -227,7 +226,7 @@ local function make_helper_request(task, domain, record, redis_server)
 
   local serialised = ucl.to_format(request_data, 'json-compact')
   lua_util.debugm(N, task, "send request to BIMI helper: %s",
-      serialised)
+    serialised)
   rspamd_http.request({
     task = task,
     mime_type = 'application/json',
@@ -241,19 +240,19 @@ end
 
 local function check_bimi_vmc(task, domain, record)
   local redis_key = string.format('%s%s', settings.redis_prefix,
-      domain)
+    domain)
   local ret, _, upstream
 
   local function redis_cached_cb(err, data)
     if err then
       rspamd_logger.warnx(task, 'cannot get reply from Redis %s: %s',
-          upstream:get_addr():to_string(), err)
+        upstream:get_addr():to_string(), err)
       upstream:fail()
     else
       if type(data) == 'string' then
         -- We got a cached record, good stuff
         lua_util.debugm(N, task, "got valid cached BIMI result for domain: %s",
-            domain)
+          domain)
         process_bimi_json(task, domain, data)
       else
         -- Get server addr + port
@@ -273,9 +272,9 @@ local function check_bimi_vmc(task, domain, record)
           password = string.format(':%s@', redis_params.password)
         end
         local redis_server = string.format('redis://%s%s:%s%s',
-            password,
-            upstream:get_name(), upstream:get_port(),
-            db)
+          password,
+          upstream:get_name(), upstream:get_port(),
+          db)
         make_helper_request(task, domain, record, redis_server)
       end
     end
@@ -283,12 +282,12 @@ local function check_bimi_vmc(task, domain, record)
 
   -- We first check Redis and then try to use helper
   ret, _, upstream = lua_redis.redis_make_request(task,
-      redis_params, -- connect params
-      redis_key, -- hash key
-      false, -- is write
-      redis_cached_cb, --callback
-      'GET', -- command
-      { redis_key })
+    redis_params,      -- connect params
+    redis_key,         -- hash key
+    false,             -- is write
+    redis_cached_cb,   --callback
+    'GET',             -- command
+    { redis_key })
 
   if not ret then
     rspamd_logger.warnx(task, 'cannot make request to Redis; domain %s', domain)
@@ -300,7 +299,7 @@ local function check_bimi_dns(task, domain)
   local dns_cb = function(_, _, results, err)
     if err then
       lua_util.debugm(N, task, "cannot resolve bimi for %s: %s",
-          domain, err)
+        domain, err)
     else
       for _, rec in ipairs(results) do
         local res = check_bimi_record(task, rec)
@@ -308,7 +307,7 @@ local function check_bimi_dns(task, domain)
         if res then
           if settings.vmc_only and not res.a then
             lua_util.debugm(N, task, "BIMI for domain %s has no VMC, skip it",
-                domain)
+              domain)
 
             return
           end
@@ -318,7 +317,7 @@ local function check_bimi_dns(task, domain)
           elseif res.l then
             -- TODO: add l check
             lua_util.debugm(N, task, "l only BIMI for domain %s is not implemented yet",
-                domain)
+              domain)
           end
         end
       end
@@ -376,7 +375,7 @@ if redis_params then
     type = 'normal',
     callback = bimi_callback,
     augmentations = { string.format("timeout=%f", settings.helper_timeout or
-        redis_params.timeout or 0.0) }
+      redis_params.timeout or 0.0) }
   })
   rspamd_config:register_symbol {
     name = 'BIMI_VALID',
index 28b3db867c070890250e156105ff475974babba4..630bb6bbda182b791fd7763bac2342a8cf9ccb4f 100644 (file)
@@ -13,7 +13,7 @@ distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-]]--
+]] --
 
 -- Dmarc policy filter
 
@@ -180,10 +180,10 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
   end
 
   lua_util.debugm(N, task,
-      "validated dmarc policy for %s: %s; dkim_ok=%s, dkim_tempfail=%s, spf_ok=%s, spf_tempfail=%s",
-      policy.domain, policy.dmarc_policy,
-      dkim_ok, dkim_tmpfail,
-      spf_ok, spf_tmpfail)
+    "validated dmarc policy for %s: %s; dkim_ok=%s, dkim_tempfail=%s, spf_ok=%s, spf_tempfail=%s",
+    policy.domain, policy.dmarc_policy,
+    dkim_ok, dkim_tmpfail,
+    spf_ok, spf_tmpfail)
 
   local disposition = 'none'
   local sampled_out = false
@@ -191,14 +191,13 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
   local function handle_dmarc_failure(what, reason_str)
     if not policy.pct or policy.pct == 100 then
       task:insert_result(settings.symbols[what], 1.0,
-          policy.domain .. ' : ' .. reason_str, policy.dmarc_policy)
+        policy.domain .. ' : ' .. reason_str, policy.dmarc_policy)
       disposition = what
     else
       local coin = math.random(100)
       if (coin > policy.pct) then
         if (not settings.no_sampling_domains or
-            not settings.no_sampling_domains:get_key(policy.domain)) then
-
+              not settings.no_sampling_domains:get_key(policy.domain)) then
           if what == 'reject' then
             disposition = 'quarantine'
           else
@@ -206,19 +205,19 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
           end
 
           task:insert_result(settings.symbols[disposition], 1.0,
-              policy.domain .. ' : ' .. reason_str, policy.dmarc_policy, "sampled_out")
+            policy.domain .. ' : ' .. reason_str, policy.dmarc_policy, "sampled_out")
           sampled_out = true
           lua_util.debugm(N, task,
-              'changed dmarc policy from %s to %s, sampled out: %s < %s',
-              what, disposition, coin, policy.pct)
+            'changed dmarc policy from %s to %s, sampled out: %s < %s',
+            what, disposition, coin, policy.pct)
         else
           task:insert_result(settings.symbols[what], 1.0,
-              policy.domain .. ' : ' .. reason_str, policy.dmarc_policy, "local_policy")
+            policy.domain .. ' : ' .. reason_str, policy.dmarc_policy, "local_policy")
           disposition = what
         end
       else
         task:insert_result(settings.symbols[what], 1.0,
-            policy.domain .. ' : ' .. reason_str, policy.dmarc_policy)
+          policy.domain .. ' : ' .. reason_str, policy.dmarc_policy)
         disposition = what
       end
     end
@@ -232,9 +231,9 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
     DMARC evaluation can only yield a "pass" result after one of the
     underlying authentication mechanisms passes for an aligned
     identifier.
-    ]]--
+    ]] --
     task:insert_result(settings.symbols['allow'], 1.0, policy.domain,
-        policy.dmarc_policy)
+      policy.dmarc_policy)
   else
     --[[
     https://tools.ietf.org/html/rfc7489#section-6.6.2
@@ -243,10 +242,10 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
     temporary error, the Receiver evaluating the message is unable to
     conclude that the DMARC mechanism had a permanent failure; they
     therefore cannot apply the advertised DMARC policy.
-    ]]--
+    ]] --
     if spf_tmpfail or dkim_tmpfail then
       task:insert_result(settings.symbols['dnsfail'], 1.0, policy.domain ..
-          ' : ' .. 'SPF/DKIM temp error', policy.dmarc_policy)
+        ' : ' .. 'SPF/DKIM temp error', policy.dmarc_policy)
     else
       -- We can now check the failed policy and maybe send report data elt
       local reason_str = table.concat(reason, ', ')
@@ -257,8 +256,8 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
         handle_dmarc_failure('reject', reason_str)
       else
         task:insert_result(settings.symbols['softfail'], 1.0,
-            policy.domain .. ' : ' .. reason_str,
-            policy.dmarc_policy)
+          policy.domain .. ' : ' .. reason_str,
+          policy.dmarc_policy)
       end
     end
   end
@@ -266,7 +265,7 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
   if policy.rua and redis_params and settings.reporting.enabled then
     if settings.reporting.only_domains then
       if not (settings.reporting.only_domains:get_key(policy.domain) or
-          settings.reporting.only_domains:get_key(rspamd_util.get_tld(policy.domain))) then
+            settings.reporting.only_domains:get_key(rspamd_util.get_tld(policy.domain))) then
         rspamd_logger.info(task, 'DMARC reporting suppressed for sender domain %s', policy.domain)
         return
       end
@@ -289,10 +288,10 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
     local function dmarc_report_cb(err)
       if not err then
         rspamd_logger.infox(task, 'dmarc report saved for %s (rua = %s)',
-            hdrfromdom, policy.rua)
+          hdrfromdom, policy.rua)
       else
         rspamd_logger.errx(task, 'dmarc report is not saved for %s: %s',
-            hdrfromdom, err)
+          hdrfromdom, err)
       end
     end
 
@@ -317,12 +316,12 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
 
     -- Prepare and send redis report element
     local period = os.date('%Y%m%d',
-        task:get_date({ format = 'connect', gmt = false }))
+      task:get_date({ format = 'connect', gmt = false }))
 
     -- Dmarc domain key must include dmarc domain, rua and period
     local dmarc_domain_key = table.concat(
-        { settings.reporting.redis_keys.report_prefix, policy.domain, policy.rua, period },
-        settings.reporting.redis_keys.join_char)
+      { settings.reporting.redis_keys.report_prefix, policy.domain, policy.rua, period },
+      settings.reporting.redis_keys.join_char)
     local report_data = dmarc_common.dmarc_report(task, settings, {
       spf_ok = spf_ok and 'pass' or 'fail',
       dkim_ok = dkim_ok and 'pass' or 'fail',
@@ -335,15 +334,15 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
     })
 
     local idx_key = table.concat({ settings.reporting.redis_keys.index_prefix, period },
-        settings.reporting.redis_keys.join_char)
+      settings.reporting.redis_keys.join_char)
 
     if report_data then
       lua_redis.exec_redis_script(take_report_id,
-          { task = task, is_write = true },
-          dmarc_report_cb,
-          { idx_key, dmarc_domain_key,
-            tostring(settings.reporting.max_entries), tostring(settings.reporting.keys_expire) },
-          { hdrfromdom, report_data })
+        { task = task, is_write = true },
+        dmarc_report_cb,
+        { idx_key, dmarc_domain_key,
+          tostring(settings.reporting.max_entries), tostring(settings.reporting.keys_expire) },
+        { hdrfromdom, report_data })
     end
   end
 end
@@ -388,7 +387,7 @@ local function dmarc_callback(task)
 
   local function process_dmarc_policy(policy, final)
     lua_util.debugm(N, task, "validate DMARC policy (final=%s): %s",
-        true, policy)
+      true, policy)
     if policy.err and policy.symbol then
       -- In case of fatal errors or final check for tld, we give up and
       -- insert result
@@ -421,7 +420,7 @@ local function dmarc_callback(task)
 
         if err then
           if (err ~= 'requested record is not found' and
-              err ~= 'no records with this name') then
+                err ~= 'no records with this name') then
             policy_target.err = lookup_domain .. ' : ' .. err
             policy_target.symbol = settings.symbols['dnsfail']
           else
@@ -506,7 +505,7 @@ local opts = rspamd_config:get_all_opt('dmarc')
 settings = lua_util.override_defaults(settings, opts)
 
 settings.auth_and_local_conf = lua_util.config_check_local_or_authed(rspamd_config, N,
-    false, false)
+  false, false)
 
 -- Legacy...
 if settings.reporting and not settings.reporting.exclude_domains and settings.no_reporting_domains then
@@ -648,11 +647,11 @@ if settings.munging then
 
   local munging_defaults = {
     reply_goes_to_list = false,
-    mitigate_allow_only = true, -- perform munging based on DMARC_POLICY_ALLOW only
+    mitigate_allow_only = true,   -- perform munging based on DMARC_POLICY_ALLOW only
     mitigate_strict_only = false, -- perform mugning merely for reject/quarantine policies
-    munge_from = true, -- replace from with something like <orig name> via <rcpt user>
-    list_map = nil, -- map of maillist domains
-    munge_map_condition = nil, -- maps expression to enable munging
+    munge_from = true,            -- replace from with something like <orig name> via <rcpt user>
+    list_map = nil,               -- map of maillist domains
+    munge_map_condition = nil,    -- maps expression to enable munging
   }
 
   local munging_opts = lua_util.override_defaults(munging_defaults, settings.munging)
@@ -664,7 +663,7 @@ if settings.munging then
   end
 
   munging_opts.list_map = lua_maps.map_add_from_ucl(munging_opts.list_map,
-      'set', 'DMARC munging map of the recipients addresses to munge')
+    'set', 'DMARC munging map of the recipients addresses to munge')
 
   if not munging_opts.list_map then
     rspamd_logger.errx(rspamd_config, 'cannot enable DMARC munging with invalid list_map (invalid map)')
@@ -674,7 +673,7 @@ if settings.munging then
 
   if munging_opts.munge_map_condition then
     munging_opts.munge_map_condition = lua_maps_expressions.create(rspamd_config,
-        munging_opts.munge_map_condition, N)
+      munging_opts.munge_map_condition, N)
   end
 
   rspamd_config:register_symbol({
index 1790e5e8d9c7598fa1866188cf3f4578fe4352f2..b9d8f0d53aabe49f4258ffeb75e05d45d73e0d2b 100644 (file)
@@ -545,8 +545,10 @@ local function insert_results(task, result, sel_part)
     end
   end
   if result.reason and settings.reason_header then
+    local v = lua_util.fold_header_with_encoding(task, settings.reason_header,
+      tostring(result.reason), { encode = 'auto' })
     lua_mime.modify_headers(task,
-      { add = { [settings.reason_header] = { value = tostring(result.reason), order = 1 } } })
+      { add = { [settings.reason_header] = { value = v, order = 1 } } })
   end
 
   if cache_context then
index 17fc9056236401b7ab88c6a7244b326b389f6194..2c20d3206c2a7a5acc7797e289e6a9c3bacc656e 100644 (file)
@@ -13,7 +13,7 @@ distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-]]--
+]] --
 
 if confighelp then
   return
@@ -33,14 +33,14 @@ local E = {}
 local HOSTNAME = rspamd_util.get_hostname()
 
 local settings = {
-  remove_upstream_spam_flag = true;
+  remove_upstream_spam_flag = true,
   skip_local = true,
   skip_authenticated = true,
   skip_all = false,
   local_headers = {},
   authenticated_headers = {},
   headers_modify_mode = 'compat', -- To avoid compatibility issues on upgrade
-  default_headers_order = nil, -- Insert at the end (set 1 to insert just after the first received)
+  default_headers_order = nil,    -- Insert at the end (set 1 to insert just after the first received)
   routines = {
     ['remove-headers'] = {
       headers = {},
@@ -132,7 +132,6 @@ local active_routines = {}
 local custom_routines = {}
 
 local function milter_headers(task)
-
   -- Used to override wanted stuff by means of settings
   local settings_override = false
 
@@ -153,19 +152,19 @@ local function milter_headers(task)
         if r.addr and r.domain and r.user then
           if settings.extended_headers_rcpt:get_key(r.addr) then
             lua_util.debugm(N, task, 'found full addr in recipients for extended headers: %s',
-                r.addr)
+              r.addr)
             found = true
           end
           -- Try user as plain match
           if not found and settings.extended_headers_rcpt:get_key(r.user) then
             lua_util.debugm(N, task, 'found user in recipients for extended headers: %s (%s)',
-                r.user, r.addr)
+              r.user, r.addr)
             found = true
           end
           -- Try @domain to match domain
           if not found and settings.extended_headers_rcpt:get_key('@' .. r.domain) then
             lua_util.debugm(N, task, 'found domain in recipients for extended headers: @%s (%s)',
-                r.domain, r.addr)
+              r.domain, r.addr)
             found = true
           end
         end
@@ -198,7 +197,6 @@ local function milter_headers(task)
     end
 
     return false
-
   end
 
   -- XXX: fix this crap one day
@@ -213,14 +211,10 @@ local function milter_headers(task)
     if not add[hname] then
       add[hname] = {}
     end
-    local folded = lua_util.fold_header(task, hname, value, stop_chars)
-    if rspamd_config:is_mime_utf8() then
-      if not rspamd_util.is_valid_utf8(folded) then
-        folded = rspamd_util.mime_header_encode(folded)
-      end
-    else
-      folded = rspamd_util.mime_header_encode(folded)
-    end
+    local folded = lua_util.fold_header_with_encoding(task, hname, value, {
+      stop_chars = stop_chars,
+      encode = 'auto'
+    })
     table.insert(add[hname], {
       order = (order or settings.default_headers_order or -1),
       value = folded
@@ -247,9 +241,9 @@ local function milter_headers(task)
 
     local buf = {}
     local verdict = string.format('default: %s [%.2f / %.2f]',
-    --TODO: (common.metric_action == 'no action') and 'False' or 'True',
-        (common.metric_action == 'reject') and 'True' or 'False',
-        common.metric_score[1], common.metric_score[2])
+      --TODO: (common.metric_action == 'no action') and 'False' or 'True',
+      (common.metric_action == 'reject') and 'True' or 'False',
+      common.metric_score[1], common.metric_score[2])
     table.insert(buf, verdict)
 
     -- Deal with symbols
@@ -267,7 +261,7 @@ local function milter_headers(task)
 
     for _, s in ipairs(common.symbols) do
       local sym_str = string.format('%s(%.2f)[%s]',
-          s.name, s.score, table.concat(s.options or {}, ','))
+        s.name, s.score, table.concat(s.options or {}, ','))
       table.insert(buf, sym_str)
     end
     add_header('x-spamd-result', table.concat(buf, '; '), ';')
@@ -405,7 +399,7 @@ local function milter_headers(task)
     add[local_mod.header] = action
   end
 
-  local function spam_header (class, name, value, remove_v)
+  local function spam_header(class, name, value, remove_v)
     if skip_wanted(class) then
       return
     end
@@ -423,9 +417,9 @@ local function milter_headers(task)
 
   routines['spam-header'] = function()
     spam_header('spam-header',
-        settings.routines['spam-header'].header,
-        settings.routines['spam-header'].value,
-        settings.routines['spam-header'].remove)
+      settings.routines['spam-header'].header,
+      settings.routines['spam-header'].value,
+      settings.routines['spam-header'].remove)
   end
 
   routines['remove-spam-flag'] = function()
@@ -486,7 +480,7 @@ local function milter_headers(task)
       else
         if local_mod.status_clean then
           add_header('x-virus', string.format('%s(%s)',
-              local_mod.status_fail, fail_reason))
+            local_mod.status_fail, fail_reason))
         end
       end
     end
@@ -499,14 +493,14 @@ local function milter_headers(task)
     local local_mod = settings.routines['x-os-fingerprint']
 
     local os_string, link_type, uptime_min, distance = task:get_mempool():get_variable('os_fingerprint',
-        'string, string, double, double');
+      'string, string, double, double');
 
     if not os_string then
       return
     end
 
     local value = string.format('%s, (up: %i min), (distance %i, link: %s)',
-        os_string, uptime_min, distance, link_type)
+      os_string, uptime_min, distance, link_type)
 
     if local_mod.remove then
       remove[local_mod.header] = local_mod.remove
@@ -553,8 +547,8 @@ local function milter_headers(task)
     end
 
     local res = ar.gen_auth_results(task,
-        lua_util.override_defaults(ar.default_settings,
-            settings.routines['authentication-results']))
+      lua_util.override_defaults(ar.default_settings,
+        settings.routines['authentication-results']))
 
     if res then
       add_header('authentication-results', res, ';', 1)
@@ -592,7 +586,7 @@ local function milter_headers(task)
 
   if user_settings and type(user_settings.routines) == 'table' then
     lua_util.debugm(N, task, 'override routines to %s from user settings',
-        user_settings.routines)
+      user_settings.routines)
     routines_enabled = user_settings.routines
     settings_override = true
   end
@@ -637,7 +631,6 @@ local function milter_headers(task)
     remove = nil
   end
   if add or remove then
-
     lua_mime.modify_headers(task, {
       add = add,
       remove = remove
@@ -687,7 +680,7 @@ local function activate_routine(s)
       table.insert(active_routines, s)
       if (opts.routines and opts.routines[s]) then
         settings.routines[s] = lua_util.override_defaults(settings.routines[s],
-            opts.routines[s])
+          opts.routines[s])
       end
     end
   else
@@ -755,11 +748,11 @@ if (#active_routines < 1) then
 end
 
 logger.infox(rspamd_config, 'active routines [%s]',
-    table.concat(active_routines, ','))
+  table.concat(active_routines, ','))
 
 if opts.extended_headers_rcpt then
   settings.extended_headers_rcpt = lua_maps.rspamd_map_add_from_ucl(opts.extended_headers_rcpt,
-      'set', 'Extended headers recipients')
+    'set', 'Extended headers recipients')
 end
 
 rspamd_config:register_symbol({