#!/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