/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release

« back to all changes in this revision

Viewing changes to mandos-keygen

First version of a somewhat complete D-Bus server interface.  Also
change user/group name to "_mandos".

* debian/mandos.postinst: Rename old "mandos" user and group to
                          "_mandos"; create "_mandos" user and group
                          if none exist.
* debian/mandos-client.postinst: - '' -

* initramfs-tools-hook: Try "_mandos" before "mandos" as user and
                        group name.

* mandos (_datetime_to_dbus_struct): New; was previously local.
  (Client.started): Renamed to "last_started".  All users changed.
  (Client.started): New; boolean.
  (Client.dbus_object_path): New.
  (Client.check_command): Renamed to "checker_command".  All users
                          changed.
  (Client.__init__): Set and use "self.dbus_object_path".  Set
                     "self.started".
  (Client.start): Update "self.started".  Emit "self.PropertyChanged"
                  signals for both "started" and "last_started".
  (Client.stop): Update "self.started".  Emit "self.PropertyChanged"
                 signal for "started".
  (Client.checker_callback): Take additional "command" argument.  All
                             callers changed. Emit
                             "self.PropertyChanged" signal.
  (Client.bump_timeout): Emit "self.PropertyChanged" signal for
                         "last_checked_ok".
  (Client.start_checker): Emit "self.PropertyChanged" signal for
                          "checker_running".
  (Client.stop_checker): Emit "self.PropertyChanged" signal for
                         "checker_running".
  (Client.still_valid): Bug fix: use "getattr(self, started, False)"
                        instead of "self.started" in case this client
                        object is so new that the "started" attribute
                        has not been created yet.
  (Client.IntervalChanged, Client.CheckerIsRunning, Client.GetChecker,
  Client.GetCreated, Client.GetFingerprint, Client.GetHost,
  Client.GetInterval, Client.GetName, Client.GetStarted,
  Client.GetTimeout, Client.StateChanged, Client.TimeoutChanged):
  Removed; all callers changed.
  (Client.CheckerCompleted): Add "condition" and "command" arguments.
                             All callers changed.
  (Client.GetAllProperties, Client.PropertyChanged): New.
  (Client.StillValid): Renamed to "IsStillValid".
  (Client.StartChecker): Changed to its own function to avoid the
                         return value from "Client.start_checker()".
  (Client.Stop): Changed to its own function to avoid the return value
                 from "Client.stop()".
  (main): Try "_mandos" before "mandos" as user and group name.
          Removed inner function "remove_from_clients".  New inner
          class "MandosServer".

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
3
3
# Mandos key generator - create a new OpenPGP key for a Mandos client
4
4
5
 
# Copyright © 2008-2016 Teddy Hogeborn
6
 
# Copyright © 2008-2016 Björn Påhlsson
 
5
# Copyright © 2008 Teddy Hogeborn
 
6
# Copyright © 2008 Björn Påhlsson
7
7
8
8
# This program is free software: you can redistribute it and/or modify
9
9
# it under the terms of the GNU General Public License as published by
18
18
# You should have received a copy of the GNU General Public License
19
19
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
20
21
 
# Contact the authors at <mandos@recompile.se>.
 
21
# Contact the authors at <mandos@fukt.bsnet.se>.
22
22
23
23
 
24
 
VERSION="1.7.13"
 
24
VERSION="1.0.2"
25
25
 
26
26
KEYDIR="/etc/keys/mandos"
27
 
KEYTYPE=RSA
28
 
KEYLENGTH=4096
29
 
SUBKEYTYPE=RSA
30
 
SUBKEYLENGTH=4096
 
27
KEYTYPE=DSA
 
28
KEYLENGTH=2048
 
29
SUBKEYTYPE=ELG-E
 
30
SUBKEYLENGTH=2048
31
31
KEYNAME="`hostname --fqdn 2>/dev/null || hostname`"
32
32
KEYEMAIL=""
33
 
KEYCOMMENT=""
 
33
KEYCOMMENT="Mandos client key"
34
34
KEYEXPIRE=0
35
35
FORCE=no
36
 
SSH=yes
37
36
KEYCOMMENT_ORIG="$KEYCOMMENT"
38
37
mode=keygen
39
38
 
42
41
fi
43
42
 
44
43
# Parse options
45
 
TEMP=`getopt --options vhpF:d:t:l:s:L:n:e:c:x:fS \
46
 
    --longoptions version,help,password,passfile:,dir:,type:,length:,subtype:,sublength:,name:,email:,comment:,expire:,force,no-ssh \
 
44
TEMP=`getopt --options vhpF:d:t:l:s:L:n:e:c:x:f \
 
45
    --longoptions version,help,password,passfile:,dir:,type:,length:,subtype:,sublength:,name:,email:,comment:,expire:,force \
47
46
    --name "$0" -- "$@"`
48
47
 
49
48
help(){
50
 
basename="`basename "$0"`"
 
49
basename="`basename $0`"
51
50
cat <<EOF
52
51
Usage: $basename [ -v | --version ]
53
52
       $basename [ -h | --help ]
61
60
  -v, --version         Show program's version number and exit
62
61
  -h, --help            Show this help message and exit
63
62
  -d DIR, --dir DIR     Target directory for key files
64
 
  -t TYPE, --type TYPE  Key type.  Default is RSA.
 
63
  -t TYPE, --type TYPE  Key type.  Default is DSA.
65
64
  -l BITS, --length BITS
66
 
                        Key length in bits.  Default is 4096.
 
65
                        Key length in bits.  Default is 2048.
67
66
  -s TYPE, --subtype TYPE
68
 
                        Subkey type.  Default is RSA.
 
67
                        Subkey type.  Default is ELG-E.
69
68
  -L BITS, --sublength BITS
70
 
                        Subkey length in bits.  Default is 4096.
 
69
                        Subkey length in bits.  Default is 2048.
71
70
  -n NAME, --name NAME  Name of key.  Default is the FQDN.
72
71
  -e ADDRESS, --email ADDRESS
73
72
                        Email address of key.  Default is empty.
74
73
  -c TEXT, --comment TEXT
75
 
                        Comment field for key.  The default is empty.
 
74
                        Comment field for key.  The default value is
 
75
                        "Mandos client key".
76
76
  -x TIME, --expire TIME
77
77
                        Key expire time.  Default is no expiration.
78
78
                        See gpg(1) for syntax.
86
86
                        Encrypt a password from FILE using the key in
87
87
                        the key directory.  All options other than
88
88
                        --dir and --name are ignored.
89
 
  -S, --no-ssh          Don't get SSH key or set "checker" option.
90
89
EOF
91
90
}
92
91
 
105
104
        -c|--comment) KEYCOMMENT="$2"; shift 2;;
106
105
        -x|--expire) KEYEXPIRE="$2"; shift 2;;
107
106
        -f|--force) FORCE=yes; shift;;
108
 
        -S|--no-ssh) SSH=no; shift;;
109
107
        -v|--version) echo "$0 $VERSION"; exit;;
110
108
        -h|--help) help; exit;;
111
109
        --) shift; break;;
113
111
    esac
114
112
done
115
113
if [ "$#" -gt 0 ]; then
116
 
    echo "Unknown arguments: '$*'" >&2
 
114
    echo "Unknown arguments: '$@'" >&2
117
115
    exit 1
118
116
fi
119
117
 
149
147
        echo "Invalid key length" >&2
150
148
        exit 1
151
149
    fi
152
 
    
 
150
 
153
151
    if [ -z "$KEYEXPIRE" ]; then
154
152
        echo "Empty key expiration" >&2
155
153
        exit 1
174
172
    if [ -n "$KEYEMAIL" ]; then
175
173
        KEYEMAILLINE="Name-Email: $KEYEMAIL"
176
174
    fi
177
 
    
 
175
 
178
176
    # Create temporary gpg batch file
179
177
    BATCHFILE="`mktemp -t mandos-keygen-batch.XXXXXXXXXX`"
180
178
fi
191
189
trap "
192
190
set +e; \
193
191
test -n \"$SECFILE\" && shred --remove \"$SECFILE\"; \
194
 
shred --remove \"$RINGDIR\"/sec* 2>/dev/null;
 
192
shred --remove \"$RINGDIR\"/sec*;
195
193
test -n \"$BATCHFILE\" && rm --force \"$BATCHFILE\"; \
196
194
rm --recursive --force \"$RINGDIR\";
197
 
tty --quiet && stty echo; \
 
195
stty echo; \
198
196
" EXIT
199
197
 
200
 
set -e
201
 
 
202
198
umask 077
203
199
 
204
200
if [ "$mode" = keygen ]; then
206
202
    cat >"$BATCHFILE" <<-EOF
207
203
        Key-Type: $KEYTYPE
208
204
        Key-Length: $KEYLENGTH
209
 
        Key-Usage: sign,auth
 
205
        #Key-Usage: encrypt,sign,auth
210
206
        Subkey-Type: $SUBKEYTYPE
211
207
        Subkey-Length: $SUBKEYLENGTH
212
 
        Subkey-Usage: encrypt
 
208
        #Subkey-Usage: encrypt,sign,auth
213
209
        Name-Real: $KEYNAME
214
210
        $KEYCOMMENTLINE
215
211
        $KEYEMAILLINE
218
214
        #Handle: <no-spaces>
219
215
        #%pubring pubring.gpg
220
216
        #%secring secring.gpg
221
 
        %no-protection
222
217
        %commit
223
218
        EOF
224
219
    
225
 
    if tty --quiet; then
226
 
        cat <<-EOF
227
 
        Note: Due to entropy requirements, key generation could take
228
 
        anything from a few minutes to SEVERAL HOURS.  Please be
229
 
        patient and/or supply the system with more entropy if needed.
230
 
        EOF
231
 
        echo -n "Started: "
232
 
        date
233
 
    fi
234
 
    
235
 
    # Make sure trustdb.gpg exists;
236
 
    # this is a workaround for Debian bug #737128
237
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
238
 
        --homedir "$RINGDIR" \
239
 
        --import-ownertrust < /dev/null
240
220
    # Generate a new key in the key rings
241
221
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
242
222
        --homedir "$RINGDIR" --trust-model always \
243
223
        --gen-key "$BATCHFILE"
244
224
    rm --force "$BATCHFILE"
245
225
    
246
 
    if tty --quiet; then
247
 
        echo -n "Finished: "
248
 
        date
249
 
    fi
250
 
    
251
226
    # Backup any old key files
252
227
    if cp --backup=numbered --force "$SECKEYFILE" "$SECKEYFILE" \
253
228
        2>/dev/null; then
278
253
fi
279
254
 
280
255
if [ "$mode" = password ]; then
281
 
    
282
 
    # Make SSH be 0 or 1
283
 
    case "$SSH" in
284
 
        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) SSH=1;;
285
 
        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) SSH=0;;
286
 
    esac
287
 
    
288
 
    if [ $SSH -eq 1 ]; then
289
 
        for ssh_keytype in ecdsa-sha2-nistp256 ed25519 rsa; do
290
 
            set +e
291
 
            ssh_fingerprint="`ssh-keyscan -t $ssh_keytype localhost 2>/dev/null`"
292
 
            set -e
293
 
            if [ $? -ne 0 ]; then
294
 
                ssh_fingerprint=""
295
 
                continue
296
 
            fi
297
 
            if [ -n "$ssh_fingerprint" ]; then
298
 
                ssh_fingerprint="${ssh_fingerprint#localhost }"
299
 
                break
300
 
            fi
301
 
        done
302
 
    fi
303
 
    
304
256
    # Import key into temporary key rings
305
257
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
306
258
        --homedir "$RINGDIR" --trust-model always --armor \
311
263
    
312
264
    # Get fingerprint of key
313
265
    FINGERPRINT="`gpg --quiet --batch --no-tty --no-options \
314
 
        --enable-dsa2 --homedir "$RINGDIR" --trust-model always \
 
266
        --enable-dsa2 --homedir \"$RINGDIR\" --trust-model always \
315
267
        --fingerprint --with-colons \
316
268
        | sed --quiet \
317
269
        --expression='/^fpr:/{s/^fpr:.*:\\([0-9A-Z]*\\):\$/\\1/p;q}'`"
320
272
    
321
273
    FILECOMMENT="Encrypted password for a Mandos client"
322
274
    
323
 
    while [ ! -s "$SECFILE" ]; do
324
 
        if [ -n "$PASSFILE" ]; then
325
 
            cat "$PASSFILE"
 
275
    if [ -n "$PASSFILE" ]; then
 
276
        cat "$PASSFILE"
 
277
    else
 
278
        stty -echo
 
279
        echo -n "Enter passphrase: " >&2
 
280
        first="$(head --lines=1 | tr --delete '\n')"
 
281
        echo -n -e "\nRepeat passphrase: " >&2
 
282
        second="$(head --lines=1 | tr --delete '\n')"
 
283
        echo >&2
 
284
        stty echo
 
285
        if [ "$first" != "$second" ]; then
 
286
            echo -e "Passphrase mismatch" >&2
 
287
            false
326
288
        else
327
 
            tty --quiet && stty -echo
328
 
            echo -n "Enter passphrase: " >/dev/tty
329
 
            read first
330
 
            tty --quiet && echo >&2
331
 
            echo -n "Repeat passphrase: " >/dev/tty
332
 
            read second
333
 
            if tty --quiet; then
334
 
                echo >&2
335
 
                stty echo
336
 
            fi
337
 
            if [ "$first" != "$second" ]; then
338
 
                echo "Passphrase mismatch" >&2
339
 
                touch "$RINGDIR"/mismatch
340
 
            else
341
 
                echo -n "$first"
342
 
            fi
343
 
        fi | gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
344
 
            --homedir "$RINGDIR" --trust-model always --armor \
345
 
            --encrypt --sign --recipient "$FINGERPRINT" --comment \
346
 
            "$FILECOMMENT" > "$SECFILE"
347
 
        if [ -e "$RINGDIR"/mismatch ]; then
348
 
            rm --force "$RINGDIR"/mismatch
349
 
            if tty --quiet; then
350
 
                > "$SECFILE"
351
 
            else
352
 
                exit 1
353
 
            fi
 
289
            echo -n "$first"
354
290
        fi
355
 
    done
 
291
    fi | gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
 
292
        --homedir "$RINGDIR" --trust-model always --armor --encrypt \
 
293
        --sign --recipient "$FINGERPRINT" --comment "$FILECOMMENT" \
 
294
        > "$SECFILE"
 
295
    status="${PIPESTATUS[0]}"
 
296
    if [ "$status" -ne 0 ]; then
 
297
        exit "$status"
 
298
    fi
356
299
    
357
300
    cat <<-EOF
358
301
        [$KEYNAME]
369
312
                /^[^-]/s/^/    /p
370
313
            }
371
314
        }' < "$SECFILE"
372
 
    if [ -n "$ssh_fingerprint" ]; then
373
 
        echo 'checker = ssh-keyscan -t '"$ssh_keytype"' %%(host)s 2>/dev/null | grep --fixed-strings --line-regexp --quiet --regexp=%%(host)s" %(ssh_fingerprint)s"'
374
 
        echo "ssh_fingerprint = ${ssh_fingerprint}"
375
 
    fi
376
315
fi
377
316
 
378
317
trap - EXIT
383
322
    shred --remove "$SECFILE"
384
323
fi
385
324
# Remove the key rings
386
 
shred --remove "$RINGDIR"/sec* 2>/dev/null
 
325
shred --remove "$RINGDIR"/sec*
387
326
rm --recursive --force "$RINGDIR"