commit 36a7d1e

Kalyan Sriram  ·  2021-10-22 18:30:50 +0000 UTC
parent a88a370
config: allow specifying an external password cmd

Storing passwords in plaintext in your configuration file is dangerous!
This patch adds support for fetching a password from an external
command (i.e. `gpg`, `pass`, `gopass`).
3 files changed,  +41, -11
+2, -0
1@@ -14,6 +14,8 @@ cat <<EOF >~/.config/senpai/senpai.yaml
2 addr: irc.libera.chat
3 nick: senpai
4 password: "my password can't be this cute"
5+# alternatively, specify a command to fetch your password:
6+# password-cmd: "gopass show irc/<username>"
7 EOF
8 go run ./cmd/senpai
9 ```
+26, -7
 1@@ -4,6 +4,7 @@ import (
 2 	"errors"
 3 	"fmt"
 4 	"io/ioutil"
 5+	"os/exec"
 6 	"strconv"
 7 	"strings"
 8 
 9@@ -47,13 +48,14 @@ func (c *Color) UnmarshalText(data []byte) error {
10 }
11 
12 type Config struct {
13-	Addr     string
14-	Nick     string
15-	Real     string
16-	User     string
17-	Password *string
18-	NoTLS    bool `yaml:"no-tls"`
19-	Channels []string
20+	Addr        string
21+	Nick        string
22+	Real        string
23+	User        string
24+	Password    *string
25+	PasswordCmd string `yaml:"password-cmd"`
26+	NoTLS       bool   `yaml:"no-tls"`
27+	Channels    []string
28 
29 	NoTypings bool `yaml:"no-typings"`
30 	Mouse     *bool
31@@ -88,6 +90,13 @@ func ParseConfig(buf []byte) (cfg Config, err error) {
32 	if cfg.Real == "" {
33 		cfg.Real = cfg.Nick
34 	}
35+	if cfg.PasswordCmd != "" {
36+		password, err := runPasswordCmd(cfg.PasswordCmd)
37+		if err != nil {
38+			return cfg, err
39+		}
40+		cfg.Password = &password
41+	}
42 	if cfg.NickColWidth <= 0 {
43 		cfg.NickColWidth = 16
44 	}
45@@ -114,3 +123,13 @@ func LoadConfigFile(filename string) (cfg Config, err error) {
46 	}
47 	return
48 }
49+
50+func runPasswordCmd(command string) (password string, err error) {
51+	cmd := exec.Command("sh", "-c", command)
52+	stdout, err := cmd.Output()
53+	if err == nil {
54+		password = strings.TrimSuffix(string(stdout), "\n")
55+	}
56+
57+	return
58+}
+13, -4
 1@@ -31,7 +31,15 @@ Some settings are required, the others are optional.
 2 	authentication.  By default, the value of *nick* is used.
 3 
 4 *password*
 5-	Your password, used for SASL authentication.
 6+	Your password, used for SASL authentication. See also *password-cmd*.
 7+
 8+*password-cmd*
 9+    Alternatively to providing your SASL authentication password directly in
10+    plaintext, you can specify a command to be run to fetch the password at
11+    runtime. This is useful if you store your passwords in a separate (probably
12+    encrypted) file using `gpg` or a command line password manager such as
13+    `pass` or `gopass`. If a *password-cmd* is provided, the value of *password*
14+    will be ignored and the output of *password-cmd* will be used for login.
15 
16 *channels*
17 	A list of channel names that senpai will automatically join at startup and
18@@ -125,9 +133,10 @@ addr: irc.libera.chat
19 nick: Guest123456
20 ```
21 
22-A more advanced configuration file that enables SASL authentication, sends
23+A more advanced configuration file that enables SASL authentication, fetches the
24+password from an external program instead of storing in plaintext, sends
25 notifications on highlight and decreases the width of the nick column to 12
26-(note: _swaymsg_ is specific to sway, a wayland compositor.  Use whatever you
27+(note: _swaymsg_ is specific to sway, a wayland compositor. Use whatever you
28 need to know if the terminal emulator that runs senpai has focus):
29 
30 ```
31@@ -135,7 +144,7 @@ addr: irc.libera.chat
32 nick: Guest123456
33 user: senpai
34 real: Guest von Lenon
35-password: A secure password, I guess?
36+password-cmd: "gopass show irc/guest" # use your favorite CLI password solution here
37 channels: ["#rahxephon"]
38 highlights:
39 	- guest