You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

auth_results.lua 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. --[[
  2. Copyright (c) 2016, Andrew Lewis <nerf@judo.za.org>
  3. Copyright (c) 2017, Vsevolod Stakhov <vsevolod@highsecure.ru>
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. ]]--
  14. local global = require "global_functions"
  15. local default_settings = {
  16. spf_symbols = {
  17. pass = 'R_SPF_ALLOW',
  18. fail = 'R_SPF_FAIL',
  19. softfail = 'R_SPF_SOFTFAIL',
  20. neutral = 'R_SPF_NEUTRAL',
  21. temperror = 'R_SPF_DNSFAIL',
  22. none = 'R_SPF_NA',
  23. permerror = 'R_SPF_PERMFAIL',
  24. },
  25. dkim_symbols = {
  26. pass = 'R_DKIM_ALLOW',
  27. fail = 'R_DKIM_REJECT',
  28. temperror = 'R_DKIM_TEMPFAIL',
  29. none = 'R_DKIM_NA',
  30. permerror = 'R_DKIM_PERMFAIL',
  31. },
  32. dmarc_symbols = {
  33. pass = 'DMARC_POLICY_ALLOW',
  34. permerror = 'DMARC_BAD_POLICY',
  35. temperror = 'DMARC_DNSFAIL',
  36. none = 'DMARC_NA',
  37. reject = 'DMARC_POLICY_REJECT',
  38. softfail = 'DMARC_POLICY_SOFTFAIL',
  39. quarantine = 'DMARC_POLICY_QUARANTINE',
  40. },
  41. arc_symbols = {
  42. pass = 'ARC_ALLOW',
  43. permerror = 'ARC_INVALID',
  44. temperror = 'ARC_DNSFAIL',
  45. none = 'ARC_NA',
  46. reject = 'ARC_REJECT',
  47. },
  48. add_smtp_user = true,
  49. }
  50. local exports = {}
  51. local function gen_auth_results(task, settings)
  52. local table = table
  53. local pairs = pairs
  54. local ipairs = ipairs
  55. local auth_results, hdr_parts = {}, {}
  56. if not settings then
  57. settings = default_settings
  58. end
  59. local auth_types = {
  60. dkim = settings.dkim_symbols,
  61. dmarc = settings.dmarc_symbols,
  62. spf = settings.spf_symbols,
  63. arc = settings.arc_symbols,
  64. }
  65. local common = {
  66. symbols = {}
  67. }
  68. local received = task:get_received_headers() or {}
  69. local mxname = (received[1] or {}).by_hostname
  70. if mxname then
  71. table.insert(hdr_parts, mxname)
  72. end
  73. for auth_type, symbols in pairs(auth_types) do
  74. for key, sym in pairs(symbols) do
  75. if not common.symbols.sym then
  76. local s = task:get_symbol(sym)
  77. if not s then
  78. common.symbols[sym] = false
  79. else
  80. common.symbols[sym] = s
  81. if not auth_results[auth_type] then
  82. auth_results[auth_type] = {key}
  83. else
  84. table.insert(auth_results[auth_type], key)
  85. end
  86. if auth_type ~= 'dkim' then
  87. break
  88. end
  89. end
  90. end
  91. end
  92. end
  93. for auth_type, keys in pairs(auth_results) do
  94. for _, key in ipairs(keys) do
  95. local hdr = ''
  96. if auth_type == 'dmarc' and key ~= 'none' then
  97. local opts = common.symbols[auth_types['dmarc'][key]][1]['options'] or {}
  98. hdr = hdr .. 'dmarc='
  99. if key == 'reject' or key == 'quarantine' or key == 'softfail' then
  100. hdr = hdr .. 'fail'
  101. else
  102. hdr = hdr .. key
  103. end
  104. if key == 'pass' then
  105. hdr = hdr .. ' (policy=' .. opts[2] .. ')'
  106. hdr = hdr .. ' header.from=' .. opts[1]
  107. elseif key ~= 'none' then
  108. local t = global.rspamd_str_split(opts[1], ' : ')
  109. local dom = t[1]
  110. local rsn = t[2]
  111. if rsn then
  112. hdr = hdr .. ' reason="' .. rsn .. '"'
  113. end
  114. hdr = hdr .. ' header.from=' .. dom
  115. if key == 'softfail' then
  116. hdr = hdr .. ' (policy=none)'
  117. else
  118. hdr = hdr .. ' (policy=' .. key .. ')'
  119. end
  120. end
  121. table.insert(hdr_parts, hdr)
  122. elseif auth_type == 'dkim' and key ~= 'none' then
  123. if common.symbols[auth_types['dkim'][key]][1] then
  124. local dkim_parts = {}
  125. local opts = common.symbols[auth_types['dkim'][key]][1]['options']
  126. for _, v in ipairs(opts) do
  127. table.insert(dkim_parts, auth_type .. '=' .. key .. ' header.d=' .. v)
  128. end
  129. table.insert(hdr_parts, table.concat(dkim_parts, '; '))
  130. end
  131. elseif auth_type == 'arc' and key ~= 'none' then
  132. if common.symbols[auth_types['arc'][key]][1] then
  133. local opts = common.symbols[auth_types['arc'][key]][1]['options'] or {}
  134. for _, v in ipairs(opts) do
  135. hdr = hdr .. auth_type .. '=' .. key .. ' (' .. v .. ')'
  136. table.insert(hdr_parts, hdr)
  137. end
  138. end
  139. elseif auth_type == 'spf' and key ~= 'none' then
  140. hdr = hdr .. auth_type .. '=' .. key
  141. local smtp_from = task:get_from('smtp')
  142. if smtp_from and smtp_from[1] and smtp_from[1]['addr'] ~= '' and smtp_from[1]['addr'] ~= nil then
  143. hdr = hdr .. ' smtp.mailfrom=' .. smtp_from[1]['addr']
  144. else
  145. local helo = task:get_helo()
  146. if helo then
  147. hdr = hdr .. ' smtp.helo=' .. task:get_helo()
  148. end
  149. end
  150. table.insert(hdr_parts, hdr)
  151. end
  152. end
  153. end
  154. local u = task:get_user()
  155. local smtp_from = task:get_from('smtp')
  156. if u and smtp_from then
  157. local hdr
  158. if #smtp_from[1]['addr'] > 0 then
  159. if settings['add_smtp_user'] then
  160. hdr = string.format('auth=pass smtp.auth=%s smtp.mailfrom=%s',
  161. u, smtp_from[1]['addr'])
  162. else
  163. hdr = string.format('auth=pass smtp.mailfrom=%s',
  164. smtp_from[1]['addr'])
  165. end
  166. else
  167. if settings['add_smtp_user'] then
  168. hdr = string.format('auth=pass smtp.auth=%s', u)
  169. else
  170. hdr = 'auth=pass'
  171. end
  172. end
  173. table.insert(hdr_parts, hdr)
  174. end
  175. if #hdr_parts > 0 then
  176. return table.concat(hdr_parts, '; ')
  177. end
  178. return nil
  179. end
  180. exports.gen_auth_results = gen_auth_results
  181. return exports