From fad20e27b359f216405aad0e0f0cb7d329bc4817 Mon Sep 17 00:00:00 2001 From: Vineet Kumar Date: Fri, 22 May 2026 18:08:13 -0400 Subject: add converter script from kasi.sh to kasi.el format --- contrib/convert.sh | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 contrib/convert.sh diff --git a/contrib/convert.sh b/contrib/convert.sh new file mode 100644 index 0000000..79ca5d1 --- /dev/null +++ b/contrib/convert.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# converts kasi.sh key-value pairs to kasi.el sexps + +# kasi.sh format +# password_on_first_line +# Username: someone +# Email: bob@example.org +# TOTP: some_base32_string +# anything else can go here too + +# kasi.el format +# -*- mode: lisp -*- +# ((password "password_here") +# (username "someone") +# (email "bob@example.org") +# (totp "some_base32_string") +# (extra-content "\ +# anything not matched +# goes in here") +# +# if any of the fields are not parsed/found in original, it will be +# set to nil in sexp + +KASI_DIR="/data/kasi" +KASI_EXT=".age" +KASI_DECRYPT="age -d -i $HOME/.ssh/id_ed25519" +KASI_ENCRYPT="age -R $HOME/.ssh/id_ed25519.pub" + +lisp_val() { + if [ -z "$1" ]; then + printf 'nil' + else + printf '"%s"' "$(printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g')" + fi +} + +convert() { + f="${KASI_DIR}/${1}${KASI_EXT}" + contents="$($KASI_DECRYPT "$f")" || { + printf 'error: failed to decrypt %s\n' "$f" >&2 + return 1 + } + + first_line=$(printf '%s\n' "$contents" | sed -n '1p') + second_line=$(printf '%s\n' "$contents" | sed -n '2p') + last_char=$(printf '%s' "$contents" | tail -c 1) + if [ "$first_line" = "; -*- mode: lisp -*-" ] && [ "${second_line#((}" != "$second_line" ] && [ "$last_char" = ")" ]; then + printf 'skipping %s (already converted)\n' "$1" >&2 + return 0 + fi + + password=$(printf '%s\n' "$contents" | sed -n '1p') + username=$(printf '%s\n' "$contents" | sed -n 's/^Username:[[:space:]]*//p' | sed 's/[[:space:]]*$//' | head -1) + email=$(printf '%s\n' "$contents" | sed -n 's/^Email:[[:space:]]*//p' | sed 's/[[:space:]]*$//' | head -1) + totp=$(printf '%s\n' "$contents" | sed -n 's/^TOTP:[[:space:]]*//p' | sed 's/[[:space:]]*$//' | head -1) + + extra=$(printf '%s\n' "$contents" | awk 'NR > 1 && !/^(Username|Email|TOTP):/ && NF') + + printf '; -*- mode: lisp -*-\n' + printf '((password %s)\n' "$(lisp_val "$password")" + printf ' (username %s)\n' "$(lisp_val "$username")" + printf ' (email %s)\n' "$(lisp_val "$email")" + printf ' (totp %s)\n' "$(lisp_val "$totp")" + + if [ -z "$extra" ]; then + printf ' (extra-content nil))\n' + else + esc=$(printf '%s' "$extra" | sed 's/\\/\\\\/g; s/"/\\"/g') + printf ' (extra-content "\\\n%s"))\n' "$esc" + fi +} + +cd "$KASI_DIR" +for i in */*"$KASI_EXT"; do + i="${i%%$KASI_EXT}" + j="$(mktemp)" + convert "$i" > "$j" + $KASI_ENCRYPT <"$j" >"$i""$KASI_EXT" + rm "$j" +done -- cgit v1.2.3