/mandos/trunk

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

« back to all changes in this revision

Viewing changes to network-hooks.d/wireless

  • Committer: Teddy Hogeborn
  • Date: 2019-02-09 23:23:26 UTC
  • Revision ID: teddy@recompile.se-20190209232326-z1z2kzpgfixz7iaj
Add support for using raw public keys in TLS (RFC 7250)

Since GnuTLS removed support for OpenPGP keys in TLS (RFC 6091), and
no other library supports it, we have to change the protocol to use
something else.  We choose to use "raw public keys" (RFC 7250).  Since
we still use OpenPGP keys to decrypt the secret password, this means
that each client will have two keys: One OpenPGP key and one TLS
public/private key, and the key ID of the latter key is used to
identify clients instead of the fingerprint of the OpenPGP key.

Note that this code is still compatible with GnuTLS before version
3.6.0 (when OpenPGP key support was removed).  This commit merely adds
support for using raw pulic keys instead with GnuTLS 3.6.6. or later.

* DBUS-API (Signals/ClientNotFound): Change name of first parameter
                                     from "Fingerprint" to "KeyID".
  (Mandos Client Interface/Properties/KeyID): New.
* INSTALL: Document conflict with GnuTLS 3.6.0 (which removed OpenPGP
           key support) up until 3.6.6, when support for raw public
           keys was added.  Also document new dependency of client on
           "gnutls-bin" package (for certtool).
* Makefile (run-client): Depend on TLS key files, and also pass them
                         as arguments to client.
  (keydir/tls-privkey.pem, keydir/tls-pubkey.pem): New.
  (confdir/clients.conf): Add dependency on TLS public key.
  (purge-client): Add removal of TLS key files.
* clients.conf ([foo]/key_id, [bar]/key_id): New.
* debian/control (Source: mandos/Build-Depends): Also allow
                                                 libgnutls30 (>= 3.6.6)
  (Package: mandos/Depends): - '' -
  (Package: mandos/Description): Alter description to match new
                                 design.
  (Package: mandos-client/Description): - '' -
  (Package: mandos-client/Depends): Move "gnutls-bin | openssl" to
                                    here from "Recommends".
* debian/mandos-client.README.Debian: Add --tls-privkey and
                                      --tls-pubkey options to test
                                      command.
* debian/mandos-client.postinst (create_key): Renamed to "create_keys"
                                             (all callers changed),
                                             and also create TLS key.
* debian/mandos-client.postrm (purge): Also remove TLS key files.
* intro.xml (DESCRIPTION): Describe new dual-key design.
* mandos (GnuTLS): Define different functions depending on whether
                   support for raw public keys is detected.
  (Client.key_id): New attribute.
  (ClientDBus.KeyID_dbus_property): New method.
  (ProxyClient.__init__): Take new "key_id" parameter.
  (ClientHandler.handle): Use key IDs when using raw public keys and
                          use fingerprints when using OpenPGP keys.
  (ClientHandler.peer_certificate): Also handle raw public keys.
  (ClientHandler.key_id): New.
  (MandosServer.handle_ipc): Pass key ID over the pipe IPC.  Also
                             check for key ID matches when looking up
                             clients.
  (main): Default GnuTLS priority string depends on whether we are
          using raw public keys or not.  When unpickling clients, set
          key_id if not set in the pickle.
  (main/MandosDBusService.ClientNotFound): Change name of first
                                           parameter from
                                           "Fingerprint" to "KeyID".
* mandos-clients.conf.xml (OPTIONS): Document new "key_id" option.
  (OPTIONS/secret): Mention new key ID matchning.
  (EXPANSION/RUNTIME EXPANSION): Add new "key_id" option.
  (EXAMPLE): - '' -
* mandos-ctl (tablewords, main/keywords): Add new "KeyID" property.
* mandos-keygen: Create TLS key files.  New "--tls-keytype" (-T)
                 option.  Alter help text to be more clear about key
                 types.  When in password mode, also output "key_id"
                 option.
* mandos-keygen.xml (SYNOPSIS): Add new "--tls-keytype" (-T) option.
  (DESCRIPTION): Alter to match new dual-key design.
  (OVERVIEW): - '' -
  (FILES): Add TLS key files.
* mandos-options.xml (priority): Document new default priority string
                                 when using raw public keys.
* mandos.xml (NETWORK PROTOCOL): Describe new protocol using key ID.
  (BUGS): Remove issue about checking expire times of OpenPGP keys,
          since TLS public keys do not have expiration times.
  (SECURITY/CLIENT): Alter description to match new design.
  (SEE ALSO/GnuTLS): - '' -
  (SEE ALSO): Add reference to RFC 7250, and alter description of when
              RFC 6091 is used.
* overview.xml: Alter text to match new design.
* plugin-runner.xml (EXAMPLE): Add --tls-pubkey and --tls-privkey
                               options to mandos-client options.
* plugins.d/mandos-client.c: Use raw public keys when compiling with
                             supporting GnuTLS versions. Add new
                             "--tls-pubkey" and "--tls-privkey"
                             options (which do nothing if GnuTLS
                             library does not support raw public
                             keys).  Alter text throughout to reflect
                             new design.  Only generate new DH
                             parameters (based on size of OpenPGP key)
                             when using OpenPGP in TLS.  Default
                             GnuTLS priority string depends on whether
                             we are using raw public keys or not.
* plugins.d/mandos-client.xml (SYNOPSIS): Add new "--tls-privkey" (-t)
                                          and "--tls-pubkey" (-T)
                                          options.
  (DESCRIPTION): Describe new dual-key design.
  (OPTIONS): Document new "--tls-privkey" (-t) and "--tls-pubkey" (-T)
             options.
  (OPTIONS/--dh-bits): No longer necessarily depends on OpenPGP key
                       size.
  (FILES): Add default locations for TLS public and private key files.
  (EXAMPLE): Use new --tls-pubkey and --tls-privkey options.
  (SECURITY): Alter wording slightly to reflect new dual-key design.
  (SEE ALSO/GnuTLS): Alter description to match new design.
  (SEE ALSO): Add reference to RFC 7250, and alter description of when
              RFC 6091 is used.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
# configuration file(s) should be copied into the
7
7
# /etc/mandos/network-hooks.d directory.
8
8
 
9
# Copyright © 2012-2018 Teddy Hogeborn
 
10
# Copyright © 2012-2018 Björn Påhlsson
 
11
9
12
# Copying and distribution of this file, with or without modification,
10
13
# are permitted in any medium without royalty provided the copyright
11
14
# notice and this notice are preserved.  This file is offered as-is,
21
24
CONFIG="$MANDOSNETHOOKDIR/wireless.conf"
22
25
 
23
26
addrtoif(){
24
 
    grep -liFe "$1" /sys/class/net/*/address | sed -e 's,.*/\([^/]*\)/[^/]*,\1,'
 
27
    grep -liFe "$1" /sys/class/net/*/address \
 
28
        | sed -e 's,.*/\([^/]*\)/[^/]*,\1,'
25
29
}
26
30
 
27
31
# Read config file
31
35
    exit
32
36
fi
33
37
 
34
 
ifkeys="`env | sed -n -e 's/^ADDRESS_\([^=]*\)=.*/\1/p' \"$CONFIG\" | sort -u`"
 
38
ifkeys=`sed -n -e 's/^ADDRESS_\([^=]*\)=.*/\1/p' "$CONFIG" | sort -u`
35
39
 
36
40
# Exit if DEVICE is set and is not any of the wireless interfaces
37
41
if [ -n "$DEVICE" ]; then
39
43
        for KEY in $ifkeys; do
40
44
            ADDRESS=`eval 'echo "$ADDRESS_'"$KEY"\"`
41
45
            INTERFACE=`addrtoif "$ADDRESS"`
42
 
            if [ "$INTERFACE" = "$DEVICE" ]; then
43
 
                break 2
44
 
            fi
 
46
            
 
47
            case "$DEVICE" in
 
48
                *,"$INTERFACE"|*,"$INTERFACE",*|"$INTERFACE",*|"$INTERFACE")
 
49
                    break 2;;
 
50
            esac
45
51
        done
46
52
        exit
47
53
    done
68
74
    WPAS_OPTIONS="-P$PIDFILE $WPAS_OPTIONS"
69
75
fi
70
76
 
71
 
case "${MODE:-$1}" in
72
 
    start)
73
 
        mkdir -m u=rwx,go= -p "$CTRLDIR"
74
 
        "$wpa_supplicant" -B -g "$CTRL" -p "$CTRLDIR" $WPAS_OPTIONS
75
 
        for KEY in $ifkeys; do
76
 
            ADDRESS=`eval 'echo "$ADDRESS_'"$KEY"\"`
77
 
            INTERFACE=`addrtoif "$ADDRESS"`
78
 
            DRIVER=`eval 'echo "$WPA_DRIVER_'"$KEY"\"`
79
 
            IFDELAY=`eval 'echo "$DELAY_'"$KEY"\"`
80
 
            "$wpa_cli" -g "$CTRL" interface_add "$INTERFACE" "" \
81
 
                "${DRIVER:-wext}" "$CTRLDIR" > /dev/null \
82
 
                | sed -e '/^OK$/d'
83
 
            NETWORK=`"$wpa_cli" -p "$CTRLDIR" -i "$INTERFACE" add_network`
84
 
            eval wpa_interface_"$KEY"
85
 
            "$wpa_cli" -p "$CTRLDIR" -i "$INTERFACE" enable_network \
86
 
                "$NETWORK" | sed -e '/^OK$/d'
87
 
            sleep "${IFDELAY:-$DELAY}" &
88
 
            sleep=$!
89
 
            while :; do
90
 
                kill -0 $sleep 2>/dev/null || break
91
 
                STATE=`"$wpa_cli" -p "$CTRLDIR" -i "$INTERFACE" status | sed -n -e 's/^wpa_state=//p'`
92
 
                if [ "$STATE" = COMPLETED ]; then
93
 
                    while :; do
94
 
                        kill -0 $sleep 2>/dev/null || break 2
95
 
                        UP=`cat /sys/class/net/"$INTERFACE"/operstate`
96
 
                        if [ "$UP" = up ]; then
97
 
                            kill $sleep 2>/dev/null
98
 
                            break 2
99
 
                        fi
100
 
                        sleep 1
101
 
                    done
102
 
                fi
103
 
                sleep 1
104
 
            done &
105
 
            wait $sleep || :
106
 
            IPADDRS=`eval 'echo "$IPADDRS_'"$KEY"\"`
107
 
            if [ -n "$IPADDRS" ]; then
108
 
                if [ "$IPADDRS" = dhcp ]; then
109
 
                    ipconfig -c dhcp -d "$INTERFACE" || :
110
 
                    #dhclient "$INTERFACE"
111
 
                else
112
 
                    for ipaddr in $IPADDRS; do
113
 
                        "$ip" addr add "$ipaddr" dev "$INTERFACE"
114
 
                    done
115
 
                fi
116
 
            fi
117
 
            ROUTES=`eval 'echo "$ROUTES_'"$KEY"\"`
118
 
            if [ -n "$ROUTES" ]; then
119
 
                for route in $ROUTES; do
120
 
                    "$ip" route add "$route" dev "$BRIDGE"
121
 
                done
122
 
            fi
123
 
        done
124
 
        ;;
125
 
    stop)
126
 
        "$wpa_cli" -g "$CTRL" terminate 2>&1 | sed -e '/^OK$/d'
127
 
        for KEY in $ifkeys; do
128
 
            ADDRESS=`eval 'echo "$ADDRESS_'"$KEY"\"`
129
 
            INTERFACE=`addrtoif "$ADDRESS"`
130
 
            "$ip" addr show scope global permanent dev "$INTERFACE" \
131
 
                | while read type addr rest; do
 
77
do_start(){
 
78
    mkdir -m u=rwx,go= -p "$CTRLDIR"
 
79
    "$wpa_supplicant" -B -g "$CTRL" -p "$CTRLDIR" $WPAS_OPTIONS
 
80
    for KEY in $ifkeys; do
 
81
        ADDRESS=`eval 'echo "$ADDRESS_'"$KEY"\"`
 
82
        INTERFACE=`addrtoif "$ADDRESS"`
 
83
        DRIVER=`eval 'echo "$WPA_DRIVER_'"$KEY"\"`
 
84
        IFDELAY=`eval 'echo "$DELAY_'"$KEY"\"`
 
85
        "$wpa_cli" -g "$CTRL" interface_add "$INTERFACE" "" \
 
86
            "${DRIVER:-wext}" "$CTRLDIR" > /dev/null \
 
87
            | sed -e '/^OK$/d'
 
88
        NETWORK=`"$wpa_cli" -p "$CTRLDIR" -i "$INTERFACE" add_network`
 
89
        eval wpa_interface_"$KEY"
 
90
        "$wpa_cli" -p "$CTRLDIR" -i "$INTERFACE" enable_network \
 
91
            "$NETWORK" | sed -e '/^OK$/d'
 
92
        sleep "${IFDELAY:-$DELAY}" &
 
93
        sleep=$!
 
94
        while :; do
 
95
            kill -0 $sleep 2>/dev/null || break
 
96
            STATE=`"$wpa_cli" -p "$CTRLDIR" -i "$INTERFACE" status \
 
97
                | sed -n -e 's/^wpa_state=//p'`
 
98
            if [ "$STATE" = COMPLETED ]; then
 
99
                while :; do
 
100
                    kill -0 $sleep 2>/dev/null || break 2
 
101
                    UP=`cat /sys/class/net/"$INTERFACE"/operstate`
 
102
                    if [ "$UP" = up ]; then
 
103
                        kill $sleep 2>/dev/null
 
104
                        break 2
 
105
                    fi
 
106
                    sleep 1
 
107
                done
 
108
            fi
 
109
            sleep 1
 
110
        done &
 
111
        wait $sleep || :
 
112
        IPADDRS=`eval 'echo "$IPADDRS_'"$KEY"\"`
 
113
        if [ -n "$IPADDRS" ]; then
 
114
            if [ "$IPADDRS" = dhcp ]; then
 
115
                ipconfig -c dhcp -d "$INTERFACE" || :
 
116
                #dhclient "$INTERFACE"
 
117
            else
 
118
                for ipaddr in $IPADDRS; do
 
119
                    "$ip" addr add "$ipaddr" dev "$INTERFACE"
 
120
                done
 
121
            fi
 
122
        fi
 
123
        ROUTES=`eval 'echo "$ROUTES_'"$KEY"\"`
 
124
        if [ -n "$ROUTES" ]; then
 
125
            for route in $ROUTES; do
 
126
                "$ip" route add "$route" dev "$INTERFACE"
 
127
            done
 
128
        fi
 
129
    done
 
130
}
 
131
 
 
132
do_stop(){
 
133
    "$wpa_cli" -g "$CTRL" terminate 2>&1 | sed -e '/^OK$/d'
 
134
    for KEY in $ifkeys; do
 
135
        ADDRESS=`eval 'echo "$ADDRESS_'"$KEY"\"`
 
136
        INTERFACE=`addrtoif "$ADDRESS"`
 
137
        "$ip" addr show scope global permanent dev "$INTERFACE" \
 
138
            | while read type addr rest; do
132
139
                case "$type" in
133
140
                    inet|inet6)
134
141
                        "$ip" addr del "$addr" dev "$INTERFACE"
135
142
                        ;;
136
143
                esac
137
144
            done
138
 
            "$ip" link set dev "$INTERFACE" down
139
 
        done
 
145
        "$ip" link set dev "$INTERFACE" down
 
146
    done
 
147
}
 
148
 
 
149
case "${MODE:-$1}" in
 
150
    start|stop)
 
151
        do_"${MODE:-$1}"
140
152
        ;;
141
153
    files)
142
154
        echo "$wpa_supplicant"