logo

secret

Replacement to pass(1) based on reop(1)git clone https://hacktivis.me/git/secret.git

secret (3933B)


  1. #!/bin/sh
  2. # secret: Replacement to pass(1) based on reop(1)
  3. # Copyright 2020 Haelwenn (lanodan) Monnier <contact+secret@hacktivis.me>
  4. # SPDX-License-Identifier: ISC
  5. basepath="$HOME/.secret-storage"
  6. set -e
  7. secret_clip() {
  8. head -n 1 | tr -d '\n' | xclip -i -selection clipboard
  9. }
  10. secret_init() {
  11. set -x
  12. test -f "${basepath}.pub" -a -f "${basepath}.priv" || reop -G -p "${basepath}.pub" -s "${basepath}.priv"
  13. chmod 0400 "${basepath}.pub" "${basepath}.priv"
  14. test -d "$basepath/.git" || git init "${basepath}"
  15. chmod 0700 "$basepath"
  16. }
  17. secret_list() {
  18. ( cd "$basepath" && find . -type f -name '*.reop' "$@" | sed -e 's;^./;;' -e 's;.reop$;;') | sort
  19. }
  20. secret_list_oath() {
  21. secret_list -name '*.oath.reop' "$@"
  22. }
  23. tree() {
  24. secret_list "$@" | tree --fromfile
  25. }
  26. secret_read() {
  27. entry="$*"
  28. target="${SECRET_FILE:--}"
  29. reop -D -p "${basepath}.pub" -s "${basepath}.priv" -m "$target" -x "${basepath}/${entry}.reop"
  30. }
  31. secret_write() {
  32. entry="$*"
  33. target="${SECRET_FILE:--}"
  34. reop -E -p "${basepath}.pub" -s "${basepath}.priv" -m "$target" -x "${basepath}/${entry}.reop"
  35. if test -f "${basepath}/.git/HEAD"
  36. then
  37. oldpwd="$PWD"
  38. cd "${basepath}"
  39. git add "${entry}.reop"
  40. git commit -m "${entry}: encrypt auto-update"
  41. if [ "$(git remote show -n)" != "" ]; then git push; fi
  42. cd "${oldpwd}"
  43. else
  44. echo "No git repository in ‘$basepath’, consider creating one"
  45. fi
  46. }
  47. secret_read_oath() {
  48. oathtool $(secret_read "$@")
  49. }
  50. secret_edit() {
  51. file="${basepath}/.secret_$RANDOM.txt"
  52. unset SECRET_FILE
  53. secret_read "$@" > "$file"
  54. $EDITOR "$file" || rm -f "$file"
  55. secret_write "$@" < "$file" ; rm -f "$file"
  56. }
  57. secret_delete() {
  58. entry="$*"
  59. (
  60. cd "${basepath}"
  61. if test -f "${basepath}/.git/HEAD"
  62. then
  63. git rm "${entry}.reop"
  64. git commit -m "${entry}: remove"
  65. if [ "$(git remote show -n)" != "" ]; then git push; fi
  66. else
  67. echo "No git repository in ‘$basepath’, consider creating one"
  68. rm "${entry}.reop"
  69. fi
  70. )
  71. }
  72. secret_dmenu() {
  73. echo | dmenu -nb '#000' -nf '#000' -p "Passphrase: "
  74. }
  75. secret_dmenu_oath() {
  76. entry="$(secret_list -name '*.oath.reop' | dmenu -i)"
  77. export SECRET_FILE="${basepath}/.secret_$RANDOM.txt"
  78. secret_dmenu | secret_read "$entry"
  79. oathtool $(cat "${SECRET_FILE}") | secret_clip
  80. shred -u "${SECRET_FILE}"
  81. }
  82. secret_dmenu_read() {
  83. entry="$(secret_list | dmenu -i)"
  84. export SECRET_FILE="${basepath}/.secret_$RANDOM.txt"
  85. secret_dmenu | secret_read "$entry"
  86. cat "${SECRET_FILE}" | secret_clip
  87. shred -u "${SECRET_FILE}"
  88. }
  89. secret_usage() {
  90. cat <<-EOF
  91. secret [command] [command-arguments...]
  92. Replacement to pass(1) based on reop(1)
  93. secret init
  94. Initializes secret keys and git storage repo.
  95. secret ls [arguments...]
  96. List the entries. Passes arguments to find(1).
  97. secret tree [arguments...]
  98. Same as ‘secret ls’ but outputs via tree(1).
  99. secret read <entry>
  100. Read a secret entry.
  101. secret write <entry>
  102. Write a secret entry.
  103. secret edit <entry>
  104. Wrapper around $EDITOR for easy secret edition.
  105. secret delete <entry>
  106. Delete a secret entry.
  107. secret dmenu
  108. dmenu on entries, dmenu for a passphrase, read secret, pipe to xclip(1).
  109. secret ls-oath [arguments...]
  110. Same as ‘secret ls’ but limited to oath entries(‘*.oath.reop’).
  111. secret read-oath <entry>
  112. Same as ‘secret read’ but entry content passed to oathtool(1) as arguments.
  113. secret dmenu-oath
  114. Same as ‘secret dmenu’ but ‘secret read-oath’ instead of ‘secret read’.
  115. EOF
  116. exit 1
  117. }
  118. command="$1"
  119. [ "$1" = "" ] && secret_usage "$@"
  120. shift || secret_usage "$@"
  121. case "$command" in
  122. init) secret_init "$@" ;;
  123. ls) secret_list "$@" ;;
  124. tree) secret_tree "$@" ;;
  125. read) secret_read "$@" ;;
  126. write) secret_write "$@" ;;
  127. edit) secret_edit "$@" ;;
  128. del*) secret_delete "$@" ;;
  129. dmenu) secret_dmenu_read "$@" ;;
  130. ls-oath) secret_list_oath "$@" ;;
  131. read-oath) secret_read_oath "$@" ;;
  132. dmenu-oath) secret_dmenu_oath "$@" ;;
  133. *) secret_usage "$@" ;;
  134. esac