summaryrefslogtreecommitdiff
path: root/src/transitions/0.23
blob: b0c967ac08a97ea3b740f7d3e3f6e305f3fade97 (plain)
  1. #!/bin/bash
  2. # This is a post-install script for monkeysphere, to transition an old
  3. # (<0.23) setup to the new (>=0.23) setup.
  4. # You should be able to run this script after any version >= 0.23 is
  5. # installed. This script should be well-behaved, even if it is run
  6. # repeatedly.
  7. # Written by
  8. # Jameson Rollins <jrollins@finestructure.net>
  9. # Daniel Kahn Gillmor <dkg@fifthhorseman.net>
  10. #
  11. # Copyright 2009, released under the GPL, version 3 or later
  12. # NOTE: the reverse operation (downgrading) is not directly supported,
  13. # and MAY LOCK YOU OUT OF YOUR SYSTEM, depending on how you have
  14. # configured the monkeysphere!
  15. # any unexpected errors should cause this script to bail:
  16. set -e
  17. SYSDATADIR=${MONKEYSPHERE_SYSDATADIR:-"/var/lib/monkeysphere"}
  18. SYSCONFIGDIR=${MONKEYSPHERE_SYSCONFIGDIR:-"/etc/monkeysphere"}
  19. MADATADIR="${SYSDATADIR}/authentication"
  20. MHDATADIR="${SYSDATADIR}/host"
  21. STASHDIR="${SYSDATADIR}/backup-from-0.23-transition"
  22. log() {
  23. printf "$@" >&2
  24. }
  25. # FIXME: implement this function better. here, we only care about
  26. # dots, *and* about reversing the regexification of them.
  27. gpg_unescape_and_unregex() {
  28. sed 's/\\x5c\././g'
  29. }
  30. is_domain_name() {
  31. printf "%s" "$1" | egrep -q '^[[:alnum:]][[:alnum:]-.]*[[:alnum:]]$'
  32. }
  33. # move the old server conf file to be the authentication conf file
  34. if [ -f "$SYSCONFIGDIR"/monkeysphere-server.conf -a \
  35. ! -f "$SYSCONFIGDIR"/monkeysphere-authentication.conf ] ; then
  36. mv "$SYSCONFIGDIR"/monkeysphere-server.conf "$SYSCONFIGDIR"/monkeysphere-authentication.conf
  37. fi
  38. # run the authentication setup (this is also the first chance to bail
  39. # if 0.23 is not fully-installed, because m-a did not exist before
  40. # 0.23)
  41. monkeysphere-authentication setup
  42. # before 0.23, the old gnupg-host data directory used to contain the
  43. # trust core and the system's ssh host key.
  44. if [ -d "$SYSDATADIR"/gnupg-host ] ; then
  45. ### transfer identity certifiers, if they don't already exist in the
  46. ### current setup:
  47. if monkeysphere-authentication list-identity-certifiers | \
  48. grep -q '^[A-F0-9]{40}:$' ; then
  49. log 'There are already certifiers in the new system!\nNot transferring any certifiers.\n'
  50. else
  51. # get the old host keygrip (don't know why there would be more
  52. # than one, but we'll transfer all tsigs made by any key that
  53. # had been given ultimate ownertrust):
  54. for authgrip in $(GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --export-ownertrust | \
  55. grep ':6:$' | \
  56. sed -r 's/^[A-F0-9]{24}([A-F0-9]{16}):6:$/\1/') ; do
  57. # we're assuming that old id certifiers were only added by old
  58. # versions of m-s c+, which added certifiers by ltsigning
  59. # entire keys.
  60. # so we'll walk the list of tsigs from the old host key, and
  61. # add those keys as certifiers to the new system.
  62. # FIXME: if an admin has run "m-s add-id-certifier $foo"
  63. # multiple times for the same $foo, we'll only transfer
  64. # one of those certifications (even if later
  65. # certifications had different parameters).
  66. GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --fingerprint --with-colons --fixed-list-mode --check-sigs | \
  67. cut -f 1,2,5,8,9,10 -d: | \
  68. egrep '^(fpr:::::|sig:!:'"$authgrip"':[[:digit:]]+ [[:digit:]]+:)' | \
  69. while IFS=: read -r type validity grip trustparams trustdomain fpr ; do
  70. case $type in
  71. 'fpr') # this is a new key
  72. keyfpr=$fpr
  73. ;;
  74. 'sig') # deal with all trust signatures, including
  75. # regexes if present.
  76. if [ "$keyfpr" ] ; then
  77. trustdepth=${trustparams%% *}
  78. trustlevel=${trustparams##* }
  79. if [ "$trustlevel" -ge 120 ] ; then
  80. truststring=full
  81. elif [ "$trustlevel" -ge 60 ] ; then
  82. truststring=marginal
  83. else
  84. # trust levels below marginal are ignored.
  85. continue
  86. fi
  87. finaldomain=
  88. if [ "$trustdomain" ] ; then
  89. # FIXME: deal with translating
  90. # $trustdomain back to a domain.
  91. if [ printf "%s" "$trustdomain" | egrep -q '^<\[\^>\]\+\[@\.\][^>]+>\$$' ] ; then
  92. dpart=$(printf "%s" "$trustdomain" | sed -r 's/^<\[\^>\]\+\[@\.\]([^>]+)>\$$/\1/' | gpg_unescape_and_unregex)
  93. if [ is_domain_name "$dpart" ]; then
  94. finaldomain="--domain $dpart"
  95. else
  96. log "Does not seem to be a domain name (%s), not adding certifier\n" "$dpart"
  97. continue
  98. fi
  99. else
  100. log "Does not seem to be a standard gpg domain-based tsig (%s), not adding certifier\n" "$trustdomain"
  101. continue
  102. fi
  103. fi
  104. CERTKEY=$(mktemp ${TMPDIR:-/tmp}/mstransition.XXXXXXXX)
  105. log "Adding identity certifier with fingerprint %s\n" "$keyfpr"
  106. GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --export "0x$keyfpr" --export-options export-clean >"$CERTKEY"
  107. MONKEYSPHERE_PROMPT=false monkeysphere-authentication add-identity-certifier $finaldomain --trust "$truststring" --depth "$trustdepth" "$CERTKEY"
  108. rm -f "$CERTKEY"
  109. # clear the fingerprint so that we don't
  110. # make additional tsigs on it if more uids
  111. # are present:
  112. keyfpr=
  113. fi
  114. ;;
  115. esac
  116. done
  117. done
  118. fi
  119. ### transfer host key information (if present) into the new spot
  120. if [ -d "${MHDATADIR}" ] ; then
  121. log "Not transferring host key info because host directory already exists.\n"
  122. else
  123. if [ -s "$SYSDATADIR"/ssh_host_rsa_key ] || \
  124. GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --with-colons --list-secret-keys | grep -q '^sec:' ; then
  125. FPR=$(GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --with-colons --fixed-list-mode --list-secret-keys --fingerprint | awk -F: '/^fpr:/{ print $10 }' )
  126. # create host home
  127. mkdir -p $(dirname "$MHDATADIR")
  128. NEWDATADIR=$(mktemp -d "${MHDATADIR}.XXXXXX")
  129. chmod 0700 "${NEWDATADIR}"
  130. log "importing host key from old monkeysphere installation\n"
  131. # export from the pubring as well as the that new (non-expired)
  132. # self-sigs are available, otherwise the secret key import may fail
  133. # FIXME: turns out the secret key import fails anyway, stupidly :(
  134. # FIXME: if all self-sigs are expired, then the secret key import may
  135. # fail anyway. How should we deal with that?
  136. if (GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --export-secret-keys && \
  137. GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --export "$FPR") | \
  138. GNUPGHOME="$NEWDATADIR" gpg --quiet --no-tty --import ; then
  139. : we are in good shape!
  140. else
  141. if ! GNUPGHOME="$NEWDATADIR" gpg --list-secret-key >/dev/null ; then
  142. log "The old host key (%s) was not imported properly.\n" "$FPR"
  143. exit 1
  144. fi
  145. fi
  146. # if we get here cleanly, then we're OK to move forward:
  147. mv "$NEWDATADIR" "$MHDATADIR"
  148. monkeysphere-host update-gpg-pub-file
  149. else
  150. log "No host key found in old monkeysphere install; not importing any host key.\n"
  151. fi
  152. fi
  153. ### get rid of this old stuff, since we've transferred it all:
  154. mkdir -p "$STASHDIR"
  155. chmod 0700 "$STASHDIR"
  156. mv "${SYSDATADIR}/gnupg-host" "$STASHDIR"
  157. fi
  158. # There is nothing in the old authentication directory that we should
  159. # need to keep around, but it is not unreasonable to transfer keys to
  160. # the new authentication keyring.
  161. if [ -d "${SYSDATADIR}/gnupg-authentication" ] ; then
  162. GNUPGHOME="${SYSDATADIR}/gnupg-authentication" gpg --no-permission-warning --export | \
  163. monkeysphere-authentication gpg-cmd --import || \
  164. log "No OpenPGP certificates imported into monkeysphere-authentication trust sphere.\n"
  165. mkdir -p "$STASHDIR"
  166. chmod 0700 "$STASHDIR"
  167. mv "${SYSDATADIR}/gnupg-authentication" "$STASHDIR"
  168. fi