Commit 379f4b5
🐛 Keep SASL connection alive across Postfix auth-client idle gap
The AUTH loop in sasl.go refreshed SetReadDeadline with ReadTimeout (10s)
before each idle wait. Postfix' xsasl_dovecot client, however, caches the
auth-client connection per smtpd worker for up to smtpd_timeout (default
300s) and reuses it across SMTP sessions. As soon as the gap between two
sessions exceeded 10s, the adapter closed the socket; on the next AUTH
Postfix wrote into a half-open connection, read EOF, and reported
`454 4.7.0 Temporary authentication failure: Connection lost to
authentication server` instead of a clean FAIL.
The symptom was most visible for ROLE_SPAM users: their auth permanently
fails, so the mail client keeps retrying, and every fresh smtpd worker
hits the stale-socket race. Successful authentications hid the bug
because the client's automatic retry succeeded on the second attempt.
Introduce saslIdleTimeout (360s, longer than smtpd_timeout) and use it
only for the AUTH-loop idle wait between requests. Per-operation
deadlines for the client handshake (sasl.go) and LOGIN CONT roundtrips
stay at ReadTimeout (10s) so a hung client cannot pin a worker.
Reproduced locally with boky/postfix + a stub Userli upstream:
pre-fix `spam@…` after ≥35s idle → 454; post-fix → 535 with
`reason=user disabled due to spam role`.
Add TestSASL_PersistentConnection_SurvivesIdleGap covering the new
behaviour and adjust TestSASL_IdleConnection_ClosesCleanly to override
saslIdleTimeout so it remains fast.
Co-Authored-By: Claude <claude@anthropic.com>1 parent 81d075d commit 379f4b5
2 files changed
Lines changed: 61 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
20 | 28 | | |
21 | 29 | | |
22 | 30 | | |
| |||
73 | 81 | | |
74 | 82 | | |
75 | 83 | | |
76 | | - | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
77 | 89 | | |
78 | 90 | | |
79 | 91 | | |
80 | 92 | | |
81 | 93 | | |
82 | | - | |
| 94 | + | |
83 | 95 | | |
84 | 96 | | |
85 | 97 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
485 | 485 | | |
486 | 486 | | |
487 | 487 | | |
488 | | - | |
489 | | - | |
490 | | - | |
491 | | - | |
492 | | - | |
| 488 | + | |
| 489 | + | |
493 | 490 | | |
494 | 491 | | |
495 | 492 | | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
496 | 498 | | |
497 | 499 | | |
498 | 500 | | |
499 | 501 | | |
500 | 502 | | |
501 | 503 | | |
502 | | - | |
503 | | - | |
| 504 | + | |
| 505 | + | |
504 | 506 | | |
505 | 507 | | |
506 | 508 | | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
0 commit comments