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