freedombone-recoverkey 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #!/bin/bash
  2. #
  3. # .---. . .
  4. # | | |
  5. # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
  6. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
  7. # ' ' --' --' -' - -' ' ' -' -' -' ' - --'
  8. #
  9. # Freedom in the Cloud
  10. #
  11. # A script which recovers a user's gpg key from a number of fragments
  12. # License
  13. # =======
  14. #
  15. # Copyright (C) 2015-2018 Bob Mottram <bob@freedombone.net>
  16. #
  17. # This program is free software: you can redistribute it and/or modify
  18. # it under the terms of the GNU Affero General Public License as published by
  19. # the Free Software Foundation, either version 3 of the License, or
  20. # (at your option) any later version.
  21. #
  22. # This program is distributed in the hope that it will be useful,
  23. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. # GNU Affero General Public License for more details.
  26. #
  27. # You should have received a copy of the GNU Affero General Public License
  28. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  29. PROJECT_NAME='freedombone'
  30. export TEXTDOMAIN=${PROJECT_NAME}-recoverkey
  31. export TEXTDOMAINDIR="/usr/share/locale"
  32. source "$PROJECT_INSTALL_DIR/${PROJECT_NAME}-vars"
  33. # include utils which allow function_check, go and drive mount
  34. UTILS_FILES="/usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-*"
  35. for f in $UTILS_FILES
  36. do
  37. source "$f"
  38. done
  39. FRIENDS_SERVERS_LIST=
  40. MY_USERNAME=
  41. function show_help {
  42. echo ''
  43. echo $"${PROJECT_NAME}-recoverkey -u [username]"
  44. echo $' -l [friends servers list filename]'
  45. echo ''
  46. exit 0
  47. }
  48. while [ $# -gt 1 ]
  49. do
  50. key="$1"
  51. case $key in
  52. -h|--help)
  53. show_help
  54. ;;
  55. -u|--user)
  56. shift
  57. MY_USERNAME="$1"
  58. ;;
  59. # backup list filename
  60. # typically /home/$USER/backup.list
  61. -l|--list)
  62. shift
  63. FRIENDS_SERVERS_LIST="$1"
  64. ;;
  65. *)
  66. # unknown option
  67. ;;
  68. esac
  69. shift
  70. done
  71. if [ ! "$MY_USERNAME" ]; then
  72. show_help
  73. fi
  74. if [ ! -d "/home/$MY_USERNAME" ]; then
  75. echo $"User $MY_USERNAME does not exist on the system"
  76. exit 7270
  77. fi
  78. if [ ! "$MY_USERNAME" ]; then
  79. echo $'No username given'
  80. exit 3578
  81. fi
  82. if [ ! -d "/home/$MY_USERNAME" ]; then
  83. echo $"User $MY_USERNAME does not exist on the system"
  84. exit 7270
  85. fi
  86. FRAGMENTS_DIR="/home/$MY_USERNAME/.gnupg_fragments"
  87. # if no remote backup list was given then assume recover from USB
  88. if [ ! "$FRIENDS_SERVERS_LIST" ]; then
  89. interactive_gpg_from_usb
  90. exit 0
  91. fi
  92. # obtain shares/fragments from remote locations
  93. if [ "$FRIENDS_SERVERS_LIST" ]; then
  94. # For each remote server
  95. while read -r remote_server
  96. do
  97. # Get the server and its password
  98. # Format is:
  99. # username@domain:/home/username <port number> <ssh password>
  100. REMOTE_SERVER=$(echo "${remote_server}" | awk -F ' ' '{print $1}')
  101. if [ "$REMOTE_SERVER" ]; then
  102. REMOTE_SSH_PORT=$(echo "${remote_server}" | awk -F ' ' '{print $2}')
  103. REMOTE_PASSWORD=$(echo "${remote_server}" | awk -F ' ' '{print $3}')
  104. # create a directory if it doesn't exist
  105. if [ ! -d "/home/$MY_USERNAME/.gnupg_fragments" ]; then
  106. mkdir -p "/home/$MY_USERNAME/.gnupg_fragments"
  107. fi
  108. echo -n $"Starting key retrieval from $REMOTE_SERVER..."
  109. /usr/bin/sshpass -p "$REMOTE_PASSWORD" \
  110. scp -r -P "$REMOTE_SSH_PORT" "$REMOTE_SERVER/.gnupg_fragments/"* "/home/$MY_USERNAME/.gnupg_fragments"
  111. # shellcheck disable=SC2181
  112. if [ ! "$?" = "0" ]; then
  113. echo $'FAILED'
  114. else
  115. echo $'Ok'
  116. fi
  117. fi
  118. done < "$FRIENDS_SERVERS_LIST"
  119. fi
  120. # was a directory created?
  121. if [ ! -d "$FRAGMENTS_DIR" ]; then
  122. echo $'No fragments have been recovered, so the key cannot be recovered'
  123. exit 7483
  124. fi
  125. # was anything downloaded?
  126. cd "$FRAGMENTS_DIR" || exit 24682468
  127. # shellcheck disable=SC2012
  128. no_of_shares=$(ls -afq keyshare.asc.* | wc -l)
  129. if (( no_of_shares == 0 )); then
  130. echo $'No key fragments were retrieved'
  131. exit 76882
  132. fi
  133. # set permissions on the fragments
  134. chown -R "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.gnupg_fragments"
  135. # decrypt the file
  136. KEYS_FILE=$FRAGMENTS_DIR/keyshare.asc
  137. cd "$FRAGMENTS_DIR" || exit 482746874624
  138. gfcombine "$KEYS_FILE.*"
  139. if [ ! -f "$KEYS_FILE" ]; then
  140. echo $'Unable to decrypt key. This may mean that not enough fragments are available'
  141. exit 6283
  142. fi
  143. echo $'Key fragments recombined'
  144. # import the gpg key
  145. if ! gpg --homedir="/home/$MY_USERNAME/.gnupg" --allow-secret-key-import --import "$KEYS_FILE"; then
  146. echo $'Unable to import gpg key'
  147. shred -zu "$KEYS_FILE"
  148. exit 3682
  149. fi
  150. shred -zu "$KEYS_FILE"
  151. chown -R "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.gnupg"
  152. chmod -R 600 "/home/$MY_USERNAME/.gnupg"
  153. echo $'GPG key was recovered'
  154. exit 0