| 277 | } |
| 278 | |
| 279 | func (s *state) RewriteBody(ctx context.Context, h *textproto.Header, body buffer.Buffer) error { |
| 280 | defer trace.StartRegion(ctx, "modify.dkim/RewriteBody").End() |
| 281 | |
| 282 | var domain string |
| 283 | if s.from != "" { |
| 284 | var err error |
| 285 | _, domain, err = address.Split(s.from) |
| 286 | if err != nil { |
| 287 | return err |
| 288 | } |
| 289 | } |
| 290 | // Use first key for null return path (<>) and postmaster (<postmaster>) |
| 291 | if domain == "" { |
| 292 | domain = s.m.domains[0] |
| 293 | } |
| 294 | selector := s.m.selector |
| 295 | |
| 296 | if s.m.signSubdomains { |
| 297 | topDomain := s.m.domains[0] |
| 298 | if strings.HasSuffix(domain, "."+topDomain) { |
| 299 | domain = topDomain |
| 300 | } |
| 301 | } |
| 302 | normDomain, err := dns.ForLookup(domain) |
| 303 | if err != nil { |
| 304 | s.log.Error("unable to normalize domain from envelope sender", err, "domain", domain) |
| 305 | return nil |
| 306 | } |
| 307 | keySigner := s.m.signers[normDomain] |
| 308 | if keySigner == nil { |
| 309 | s.log.Msg("no key for domain", "domain", normDomain) |
| 310 | return nil |
| 311 | } |
| 312 | |
| 313 | // If the message is non-EAI, we are not allowed to use domains in U-labels, |
| 314 | // attempt to convert. |
| 315 | if !s.meta.SMTPOpts.UTF8 { |
| 316 | var err error |
| 317 | domain, err = idna.ToASCII(domain) |
| 318 | if err != nil { |
| 319 | return nil |
| 320 | } |
| 321 | |
| 322 | selector, err = idna.ToASCII(selector) |
| 323 | if err != nil { |
| 324 | return nil |
| 325 | } |
| 326 | } |
| 327 | |
| 328 | opts := dkim.SignOptions{ |
| 329 | Domain: domain, |
| 330 | Selector: selector, |
| 331 | Identifier: "@" + domain, |
| 332 | Signer: keySigner, |
| 333 | Hash: s.m.hash, |
| 334 | HeaderCanonicalization: s.m.headerCanon, |
| 335 | BodyCanonicalization: s.m.bodyCanon, |
| 336 | HeaderKeys: s.m.fieldsToSign(h), |