Skip to content

Fix SMTP STARTTLS flow and restore doctor dial timeout#1

Merged
bscott merged 3 commits into
bscott:masterfrom
jesseposner:fix/smtp-starttls
Feb 22, 2026
Merged

Fix SMTP STARTTLS flow and restore doctor dial timeout#1
bscott merged 3 commits into
bscott:masterfrom
jesseposner:fix/smtp-starttls

Conversation

@jesseposner
Copy link
Copy Markdown
Contributor

@jesseposner jesseposner commented Feb 17, 2026

Summary

Proton Bridge SMTP (127.0.0.1:1025) requires STARTTLS (plain connect, then TLS upgrade).
The prior STARTTLS fix switched to smtp.Dial, but that removed the explicit dial timeout in config doctor, so unreachable/blackholed SMTP hosts could stall diagnostics.

This PR keeps the STARTTLS behavior while restoring bounded connection behavior and tightening related networking paths.

What changed

  • Added timeout-aware SMTP dial helper:

    • internal/smtp/connect.go
    • Uses explicit ConnectTimeout (5s) and smtp.NewClient over a timed TCP dial.
  • Updated SMTP send path:

    • internal/smtp/client.go
    • Replaced direct smtp.Dial with the timeout-aware helper.
  • Fixed config doctor SMTP flow:

    • internal/cli/config.go
    • Check 6 (SMTP port reachable) uses explicit timeout constant.
    • Check 8 (SMTP connection succeeds) now short-circuits when check 6 fails and reports:
      • cannot test - SMTP port not reachable
    • Prevents running STARTTLS/AUTH when SMTP port is already unreachable.
  • Networking hardening / convention cleanup:

    • Replaced fmt.Sprintf("%s:%d", host, port) with net.JoinHostPort(...) in doctor/send/imap connection paths for IPv6-safe addressing.
  • Tests added:

    • internal/cli/config_test.go: doctor short-circuit regression coverage.
    • internal/smtp/client_test.go: timeout helper coverage and send-path timeout dial usage.
  • Docs updated:

    • docs/commands.md
    • docs/setup.md

Behavior impact

  • No CLI flags or JSON schema changes.
  • config doctor now reports a clear cannot-test message for SMTP auth when SMTP port reachability fails.
  • SMTP/IMAP address assembly is IPv6-safe.

Validation

  • go test ./...
  • go vet ./...

@jesseposner jesseposner changed the title Fix SMTP connection to use STARTTLS instead of implicit TLS Fix SMTP STARTTLS flow and restore doctor dial timeout Feb 17, 2026
Add a timeout-aware SMTP dial helper and use it in both config doctor and the send path so unreachable SMTP hosts cannot stall diagnostics or sends indefinitely.

In config doctor, short-circuit check 8 when SMTP reachability (check 6) fails, and report an explicit cannot-test message instead of attempting STARTTLS/AUTH anyway.

Also replace host:port formatting with net.JoinHostPort in doctor/send/imap connection paths for IPv6-safe addressing (and to satisfy go vet).

Includes regression coverage for doctor short-circuit behavior and timeout helper/send-path dialing behavior, plus docs updates for the new doctor semantics.
Use a reserved .invalid SMTP hostname in ConfigDoctor short-circuit test instead of relying on localhost port 1 being closed, reducing environment-dependent flakiness.
@bscott bscott self-assigned this Feb 19, 2026
@bscott bscott added the bug Something isn't working label Feb 19, 2026
@bscott
Copy link
Copy Markdown
Owner

bscott commented Feb 19, 2026

Thank you @jesseposner -- I'll get this in tomorrow's release

@bscott bscott merged commit a47d936 into bscott:master Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants