summaryrefslogtreecommitdiffstats
path: root/run.sh
blob: aab9b670e6cdd31e892817d65d05706bdeac312c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#!/bin/bash

#
# this function watches the $KUVERT_GNUPG_DIR files for changes
# and re-loads kuvert's config and keychain when they're detected
function watch_pubkeys {
    echo "+-- watching for changes in $KUVERT_GNUPG_DIR"
    # FIXME we need to handle SIGHUP/SIGTERM/SIGKILL nicely some day
    while true; do
        # wait for events
        set +e # yeah, inotifywatch can return a different return code than 0, and we have to be fine with that
        inotifywait -r -e modify -e move -e create -e delete -qq "$KUVERT_GNUPG_DIR/"*.gpg "$KUVERT_GNUPG_DIR/"*.gpg~
        set -e # back to being strict about stuff
        # if a watched event occured, redo authorized_keys
        if [ $? -eq 0 ]; then
            echo "    +-- files in $KUVERT_GNUPG_DIR changed"
            # we need to wait for gpg to finish its stuff
            echo "        +-- continuing in 3s..."
            sleep 3
            # permissions and ownership
            echo "        +-- making sure permissions are AOK..."
            # just the relevant files, gpg creates .lock and .tmp files too, we're going to ignore those
            chown "$KUVERT_USER":"$KUVERT_GROUP" "$KUVERT_GNUPG_DIR/" "$KUVERT_GNUPG_DIR/"*.gpg "$KUVERT_GNUPG_DIR/"*.gpg~ || \
                echo "WARNING: unable to change ownership!"
            chmod u=rwX,go= "$KUVERT_GNUPG_DIR/" "$KUVERT_GNUPG_DIR/"*.gpg "$KUVERT_GNUPG_DIR/"*.gpg~ || \
                echo "WARNING: unable to change permissions!"
            # now the important stuff
            echo "        +-- reloading kuvert config and keyring..."
            su -p -c "env PATH=\"$PATH\" kuvert -r" "$KUVERT_USER"
        fi
    done
}

# exit when any of the commands fails
set -e

# we need the KUVERT_USER envvar
[ -z ${KUVERT_USER+x} ] && KUVERT_USER="user"

# we need the KUVERT_GROUP envvar, but we can get it from the username, right?
[ -z ${KUVERT_GROUP+x} ] && KUVERT_GROUP="$KUVERT_USER"

echo "+-- settings:"
echo "    +-- KUVERT_USER  : $KUVERT_USER"
echo "    +-- KUVERT_GROUP : $KUVERT_GROUP"
echo "    +-- KUVERT_UID   : ${KUVERT_UID-<not set>}"
echo "    +-- KUVERT_GID   : ${KUVERT_GID-<not set>}"

# users' home directory
# TODO feature/future proof it
[ -z ${KUVERT_HOME+x} ] && KUVERT_HOME="/home/${KUVERT_USER}"

# important directories
[ -z ${KUVERT_LOGS_DIR+x} ] && KUVERT_LOGS_DIR="$KUVERT_HOME/logs"
[ -z ${KUVERT_QUEUE_DIR+x} ] && KUVERT_QUEUE_DIR="$KUVERT_HOME/queue"
[ -z ${KUVERT_GNUPG_DIR+x} ] && KUVERT_GNUPG_DIR="$KUVERT_HOME/gnupg"
[ -z ${KUVERT_CONFIG_DIR+x} ] && KUVERT_CONFIG_DIR="$KUVERT_HOME/config"

echo "+-- directories:"
echo "    +-- KUVERT_HOME       : ${KUVERT_HOME}"
echo "    +-- KUVERT_LOGS_DIR   : ${KUVERT_LOGS_DIR}"
echo "    +-- KUVERT_QUEUE_DIR  : ${KUVERT_QUEUE_DIR}"
echo "    +-- KUVERT_GNUPG_DIR  : ${KUVERT_GNUPG_DIR}"
echo "    +-- KUVERT_CONFIG_DIR : ${KUVERT_CONFIG_DIR}"


# get group data, if any, and check if the group exists
echo "+-- setting up the group..."
if GROUP_DATA=`getent group "$KUVERT_GROUP"`; then
    echo "    +-- group seems to exist"
    # it does! do we have the gid given?
    if [[ "$KUVERT_GID" != "" ]]; then
        # we do! do these match?
        if [[ `echo "$GROUP_DATA" | cut -d ':' -f 3` != "$KUVERT_GID" ]]; then
            # they don't. we have a problem
            echo "ERROR: group $KUVERT_GROUP already exists, but with a different gid (`echo "$GROUP_DATA" | cut -d ':' -f 3`) than provided ($KUVERT_GID)!"
            exit 3
        fi
    fi
    # if no gid given, the existing group satisfies us regardless of the GID

# group does not exist
else
    echo -n "    +-- group does not exist, creating"
    # do we have the gid given?
    GID_ARGS=""
    if [[ "$KUVERT_GID" != "" ]]; then
        # prepare the fragment of the groupadd command
        GID_ARGS="-g $KUVERT_GID"
        
        # we do! does a group with a given id exist?
        if getent group "$KUVERT_GID" >/dev/null; then
            # let's make that non-unique, then
            echo -n ' (non-unique)'
            GID_ARGS="$GID_ARGS --non-unique"
        fi
        echo -n " with gid $KUVERT_GID"
    fi
    echo
    # we either have no GID given (and don't care about it), or have a GID given that does not exist in the system
    # great! let's add the group
    groupadd $GID_ARGS "$KUVERT_GROUP"
fi


# get user data, if any, and check if the user exists
echo "+-- setting up the user..."
if USER_DATA=`id -u "$KUVERT_USER" 2>/dev/null`; then
    echo "    +-- user seems to exist"
    # it does! do we have the uid given?
    if [[ "$KUVERT_UID" != "" ]]; then
        # we do! do these match?
        if [[ "$USER_DATA" != "$KUVERT_UID" ]]; then
            # they don't. we have a problem
            echo "ERROR: user $KUVERT_USER already exists, but with a different uid ("$USER_DATA") than provided ($KUVERT_UID)!"
            exit 5
        fi
    fi
    # if no uid given, the existing user satisfies us regardless of the uid
    # but is he in the right group?
    adduser "$KUVERT_USER" "$KUVERT_GROUP"

# user does not exist
else
    # do we have the uid given?
    echo -n "    +-- user does not exist, creating"
    UID_ARGS=""
    if [[ "$KUVERT_UID" != "" ]]; then
        # prepare the fragment of the useradd command
        UID_ARGS="-u $KUVERT_UID"
        # we do! does a group with a given id exist?
        if getent passwd "$KUVERT_UID" >/dev/null; then
            echo -n ' (non-unique)'
            UID_ARGS="$UID_ARGS --non-unique"
        fi
        echo -n " with uid $KUVERT_UID"
    fi
    echo
    # we either have no UID given (and don't care about it), or have a UID given that does not exist in the system
    # great! let's add the user
    useradd $UID_ARGS -r -g "$KUVERT_GROUP" -s /bin/bash "$KUVERT_USER"
    # by default disable the password
    passwd -d "$KUVERT_USER"
    # create home
    mkdir -p "$KUVERT_HOME"
    # and make sure that permissions and ownership are set properly
    # but don't fail completely when that's not the case
    chown -R "$KUVERT_USER:$KUVERT_GROUP" "$KUVERT_HOME" || echo "WARNING: changing ownership of $KUVERT_HOME failed!"
    chmod -R ug+rwX "$KUVERT_HOME" || echo "WARNING: changing permissions on $KUVERT_HOME failed!"
fi

# the directories
echo "+-- handling directories..."
echo "    +-- creating..."
mkdir -p "$KUVERT_LOGS_DIR"
mkdir -p "$KUVERT_QUEUE_DIR"
mkdir -p "$KUVERT_GNUPG_DIR"
mkdir -p "$KUVERT_CONFIG_DIR"
echo "    +-- changing ownership..."
chown -R "$KUVERT_USER":"$KUVERT_GROUP" "$KUVERT_LOGS_DIR"
chown -R "$KUVERT_USER":"$KUVERT_GROUP" "$KUVERT_QUEUE_DIR"
chown -R "$KUVERT_USER":"$KUVERT_GROUP" "$KUVERT_GNUPG_DIR"
chown -R "$KUVERT_USER":"$KUVERT_GROUP" "$KUVERT_CONFIG_DIR" || \
    echo "WARNING: unable to change ownership of $KUVERT_CONFIG_DIR!"
echo "    +-- changing permissions..."
chmod -R u=rwX,g=rX,o= "$KUVERT_LOGS_DIR"
chmod -R u=rwX,go= "$KUVERT_QUEUE_DIR" # queue dir has to be readable only to kuvert user
chmod -R u=rwX,go= "$KUVERT_GNUPG_DIR" # gnupg home dir has to be readable only to kuvert user
chmod -R u=rwX,g=rX,o= "$KUVERT_CONFIG_DIR" || \
    echo "WARNING: unable to change permissions of $KUVERT_CONFIG_DIR!"

#
# kuvert explicitly expects the config file to be ~/.kuvert, so we need to link it to the actual config file,
# wherever we expect it to be
ln -s "$KUVERT_CONFIG_DIR/kuvert.conf" "$KUVERT_HOME/.kuvert"

# making sure the env is AOK
export HOME="$KUVERT_HOME"
export GNUPGHOME="$KUVERT_GNUPG_DIR"
# make sure said settings will be in effect upon each and every
# su - $KUVERT_USER within the container
# as that's how we'll manage gpg the keyring...
echo "export GNUPGHOME=\"$KUVERT_GNUPG_DIR\"" > "$KUVERT_HOME"/.profile
chown "$KUVERT_USER":"$KUVERT_GROUP" "$KUVERT_HOME"/.profile

# let's check up on the keyring,
# creating it if needed
echo -ne "+-- keys in keyring: "
# this has to be run as the target user
su -p -c "env PATH=\"$PATH\" gpg --list-keys" "$KUVERT_USER" 2>/dev/null | egrep '^pub' | wc -l

# if there are no secret keys in the keyring,
# generate a new password-less secret key
# "|| true" required due to "set -e", in case secret keyring is empty and egrep finds nothing
SECRET_KEYS="$( su -p -c "env PATH=\"$PATH\" gpg --list-secret-keys" "$KUVERT_USER" 2>/dev/null | egrep '^sec' )" || true
if [[ "$SECRET_KEYS" == "" ]]; then
    echo "+-- no secret keys found, generating one for: $KUVERT_USER@localhost"
    echo
    echo "    WARNING: this secret key will not be password-protected!"
    echo
    # https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html
    su -p -c "env PATH=\"$PATH\" gpg --batch --gen-key" "$KUVERT_USER" <<EOT
%no-protection
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Name-Real: $KUVERT_USER
Name-Comment: Auto-generated for kuvert testing, change as soon as possible
Name-Email: $KUVERT_USER@localhost
Expire-Date: 0
%commit
EOT
    echo "    +-- done."
else
    echo -ne "+-- secret keys in keyring: "
    echo "$SECRET_KEYS" | wc -l
fi

# watch for changes with the keyring in the background
# when changes are detected, kuvert gets reloaded
watch_pubkeys &
sleep 1

# inform
echo "========================================================================"
echo "== Starting kuvert                                                    =="
echo "========================================================================"

# change directory
echo "+-- changing directory to: $KUVERT_HOME"
cd "$KUVERT_HOME"

# time for kuvert!
echo "+-- changing user to: $KUVERT_USER"

echo -e "+-- running:\n\t$*"
exec su -p -c "env PATH=\"$PATH\" $*" "$KUVERT_USER"