/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.6"
 
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
221
217
        %commit
222
218
        EOF
223
219
    
224
 
    if tty --quiet; then
225
 
        cat <<-EOF
226
 
        Note: Due to entropy requirements, key generation could take
227
 
        anything from a few minutes to SEVERAL HOURS.  Please be
228
 
        patient and/or supply the system with more entropy if needed.
229
 
        EOF
230
 
        echo -n "Started: "
231
 
        date
232
 
    fi
233
 
    
234
 
    # Make sure trustdb.gpg exists;
235
 
    # this is a workaround for Debian bug #737128
236
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
237
 
        --homedir "$RINGDIR" \
238
 
        --import-ownertrust < /dev/null
239
220
    # Generate a new key in the key rings
240
221
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
241
222
        --homedir "$RINGDIR" --trust-model always \
242
223
        --gen-key "$BATCHFILE"
243
224
    rm --force "$BATCHFILE"
244
225
    
245
 
    if tty --quiet; then
246
 
        echo -n "Finished: "
247
 
        date
248
 
    fi
249
 
    
250
226
    # Backup any old key files
251
227
    if cp --backup=numbered --force "$SECKEYFILE" "$SECKEYFILE" \
252
228
        2>/dev/null; then
277
253
fi
278
254
 
279
255
if [ "$mode" = password ]; then
280
 
    
281
 
    # Make SSH be 0 or 1
282
 
    case "$SSH" in
283
 
        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) SSH=1;;
284
 
        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) SSH=0;;
285
 
    esac
286
 
    
287
 
    if [ $SSH -eq 1 ]; then
288
 
        for ssh_keytype in ed25519 rsa; do
289
 
            set +e
290
 
            ssh_fingerprint="`ssh-keyscan -t $ssh_keytype localhost 2>/dev/null`"
291
 
            set -e
292
 
            if [ $? -ne 0 ]; then
293
 
                ssh_fingerprint=""
294
 
                continue
295
 
            fi
296
 
            if [ -n "$ssh_fingerprint" ]; then
297
 
                ssh_fingerprint="${ssh_fingerprint#localhost }"
298
 
                break
299
 
            fi
300
 
        done
301
 
    fi
302
 
    
303
256
    # Import key into temporary key rings
304
257
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
305
258
        --homedir "$RINGDIR" --trust-model always --armor \
310
263
    
311
264
    # Get fingerprint of key
312
265
    FINGERPRINT="`gpg --quiet --batch --no-tty --no-options \
313
 
        --enable-dsa2 --homedir "$RINGDIR" --trust-model always \
 
266
        --enable-dsa2 --homedir \"$RINGDIR\" --trust-model always \
314
267
        --fingerprint --with-colons \
315
268
        | sed --quiet \
316
269
        --expression='/^fpr:/{s/^fpr:.*:\\([0-9A-Z]*\\):\$/\\1/p;q}'`"
319
272
    
320
273
    FILECOMMENT="Encrypted password for a Mandos client"
321
274
    
322
 
    while [ ! -s "$SECFILE" ]; do
323
 
        if [ -n "$PASSFILE" ]; then
324
 
            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
325
288
        else
326
 
            tty --quiet && stty -echo
327
 
            echo -n "Enter passphrase: " >&2
328
 
            read first
329
 
            tty --quiet && echo >&2
330
 
            echo -n "Repeat passphrase: " >&2
331
 
            read second
332
 
            if tty --quiet; then
333
 
                echo >&2
334
 
                stty echo
335
 
            fi
336
 
            if [ "$first" != "$second" ]; then
337
 
                echo "Passphrase mismatch" >&2
338
 
                touch "$RINGDIR"/mismatch
339
 
            else
340
 
                echo -n "$first"
341
 
            fi
342
 
        fi | gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
343
 
            --homedir "$RINGDIR" --trust-model always --armor \
344
 
            --encrypt --sign --recipient "$FINGERPRINT" --comment \
345
 
            "$FILECOMMENT" > "$SECFILE"
346
 
        if [ -e "$RINGDIR"/mismatch ]; then
347
 
            rm --force "$RINGDIR"/mismatch
348
 
            if tty --quiet; then
349
 
                > "$SECFILE"
350
 
            else
351
 
                exit 1
352
 
            fi
 
289
            echo -n "$first"
353
290
        fi
354
 
    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
355
299
    
356
300
    cat <<-EOF
357
301
        [$KEYNAME]
368
312
                /^[^-]/s/^/    /p
369
313
            }
370
314
        }' < "$SECFILE"
371
 
    if [ -n "$ssh_fingerprint" ]; then
372
 
        echo 'checker = ssh-keyscan -t '"$ssh_keytype"' %%(host)s 2>/dev/null | grep --fixed-strings --line-regexp --quiet --regexp=%%(host)s" %(ssh_fingerprint)s"'
373
 
        echo "ssh_fingerprint = ${ssh_fingerprint}"
374
 
    fi
375
315
fi
376
316
 
377
317
trap - EXIT
382
322
    shred --remove "$SECFILE"
383
323
fi
384
324
# Remove the key rings
385
 
shred --remove "$RINGDIR"/sec* 2>/dev/null
 
325
shred --remove "$RINGDIR"/sec*
386
326
rm --recursive --force "$RINGDIR"