Advertisement
MestreLion

clearsign - Signs a single file using GnuPG (gpg)

Jul 30th, 2011
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 5.00 KB | None | 0 0
  1. #!/bin/bash
  2. #
  3. # clearsign - Signs a single file using GnuPG (gpg)
  4. # in clearsign mode (non-detached, ASCII-armored)
  5. # Uses zenity for GUI. Nautilus-scripts compatible.
  6. #
  7. #    Copyright (C) 2011 Rodrigo Silva - <[email protected]>
  8. #
  9. #    This program is free software: you can redistribute it and/or modify
  10. #    it under the terms of the GNU General Public License as published by
  11. #    the Free Software Foundation, either version 3 of the License, or
  12. #    (at your option) any later version.
  13. #
  14. #    This program is distributed in the hope that it will be useful,
  15. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. #    GNU General Public License for more details.
  18. #
  19. #    You should have received a copy of the GNU General Public License
  20. #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  21. #
  22. # Huge thanks to all the gurus and friends in <irc://irc.freenet.org/#bash>
  23. # and the contributors of <http://mywiki.wooledge.org/>
  24. #
  25. # Usage: clearsign FILE
  26. #
  27. # TODO: add more output options:
  28. #        Detached binary (file.ext.sig) - "gpg --detach-sign"
  29. #        Detached text   (file.ext.asc) - "gpg --detach-sign --armor"
  30. #    Non-Detached binary (file.ext.gpg) - "gpg --sign"
  31. #    Non-Detached binary-to-text (file.ext.asc) - "gpg --sign --armor"
  32. #
  33. # TODO: add help, usage, verbose, debug, force, etc
  34. # TODO: test if zenity and gpg avaliable
  35. # TODO: allow multiple files and directories
  36. # TODO: update common lib and use it
  37. # TODO: read (and pre-select) default key from searhorse
  38. # TODO: use proper icon
  39. # FIXME: gnupg creates blank dir.asc if file is actually a dir
  40.  
  41.  
  42. # User input
  43. FILE="$1"            # globs not allowed.. for now
  44. OUTPUT="${FILE}.asc" # user may only change if already exists
  45.  
  46. # Constants
  47. SELF="${0##*/}"
  48. SELF_GUI="Sign file"
  49. WIDTH_MAX=790
  50. WIDTH_BASE=250
  51. WIDTH_UNIT=8    #char
  52.  
  53. HEIGHT_MAX=600
  54. HEIGHT_BASE=130
  55. HEIGHT_UNIT=25  #line
  56.  
  57. # Variables
  58. max_chars=0
  59. window_width=0
  60. window_height=0
  61.  
  62.  
  63. # Functions
  64.  
  65. fatal() { : ; }
  66.  
  67. fatalgui()
  68. {
  69.     local message="$1"
  70.     local errorcode="${2:-1}"
  71.     local dump="$3"
  72.    
  73.     [[ -n "$dump"    ]] && echo "$dump" >&2
  74.     [[ -n "$message" ]] && echo "$SELF: ${message/%['!''.'':']/}" >&2
  75.  
  76.     zenity --error --title="$SELF_GUI" \
  77.            --text="${message:+$message\n\n}${dump:+$dump\n\n}" #"Exiting with error code ${errorcode}"
  78.    
  79.     exit $errorcode
  80. }
  81.  
  82. min() { (( $1 < $2 )) && printf %d "$1" || printf %d "$2"; }
  83. max() { (( $1 > $2 )) && printf %d "$1" || printf %d "$2"; }
  84.  
  85.  
  86. # =========================================== MAIN
  87.  
  88. # Check input file
  89. [[ -r "$FILE" ]] || fatalgui "File to sign is missing or is not readable."
  90.  
  91. # Check more than 1 file
  92. [[ $# = 1 ]] || {
  93.     zenity --question --title="Multiple files" \
  94.         --text="Multiple files were selected, but only this will be signed:\n\n${FILE}\n\nProceed?" \
  95.     || exit 0
  96. }
  97.  
  98. # Grab the list of keys
  99. keys=$(
  100.     gpg --list-keys --with-colons --keyid-format short 2>&1
  101. ) || fatalgui "Error when retrieving list of keys:" $? "$keys"
  102.  
  103. # Empy array to hold the keys
  104. array=()
  105.  
  106. # Loop the list
  107. while IFS=":" read -r -s keyType _ keySize _ keyId keyDate _ _ _ keyUser _ keyFlags _ ; do
  108.  
  109.     # Check for (pub)lic keys that are able to (s)ign and are not (D)isabled
  110.     if [[ "$keyType" = "pub" && "$keyFlags" = *s* && ! "$keyFlags" = *D* ]] ; then
  111.    
  112.         # populate the array
  113.         array+=("$keyId" "$keyUser" "${keyId:(-8)}" "$keyDate" "$keySize")
  114.        
  115.         # Save the number of chars of the longest user string
  116.         (( ${#keyUser} > $max_chars )) && max_chars=${#keyUser}
  117.  
  118.         #DEBUG echo "$keyType|$keySize|${keyId:(-8)}|$keyDate|${#keyUser}|$max_chars|$keyUser"
  119.     fi
  120.    
  121. done <<< "$keys"
  122.  
  123. # Check if suitable keys were found
  124. [[ ${#array[@]} = 0 ]] && fatalgui "No suitable keys for signing were found."
  125.  
  126. # Set window height and weight
  127. window_width=$(  min  $WIDTH_MAX $(( $WIDTH_BASE +  $WIDTH_UNIT * $max_chars    )) )
  128. window_height=$( min $HEIGHT_MAX $(($HEIGHT_BASE + $HEIGHT_UNIT * ${#array[@]}/5)) )
  129.  
  130. # Choose key
  131. key=$(
  132.     zenity --list --title="Choose Signer" --text="Sign file as:" --hide-column=1        \
  133.            --width=$window_width --height=$window_height                                \
  134.            --window-icon="/usr/share/pixmaps/seahorse-plugins/22x22/seahorse-key.png"   \
  135.            --column="id" --column="User" --column="Key" --column="Date" --column="Size" \
  136.            "${array[@]}"
  137. ) || exit 0
  138.  
  139.  
  140. # default output already exists?
  141. [[ -f "$OUTPUT" ]] && {
  142.    
  143.     # prompt for another output file
  144.     OUTPUT=$(
  145.         zenity --file-selection --save --filename="$OUTPUT"                               \
  146.                --window-icon="/usr/share/pixmaps/seahorse-plugins/22x22/seahorse-key.png" \
  147.                --title="Choose Signed File Name for ${FILE##*/}"                          \
  148.                --confirm-overwrite --file-filter "*.asc"
  149.     ) || exit 0
  150. }
  151.  
  152.  
  153. # Do it! :D
  154. dump=$(
  155.     gpg --clearsign --batch --yes --default-key="$key" --output="$OUTPUT" "$FILE" 2>&1
  156. ) || fatalgui "Error when signing $FILE:" $? "$dump"
  157.  
  158.  
  159. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement