config: keep cache of resolved credential commands
outgoing-cred-cmd is used to retrieve the password from a password
manager such as UNIX pass or bitwarden CLI. These tools often prompt for
a passphrase to secure the passwords and it is annoying having to enter
it every time sending an email with aerc.
Add a new option outgoing-cred-cmd-cache (default to true) to control
whether aerc will keep a cache of the password or run outgoing-cred-cmd
every time an email needs to be sent.
NB: If the cached password is incorrect, the only way to change it is to
restart aerc.
Fixes: ca90343850
("outgoing-cred-cmd: delay execution until an email needs to be sent")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
This commit is contained in:
parent
f6a7a64fa7
commit
abf6ec7f02
3 changed files with 40 additions and 12 deletions
|
@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## [Unreleased](https://git.sr.ht/~rjarry/aerc/log/master)
|
## [Unreleased](https://git.sr.ht/~rjarry/aerc/log/master)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- `outgoing-cred-cmd` will no longer be executed every time an email needs to
|
||||||
|
be sent. The output will be stored until aerc is shut down. This behaviour
|
||||||
|
can be disabled by setting `outgoing-cred-cmd-cache=false` in
|
||||||
|
`accounts.conf`.
|
||||||
|
|
||||||
## [0.12.0](https://git.sr.ht/~rjarry/aerc/refs/0.12.0) - 2022-09-01
|
## [0.12.0](https://git.sr.ht/~rjarry/aerc/refs/0.12.0) - 2022-09-01
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -98,13 +98,15 @@ const (
|
||||||
type RemoteConfig struct {
|
type RemoteConfig struct {
|
||||||
Value string
|
Value string
|
||||||
PasswordCmd string
|
PasswordCmd string
|
||||||
|
CacheCmd bool
|
||||||
|
cache string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c RemoteConfig) parseValue() (*url.URL, error) {
|
func (c *RemoteConfig) parseValue() (*url.URL, error) {
|
||||||
return url.Parse(c.Value)
|
return url.Parse(c.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c RemoteConfig) ConnectionString() (string, error) {
|
func (c *RemoteConfig) ConnectionString() (string, error) {
|
||||||
if c.Value == "" || c.PasswordCmd == "" {
|
if c.Value == "" || c.PasswordCmd == "" {
|
||||||
return c.Value, nil
|
return c.Value, nil
|
||||||
}
|
}
|
||||||
|
@ -124,18 +126,23 @@ func (c RemoteConfig) ConnectionString() (string, error) {
|
||||||
return c.Value, nil
|
return c.Value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command("sh", "-c", c.PasswordCmd)
|
pw := c.cache
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
output, err := cmd.Output()
|
if pw == "" {
|
||||||
if err != nil {
|
cmd := exec.Command("sh", "-c", c.PasswordCmd)
|
||||||
return "", fmt.Errorf("failed to read password: %w", err)
|
cmd.Stdin = os.Stdin
|
||||||
|
output, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to read password: %w", err)
|
||||||
|
}
|
||||||
|
pw = strings.TrimSpace(string(output))
|
||||||
|
}
|
||||||
|
u.User = url.UserPassword(u.User.Username(), pw)
|
||||||
|
if c.CacheCmd {
|
||||||
|
c.cache = pw
|
||||||
}
|
}
|
||||||
|
|
||||||
pw := strings.TrimSpace(string(output))
|
return u.String(), nil
|
||||||
u.User = url.UserPassword(u.User.Username(), pw)
|
|
||||||
c.Value = u.String()
|
|
||||||
|
|
||||||
return c.Value, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccountConfig struct {
|
type AccountConfig struct {
|
||||||
|
@ -314,6 +321,13 @@ func loadAccountConfig(path string, accts []string) ([]AccountConfig, error) {
|
||||||
account.Outgoing.Value = val
|
account.Outgoing.Value = val
|
||||||
case "outgoing-cred-cmd":
|
case "outgoing-cred-cmd":
|
||||||
account.Outgoing.PasswordCmd = val
|
account.Outgoing.PasswordCmd = val
|
||||||
|
case "outgoing-cred-cmd-cache":
|
||||||
|
cache, err := strconv.ParseBool(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"%s=%s %w", key, val, err)
|
||||||
|
}
|
||||||
|
account.Outgoing.CacheCmd = cache
|
||||||
case "from":
|
case "from":
|
||||||
account.From = val
|
account.From = val
|
||||||
case "aliases":
|
case "aliases":
|
||||||
|
|
|
@ -657,6 +657,13 @@ Note that many of these configuration options are written for you, such as
|
||||||
|
|
||||||
Default: none
|
Default: none
|
||||||
|
|
||||||
|
*outgoing-cred-cmd-cache*
|
||||||
|
By default, the credentials returned by the command will be cached until
|
||||||
|
aerc is shut down. If set to false, *outgoing-cred-cmd* will be executed
|
||||||
|
every time an email is to be sent.
|
||||||
|
|
||||||
|
Default: true
|
||||||
|
|
||||||
*pgp-auto-sign*
|
*pgp-auto-sign*
|
||||||
If true, all outgoing emails from this account will be signed (if a signing
|
If true, all outgoing emails from this account will be signed (if a signing
|
||||||
key is available)
|
key is available)
|
||||||
|
|
Loading…
Reference in a new issue