open
https://gitlab.synchro.net/main/sbbs/-/work_items/1279
When an outbound SMTP delivery's connection drops partway through sending the message body, the mail server logs a misleading DKIM error:
```
12:11:34 2332 SEND connecting to port 25 on mx1.emailn.de [178.63.251.174] 12:11:42 2332 SEND TLS Session started successfully
12:12:22 2332 SEND/TLS dbg 'WSAECONNABORTED: Connection was terminated due to a time-out or other failure' (-42) flushing data
12:12:22 2332 SEND/TLS !DKIM body hash changed between sign and send - message delivery aborted
12:12:22 2332 SEND !Delivery attempt #1 FAILED (mx1.emailn.de replied with: ```
A second occurrence on 2026-08-17 (plain SMTP, no TLS) shows the same sequence: `Connection aborted by peer on send`, then the DKIM error. Because it is logged at `LOG_ERR`, the error also lands in `data/error.log`.
Nothing changed between signing and sending. The connection failed, and the DKIM verify pass then hashed a truncated body.
## Cause
In `mailsrvr.cpp`:
1. During pass 2, `sockprintf()` feeds each line to the DKIM verify capture (`dkim_capture_line()`) *before* trying to transmit it.
2. In `sockmimetext()`'s body loop, the first failed `sockprintf()` exits the loop with `break`. The rest of the body and any attachments are skipped.
3. Execution still reaches `sockprintf(..., ".")` at the end of `sockmimetext()`. The verify capture sees the end-of-data terminator, finalizes a hash over the partial body, and sets `mismatch`. The caller then logs "DKIM body hash changed between sign and send".
The "message delivery aborted" part is also misleading: the dropped connection had already ended the delivery.
## Suggested fix
In the `sockmimetext()` body loop, replace `break` with `return lines;`. This follows the existing early `return 0` when the header-terminator send fails. After a failed send the session is unusable, so the terminator and attachment encoding can't reach the peer anyway. With this change:
- The DKIM verify capture never sees `.`, so there's no false mismatch.
- Attachments are no longer MIME-encoded into a dead socket.
- `MSG_KILLFILE` attachments are left in place, which is correct because they weren't delivered.
The POP3 RETR path, which shares `sockmimetext()`, gets the same early exit.
## Release notes
DKIM signing (#215) was added after v3.21e, so this fix doesn't need an entry in `docs/v322_new.md`.
_Authored by Claude (Claude Code), on behalf of @rswindell_
--- SBBSecho 3.38-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)