commit d4cfb330c2badd838a70f4221135579745df5451
parent 44609570c1e33a7b362fecddb43aac565af22991
Author: awy <awy@awy.one>
Date: Wed, 8 Apr 2026 22:14:25 +0300
feature: experimental KeepassXC support
Diffstat:
9 files changed, 105 insertions(+), 23 deletions(-)
diff --git a/README.md b/README.md
@@ -2,12 +2,15 @@
https://git.awy.one/aerc-wizard
-Fork of [mutt-wizard](https://github.com/lukesmithxyz/mutt-wizard) with some additions:
+Fork of [mutt-wizard](https://github.com/lukesmithxyz/mutt-wizard) with \
+some additions:
- `aerc` support (no mutt-related configuration is created)
- better wayland notification handling in `mailsync`
-- gmail with sane IMAP folders (for example `Sent` instead of `[Gmail]/Sent Mail`) so binds just werk
+- gmail with sane IMAP folders (for example `Sent` \
+instead of `[Gmail]/Sent Mail`) so binds just werk
- `gopass` backend instead of `pass`
+- experimental `keepassxc` support
Get this great stuff without effort:
@@ -80,6 +83,8 @@ The aerc-wizard runs via the command `aew`. Once setup is complete, you'll use
`aerc` to access your mail.
- `aew -a you@email.com` -- add a new email account
+- `aew -a you@email.com -P <keepassxc entry> -b keepassxc -K <path to db>` \
+ -- add a new email account using `KeepassXC`
- `aew -l` -- list existing accounts
- `aew -d` -- choose an account to delete
- `aew -D your@email.com` -- delete account settings without confirmation
diff --git a/bin/aew b/bin/aew
@@ -56,6 +56,10 @@ imapssl="IMAPS"
tlsline="tls_starttls off"
maxmes="0"
+backend="${backend:-gopass}"
+keepassxc_db="${KEEPASSXC_DB:-$HOME/.local/share/passwords.kdbx}"
+keepassxc_unlock_cmd="${KEEPASSXC_UNLOCK_CMD:-secret-tool lookup keepassxc keepassxc-db}"
+
alias mbsync='mbsync -c "$mbsyncrc"'
# mbsync >=1.4.0 requires "Far/Near" rather than "Master/Slave."
@@ -83,12 +87,36 @@ done || { echo "CA Certificate not found. Please install one or link it to /etc/
checkbasics() {
command -V gpg >/dev/null 2>&1 && GPG="gpg" || GPG="gpg2"
- PASSWORD_STORE_DIR="${PASSWORD_STORE_DIR:-$HOME/.password-store}"
- [ -r "$PASSWORD_STORE_DIR/.gpg-id" ] || {
- echo "First run \`gopass init <yourgpgemail>\` to set up a password archive."
- echo "(If you don't already have a GPG key pair, first run \`$GPG --full-generate-key\`.)"
+
+ case "$backend" in
+ gopass)
+ PASSWORD_STORE_DIR="${PASSWORD_STORE_DIR:-$HOME/.password-store}"
+ command -V gopass >/dev/null 2>&1 || {
+ echo "gopass is required for backend=gopass."
+ exit 1
+ }
+ [ -r "$PASSWORD_STORE_DIR/.gpg-id" ] || {
+ echo "First run \`gopass init <yourgpgemail>\` to set up a password archive."
+ echo "(If you don't already have a GPG key pair, first run \`$GPG --full-generate-key\`.)"
+ exit 1
+ }
+ ;;
+ keepassxc)
+ command -V keepassxc-cli >/dev/null 2>&1 || {
+ echo "keepassxc-cli is required for backend=keepassxc."
+ exit 1
+ }
+ [ -f "$keepassxc_db" ] || {
+ echo "KeePassXC database not found: $keepassxc_db"
+ exit 1
+ }
+ ;;
+ *)
+ echo "Invalid backend: $backend"
+ echo "Valid backends: gopass, keepassxc"
exit 1
- }
+ ;;
+ esac
}
getaccounts() { accounts="$(sed -n 's/^\[\(.*\)\]/\1/p' "$accountsconf" 2>/dev/null | nl)"; }
@@ -198,7 +226,14 @@ delete() {
rm -f "$msmtprc"bu
sed -ibu "/account $fulladdr$/,/^\(\s*$\|account\)/d" "$mpoprc" 2>/dev/null
rm -f "$mpoprc"bu
- gopass rm -f "$passprefix$fulladdr" >/dev/null 2>&1
+ case "$backend" in
+ gopass)
+ gopass rm -f "$passprefix$fulladdr" >/dev/null 2>&1
+ ;;
+ keepassxc)
+ # TO DO
+ ;;
+ esac
[ -n "${purge+x}" ] && safename="$(echo $fulladdr | sed 's/@/_/g')" && rm -rf "${cachedir:?}/${safename:?}" "${maildir:?}/${fulladdr:?}"
}
@@ -222,12 +257,21 @@ askinfo() {
465) scheme="smtps" ;;
587)
scheme="smtp"
- tlsline="# tls_starttls" ;;
+ tlsline="# tls_starttls"
+ ;;
esac
[ -z "$realname" ] && realname="${fulladdr%%@*}"
[ -z "$passprefix" ] && passprefix=""
hostname="${fulladdr#*@}"
login="${login:-$fulladdr}"
+ case "$backend" in
+ gopass)
+ pass_cmd="gopass $passprefix$fulladdr"
+ ;;
+ keepassxc)
+ pass_cmd="$keepassxc_unlock_cmd | keepassxc-cli show -q "$keepassxc_db" "$passprefix" -a app_code"
+ ;;
+ esac
if [ -n "${password+x}" ] && [ ! -f "$PASSWORD_STORE_DIR/$passprefix$fulladdr.gpg" ]; then
insertpass
elif [ ! -f "$PASSWORD_STORE_DIR/$passprefix$fulladdr.gpg" ]; then
@@ -236,7 +280,14 @@ askinfo() {
}
insertpass() {
- printf "%s" "$password" | gopass insert -fe "$passprefix$fulladdr"
+ case "$backend" in
+ gopass)
+ printf "%s" "$password" | gopass insert -fe "$passprefix$fulladdr"
+ ;;
+ keepassxc)
+ # TO DO
+ ;;
+ esac
}
errorexit() {
@@ -255,15 +306,34 @@ Please be sure you either enable third-party applications, or create an app-spec
}
getpass() { while :; do
- gopass rm -f "$passprefix$fulladdr" >/dev/null 2>&1
- gopass insert -f "$passprefix$fulladdr" && break
-done; }
+ case "$backend" in
+ gopass)
+ gopass rm -f "$passprefix$fulladdr" >/dev/null 2>&1
+ gopass insert -f "$passprefix$fulladdr" && break
+ ;;
+ keepassxc)
+ # TO DO
+ break;
+ ;;
+ esac
+done }
+
+catpass() {
+ case "$backend" in
+ gopass)
+ gopass "$passprefix$fulladdr"
+ ;;
+ keepassxc)
+ eval "$keepassxc_unlock_cmd" | keepassxc-cli show -q "$keepassxc_db" "$passprefix" -a app_code
+ ;;
+ esac
+}
getboxes() {
if [ -n "${force+x}" ]; then
mailboxes="$(printf "INBOX\\nDrafts\\nJunk\\nTrash\\nSent\\nArchive")"
else
- info="$(curl --location-trusted -s -m 5 --user "$login:$(gopass "$passprefix$fulladdr")" --url "${protocol:-imaps}://$imap:${iport:-993}")"
+ info="$(curl --location-trusted -s -m 5 --user "$login:$(catpass)" --url "${protocol:-imaps}://$imap:${iport:-993}")"
[ -z "$info" ] && errorexit
mailboxes="$(echo "$info" | grep -v HasChildren | sed "s/.*\" //;s/\"//g" | tr -d '\r')"
fi
@@ -412,7 +482,7 @@ reorder() {
mv "$bindsconf.new" "$bindsconf"
}
-while getopts "rfpXlhodTYD:y:i:I:s:S:u:a:n:P:x:m:t:" o; do case "${o}" in
+while getopts "rfpXlhodTYD:y:i:I:s:S:u:a:n:P:x:m:t:b:K:" o; do case "${o}" in
l) setact list ;;
r) setact reorder ;;
d) setact delete ;;
@@ -489,6 +559,14 @@ while getopts "rfpXlhodTYD:y:i:I:s:S:u:a:n:P:x:m:t:" o; do case "${o}" in
;;
T) setact toggle ;;
h) setact info ;;
+ b)
+ setact add
+ backend="$OPTARG"
+ ;;
+ K)
+ setact add
+ keepassxc_db="$OPTARG"
+ ;;
\?)
echo "See \`$(basename $0) -h\` for possible options and help."
exit 1
diff --git a/share/aerc-temp b/share/aerc-temp
@@ -1,6 +1,6 @@
[$fulladdr]
outgoing = $scheme://$aercuser%40$hostname@$smtp:$sport
maildir-account-path = $fulladdr
-outgoing-cred-cmd = gopass $passprefix$fulladdr
+outgoing-cred-cmd = $pass_cmd
from = $realname <$fulladdr>
copy-to = Sent
diff --git a/share/imapnotify-temp b/share/imapnotify-temp
@@ -7,9 +7,8 @@
},
"username": "$login",
"password": "",
- "passwordCmd": "gopass $passprefix$fulladdr",
+ "passwordCmd": "$pass_cmd",
"onNewMail": "mailsync",
"onNewMailPost": "",
"boxes": [ "INBOX" ]
}
-
diff --git a/share/mbsync-gmail-temp b/share/mbsync-gmail-temp
@@ -2,7 +2,7 @@ IMAPStore $fulladdr-remote
Host $imap
Port $iport
User $login
-PassCmd "gopass $passprefix$fulladdr"
+PassCmd "$pass_cmd"
AuthMechs LOGIN
TLSType $imapssl
CertificateFile $sslcert
diff --git a/share/mbsync-temp b/share/mbsync-temp
@@ -2,7 +2,7 @@ IMAPStore $fulladdr-remote
Host $imap
Port $iport
User $login
-PassCmd "gopass $passprefix$fulladdr"
+PassCmd "$pass_cmd"
AuthMechs LOGIN
TLSType $imapssl
CertificateFile $sslcert
diff --git a/share/mpop-temp b/share/mpop-temp
@@ -5,4 +5,4 @@ host $imap
port $iport
timeout 10
delivery maildir $maildir/$fulladdr/INBOX
-passwordeval gopass $passprefix$fulladdr
+passwordeval $pass_cmd
diff --git a/share/msmtp-temp b/share/msmtp-temp
@@ -3,7 +3,7 @@ host $smtp
port $sport
from $fulladdr
user $login
-passwordeval "gopass $passprefix$fulladdr"
+passwordeval "$pass_cmd"
auth on
tls on
tls_trust_file $sslcert
diff --git a/share/online-temp b/share/online-temp
@@ -1,4 +1,4 @@
set imap_user = "$login"
-set imap_pass = "`gopass $passprefix$fulladdr`"
+set imap_pass = "`$pass_cmd`"
set ssl_starttls = yes
set ssl_force_tls = yes