aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcin Serwin <marcin.serwin0@protonmail.com>2023-03-14 10:42:49 +0000
committerRobin Jarry <robin@jarry.cc>2023-03-26 20:44:56 +0200
commitc09b17a930cc58c13dd5dd2ba8e7a261833eb05a (patch)
tree3d876bd91e3d0c463e8bb79129dfeb09cef16fd2
parent6d59ad3f02bc97c0b5040f59259fa8450702a2e2 (diff)
downloadaerc-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.go65
-rw-r--r--config/accounts.go10
-rw-r--r--doc/aerc-smtp.5.scd13
-rw-r--r--widgets/account-wizard.go20
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