RFC 8601 "no result" Authentication-Results 헤더(authserv-id; none)가 있는 수신 이메일로 인한 충돌

email_in_authserv_id가 설정되어 있고, 수신된 이메일에 결과가 없는(Authentication-Results: ``mx.example.com``; none, RFC 8601 §2.2의 “no-result” 형식) 일치하는 Authentication-Results 헤더가 포함된 경우, 게시물 생성이 다음과 같은 오류로 실패합니다:

NoMethodError: undefined method 'each' for nil
lib/email/authentication_results.rb:45:in 'block in Email::AuthenticationResults#calc_dmarc'

게시물은 유실되고, 발신자에게 거절 이메일이 전송되지 않습니다.

원인: parse_header에서 authres_payload의 no_result 분기가 일치하므로 resinfo_val이 nil이 되고 parsed_resinfo는 할당되지 않습니다. 그 결과 { authserv_id: "``mx.example.com``", resinfo: nil }가 반환되고, calc_dmarc가 result[:resinfo].each를 호출하게 됩니다.

발생 시점: 일부 MTA는 검사를 수행하지 않은 경우 no-result 형식을 추가합니다. 예를 들어 rspamd는 local_addrs에서 온 인증되지 않은 메일(예: 네트워크 내부에서 중계된 메일)에 대해 이렇게 합니다. 이 크래시는 게시물 생성 시에만 나타납니다(Email::Receiver#create_post → auth_res_action). 예를 들어 낯선 사람으로부터 온 메일처럼 이전 단계에서 거절된 메일은 여기까지 도달하지 않습니다.

재현 방법 (rails console):

SiteSetting.email_in_authserv_id = "mx.example.com"
Email::AuthenticationResults.new(["mx.example.com; none"]).verdict
# => NoMethodError: undefined method 'each' for nil

제안되는 수정 사항: calc_dmarc에서 Array(result[:resinfo]).each do |resinfo|를 사용하거나, parse_header에서 parsed_resinfo = []로 설정하십시오. 이렇게 하면 no-result 헤더가 gray로 계산되며, 이는 그 의미와 일치합니다.

ESR v2026.7.3에서 확인되었으며, 동일한 줄은 여전히 main 브랜치에 존재합니다.