rpm: assign a real shell to user monkeysphere
[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 SYSCONFIGDIR=${MONKEYSPHERE_SYSCONFIGDIR:-"/etc/monkeysphere"}
25
26 MADATADIR="${SYSDATADIR}/authentication"
27 MHDATADIR="${SYSDATADIR}/host"
28
29 STASHDIR="${SYSDATADIR}/backup-from-0.23-transition"
30
31
32 log() {
33     printf "$@" >&2
34 }
35
36 # FIXME: implement this function better.  here, we only care about
37 # dots, *and* about reversing the regexification of them.
38 gpg_unescape_and_unregex() {
39     sed  's/\\x5c\././g'
40 }
41
42
43 is_domain_name() {
44     printf "%s" "$1" | egrep -q '^[[:alnum:]][[:alnum:]-.]*[[:alnum:]]$'
45 }
46
47
48 # move the old server conf file to be the authentication conf file
49 if [ -f "$SYSCONFIGDIR"/monkeysphere-server.conf -a \
50     ! -f "$SYSCONFIGDIR"/monkeysphere-authentication.conf ] ; then
51     mv "$SYSCONFIGDIR"/monkeysphere-server.conf "$SYSCONFIGDIR"/monkeysphere-authentication.conf
52 fi
53
54 # run the authentication setup (this is also the first chance to bail
55 # if 0.23 is not fully-installed, because m-a did not exist before
56 # 0.23)
57 monkeysphere-authentication setup
58
59 # before 0.23, the old gnupg-host data directory used to contain the
60 # trust core and the system's ssh host key.  
61
62 if [ -d "$SYSDATADIR"/gnupg-host ] ; then
63
64 ### transfer identity certifiers, if they don't already exist in the
65 ### current setup:
66
67     if monkeysphere-authentication list-identity-certifiers | \
68         grep -q '^[A-F0-9]{40}:$' ; then
69         log 'There are already certifiers in the new system!\nNot transferring any certifiers.\n'
70     else
71         # get the old host keygrip (don't know why there would be more
72         # than one, but we'll transfer all tsigs made by any key that
73         # had been given ultimate ownertrust):
74         for authgrip in $(GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --export-ownertrust | \
75             grep ':6:$' | \
76             sed -r 's/^[A-F0-9]{24}([A-F0-9]{16}):6:$/\1/') ; do
77             
78         # we're assuming that old id certifiers were only added by old
79         # versions of m-s c+, which added certifiers by ltsigning
80         # entire keys.
81             
82         # so we'll walk the list of tsigs from the old host key, and
83         # add those keys as certifiers to the new system.
84
85             # FIXME: if an admin has run "m-s add-id-certifier $foo"
86             # multiple times for the same $foo, we'll only transfer
87             # one of those certifications (even if later
88             # certifications had different parameters).
89             
90             GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --fingerprint --with-colons --fixed-list-mode --check-sigs | \
91                 cut -f 1,2,5,8,9,10 -d: | \
92                 egrep '^(fpr:::::|sig:!:'"$authgrip"':[[:digit:]]+ [[:digit:]]+:)' | \
93                 while IFS=: read -r type validity grip trustparams trustdomain fpr ; do
94                 case $type in
95                     'fpr') # this is a new key
96                         keyfpr=$fpr
97                         ;;
98                     'sig') # deal with all trust signatures, including
99                            # regexes if present.
100                         if [ "$keyfpr" ] ; then
101                             trustdepth=${trustparams%% *}
102                             trustlevel=${trustparams##* }
103                             if [ "$trustlevel" -ge 120 ] ; then
104                                 truststring=full
105                             elif [ "$trustlevel" -ge 60 ] ; then
106                                 truststring=marginal
107                             else
108                                 # trust levels below marginal are ignored.
109                                 continue
110                             fi
111
112                             finaldomain=
113                             if [ "$trustdomain" ] ; then
114                             # FIXME: deal with translating
115                             # $trustdomain back to a domain.
116                                 if [ printf "%s" "$trustdomain" | egrep -q '^<\[\^>\]\+\[@\.\][^>]+>\$$' ] ; then
117                                     dpart=$(printf "%s" "$trustdomain" | sed -r 's/^<\[\^>\]\+\[@\.\]([^>]+)>\$$/\1/' | gpg_unescape_and_unregex)
118                                     if [ is_domain_name "$dpart" ]; then
119                                         finaldomain="--domain $dpart"
120                                     else
121                                         log "Does not seem to be a domain name (%s), not adding certifier\n" "$dpart"
122                                         continue
123                                     fi
124                                 else
125                                     log "Does not seem to be a standard gpg domain-based tsig (%s), not adding certifier\n" "$trustdomain"
126                                     continue
127                                 fi
128                             fi
129
130                             CERTKEY=$(mktemp ${TMPDIR:-/tmp}/mstransition.XXXXXXXX)
131                             log "Adding identity certifier with fingerprint %s\n" "$keyfpr"
132                             GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --export "0x$keyfpr" --export-options export-clean >"$CERTKEY"
133                             MONKEYSPHERE_PROMPT=false monkeysphere-authentication add-identity-certifier $finaldomain --trust "$truststring" --depth "$trustdepth" "$CERTKEY"
134                             rm -f "$CERTKEY"
135                             # clear the fingerprint so that we don't
136                             # make additional tsigs on it if more uids
137                             # are present:
138                             keyfpr=
139                         fi
140                         ;;
141                 esac
142             done
143         done
144     fi
145
146 ### transfer host key information (if present) into the new spot
147     
148     if [ -d "${MHDATADIR}" ] ; then
149         log "Not transferring host key info because host directory already exists.\n"
150     else
151         if [ -s "$SYSDATADIR"/ssh_host_rsa_key ] || \
152             GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --with-colons --list-secret-keys | grep -q '^sec:' ; then
153             
154             FPR=$(GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --with-colons --fixed-list-mode --list-secret-keys --fingerprint | awk -F: '/^fpr:/{ print $10 }' )
155             
156         # create host home
157             mkdir -p $(dirname "$MHDATADIR")
158             NEWDATADIR=$(mktemp -d "${MHDATADIR}.XXXXXX")
159             chmod 0700 "${NEWDATADIR}"
160             
161             log "importing host key from old monkeysphere installation\n"
162
163 # export from the pubring as well as the that new (non-expired)
164 # self-sigs are available, otherwise the secret key import may fail
165
166 # FIXME: turns out the secret key import fails anyway, stupidly :(
167
168 # FIXME: if all self-sigs are expired, then the secret key import may
169 # fail anyway. How should we deal with that?
170             
171             if (GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --export-secret-keys && \
172                 GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --export "$FPR") | \
173                 GNUPGHOME="$NEWDATADIR" gpg --quiet --no-tty --import ; then
174                 : we are in good shape!
175             else
176                 if ! GNUPGHOME="$NEWDATADIR" gpg --quiet --no-tty --list-secret-key >/dev/null ; then
177                     log "The old host key (%s) was not imported properly.\n" "$FPR"
178                     exit 1
179                 fi
180             fi
181                 
182             # if we get here cleanly, then we're OK to move forward:
183             mv "$NEWDATADIR" "$MHDATADIR"
184
185             monkeysphere-host update-gpg-pub-file
186         else
187             log "No host key found in old monkeysphere install; not importing any host key.\n"
188         fi
189     fi
190
191
192 ### get rid of this old stuff, since we've transferred it all:
193
194     mkdir -p "$STASHDIR"
195     chmod 0700 "$STASHDIR"
196     mv "${SYSDATADIR}/gnupg-host" "$STASHDIR"/gnupg-host.$(date '+%F_%T%z')
197 fi
198
199
200 # There is nothing in the old authentication directory that we should
201 # need to keep around, but it is not unreasonable to transfer keys to
202 # the new authentication keyring.
203 if [ -d "${SYSDATADIR}/gnupg-authentication" ] ; then
204
205     GNUPGHOME="${SYSDATADIR}/gnupg-authentication" \
206         gpg --quiet --no-tty --no-permission-warning --export 2>/dev/null | \
207         monkeysphere-authentication gpg-cmd --import 2>/dev/null || \
208         log "No OpenPGP certificates imported into monkeysphere-authentication trust sphere.\n"
209
210     mkdir -p "$STASHDIR"
211     chmod 0700 "$STASHDIR"
212     mv "${SYSDATADIR}/gnupg-authentication" "$STASHDIR"/gnupg-authentication.$(date '+%F_%T%z')
213 fi