diff options
author | Marcin Serwin <marcin.serwin0@protonmail.com> | 2023-03-14 10:42:49 +0000 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-03-26 20:44:56 +0200 |
commit | c09b17a930cc58c13dd5dd2ba8e7a261833eb05a (patch) | |
tree | 3d876bd91e3d0c463e8bb79129dfeb09cef16fd2 | |
parent | 6d59ad3f02bc97c0b5040f59259fa8450702a2e2 (diff) | |
download | aerc-c09b17a930cc58c13dd5dd2ba8e7a261833eb05a.tar.gz |
smtp: replace smtp-starttls with schema option
The "smtp-starttls" options is now ignored in favor of more detailed
schema specification, similarly to IMAP.
Fixes: https://todo.sr.ht/~rjarry/aerc/149
Signed-off-by: Marcin Serwin <marcin.serwin0@protonmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
-rw-r--r-- | commands/compose/send.go | 65 | ||||
-rw-r--r-- | config/accounts.go | 10 | ||||
-rw-r--r-- | doc/aerc-smtp.5.scd | 13 | ||||
-rw-r--r-- | widgets/account-wizard.go | 20 |
4 files changed, 53 insertions, 55 deletions
diff --git a/commands/compose/send.go b/commands/compose/send.go index 4eceefe9..a5571e37 100644 --- a/commands/compose/send.go +++ b/commands/compose/send.go @@ -89,28 +89,22 @@ func (Send) Execute(aerc *widgets.Aerc, args []string) error { if err != nil { return err } - var starttls bool - if starttls_, ok := config.Params["smtp-starttls"]; ok { - starttls = starttls_ == "yes" - } var domain string if domain_, ok := config.Params["smtp-domain"]; ok { domain = domain_ } ctx := sendCtx{ - uri: uri, - scheme: scheme, - auth: auth, - starttls: starttls, - from: config.From, - rcpts: rcpts, - domain: domain, + uri: uri, + scheme: scheme, + auth: auth, + from: config.From, + rcpts: rcpts, + domain: domain, } log.Debugf("send config uri: %s", ctx.uri) log.Debugf("send config scheme: %s", ctx.scheme) log.Debugf("send config auth: %s", ctx.auth) - log.Debugf("send config starttls: %s", ctx.starttls) log.Debugf("send config from: %s", ctx.from) log.Debugf("send config rcpts: %s", ctx.rcpts) log.Debugf("send config domain: %s", ctx.domain) @@ -171,6 +165,8 @@ func send(aerc *widgets.Aerc, composer *widgets.Composer, ctx sendCtx, switch ctx.scheme { case "smtp": fallthrough + case "smtp+insecure": + fallthrough case "smtps": sender, err = newSmtpSender(ctx) case "": @@ -243,13 +239,12 @@ func listRecipients(h *mail.Header) ([]*mail.Address, error) { } type sendCtx struct { - uri *url.URL - scheme string - auth string - starttls bool - from *mail.Address - rcpts []*mail.Address - domain string + uri *url.URL + scheme string + auth string + from *mail.Address + rcpts []*mail.Address + domain string } func newSendmailSender(ctx sendCtx) (io.WriteCloser, error) { @@ -306,8 +301,15 @@ func parseScheme(uri *url.URL) (scheme string, auth string, err error) { case 1: scheme = parts[0] case 2: - scheme = parts[0] - auth = parts[1] + if parts[1] == "insecure" { + scheme = uri.Scheme + } else { + scheme = parts[0] + auth = parts[1] + } + case 3: + scheme = parts[0] + "+" + parts[1] + auth = parts[2] default: return "", "", fmt.Errorf("Unknown transfer protocol %s", uri.Scheme) } @@ -407,7 +409,9 @@ func newSmtpSender(ctx sendCtx) (io.WriteCloser, error) { ) switch ctx.scheme { case "smtp": - conn, err = connectSmtp(ctx.starttls, ctx.uri.Host, ctx.domain) + conn, err = connectSmtp(true, ctx.uri.Host, ctx.domain) + case "smtp+insecure": + conn, err = connectSmtp(false, ctx.uri.Host, ctx.domain) case "smtps": conn, err = connectSmtps(ctx.uri.Host) default: @@ -468,11 +472,11 @@ func connectSmtp(starttls bool, host string, domain string) (*smtp.Client, error return nil, errors.Wrap(err, "Hello") } } - if sup, _ := conn.Extension("STARTTLS"); sup { - if !starttls { - err := errors.New("STARTTLS is supported by this server, " + - "but not set in accounts.conf. " + - "Add smtp-starttls=yes") + if starttls { + if sup, _ := conn.Extension("STARTTLS"); !sup { + err := errors.New("STARTTLS requested, but not supported " + + "by this SMTP server. Is someone tampering with your " + + "connection?") conn.Close() return nil, err } @@ -482,13 +486,8 @@ func connectSmtp(starttls bool, host string, domain string) (*smtp.Client, error conn.Close() return nil, errors.Wrap(err, "StartTLS") } - } else if starttls { - err := errors.New("STARTTLS requested, but not supported " + - "by this SMTP server. Is someone tampering with your " + - "connection?") - conn.Close() - return nil, err } + return conn, nil } diff --git a/config/accounts.go b/config/accounts.go index 8aadb329..bacd7e39 100644 --- a/config/accounts.go +++ b/config/accounts.go @@ -161,6 +161,16 @@ func parseAccounts(root string, accts []string) error { account.Params[key] = val } } + if _, ok := account.Params["smtp-starttls"]; ok { + Warnings = append(Warnings, Warning{ + Title: "accounts.conf: smtp-starttls is deprecated", + Body: ` +SMTP connections now use STARTTLS by default and the smtp-starttls setting is ignored. + +If you want to disable STARTTLS, append +insecure to the schema. +`, + }) + } if account.Source == "" { return fmt.Errorf("Expected source for account %s", _sec) } diff --git a/doc/aerc-smtp.5.scd b/doc/aerc-smtp.5.scd index 850a71b2..88fb6629 100644 --- a/doc/aerc-smtp.5.scd +++ b/doc/aerc-smtp.5.scd @@ -15,14 +15,17 @@ SMTP configuration may be done interactively with the *:new-account* command. In _accounts.conf_ (see *aerc-accounts*(5)), the following SMTP-specific options are available: -*outgoing* = _<scheme>_+_<auth>_://_<username>_[_:<password>_]_@<hostname>_[_:<port>_]?[_<oauth2_params>_] +*outgoing* = _<scheme>_[_+<auth>_]://_<username>_[_:<password>_]_@<hostname>_[_:<port>_]?[_<oauth2_params>_] Remember that all fields must be URL encoded. The _@_ symbol, when URL encoded, is _%40_. The value of _<scheme>_ can be: _smtp_ - Unencrypted SMTP + SMTP with STARTTLS + + _smtp+insecure_ + SMTP without STARTTLS _smtps_ SMTP with TLS/SSL @@ -58,12 +61,6 @@ are available: Example: outgoing-cred-cmd = pass hostname/username -*smtp-starttls* = _true_|_false_ - Set this to _true_ if the server uses STARTTLS. In that case you should - also use _smtp://_ instead of _smtps://_. - - Default: _false_ - *smtp-domain* = _<domain>_ Local domain name to use in the HELO/EHLO SMTP command. Set this to a fully qualified domain name if the server requires it as an antispam measure. diff --git a/widgets/account-wizard.go b/widgets/account-wizard.go index c1d237ef..60497f83 100644 --- a/widgets/account-wizard.go +++ b/widgets/account-wizard.go @@ -99,11 +99,11 @@ func NewAccountWizard(aerc *Aerc) *AccountWizard { fullName: ui.NewTextInput("", config.Ui).Prompt("> "), imapPassword: ui.NewTextInput("", config.Ui).Prompt("] ").Password(true), imapServer: ui.NewTextInput("", config.Ui).Prompt("> "), - imapStr: ui.NewText("imaps://", config.Ui.GetStyle(config.STYLE_DEFAULT)), + imapStr: ui.NewText("Connection URL: imaps://", config.Ui.GetStyle(config.STYLE_DEFAULT)), imapUsername: ui.NewTextInput("", config.Ui).Prompt("> "), smtpPassword: ui.NewTextInput("", config.Ui).Prompt("] ").Password(true), smtpServer: ui.NewTextInput("", config.Ui).Prompt("> "), - smtpStr: ui.NewText("smtps://", config.Ui.GetStyle(config.STYLE_DEFAULT)), + smtpStr: ui.NewText("Connection URL: smtps://", config.Ui.GetStyle(config.STYLE_DEFAULT)), smtpUsername: ui.NewTextInput("", config.Ui).Prompt("> "), } @@ -513,10 +513,7 @@ func (wizard *AccountWizard) finish(tutorial bool) { sec.NewKey("source", wizard.imapUrl.String()) //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty sec.NewKey("outgoing", wizard.smtpUrl.String()) //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty sec.NewKey("default", "INBOX") //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty - if wizard.smtpMode == SMTP_STARTTLS { - sec.NewKey("smtp-starttls", "yes") //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty - } - sec.NewKey("from", fmt.Sprintf("%s <%s>", //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty + sec.NewKey("from", fmt.Sprintf("%s <%s>", //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty wizard.fullName.String(), wizard.email.String())) if wizard.copySent { sec.NewKey("copy-to", "Sent") //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty @@ -547,11 +544,6 @@ func (wizard *AccountWizard) finish(tutorial bool) { Source: sec.Key("source").String(), Outgoing: config.RemoteConfig{Value: sec.Key("outgoing").String()}, } - if wizard.smtpMode == SMTP_STARTTLS { - account.Params = map[string]string{ - "smtp-starttls": "yes", - } - } if wizard.copySent { account.CopyTo = "Sent" } @@ -635,11 +627,11 @@ func (wizard *AccountWizard) smtpUri() url.URL { var scheme string switch wizard.smtpMode { case SMTP_OVER_TLS: - scheme = "smtps+plain" + scheme = "smtps" case SMTP_STARTTLS: - scheme = "smtp+plain" + scheme = "smtp" case SMTP_INSECURE: - scheme = "smtp+plain" + scheme = "smtp+insecure" } var ( userpass *url.Userinfo |