1#   Copyright 2017 - The Android Open Source Project
2#
3#   Licensed under the Apache License, Version 2.0 (the "License");
4#   you may not use this file except in compliance with the License.
5#   You may obtain a copy of the License at
6#
7#       http://www.apache.org/licenses/LICENSE-2.0
8#
9#   Unless required by applicable law or agreed to in writing, software
10#   distributed under the License is distributed on an "AS IS" BASIS,
11#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12#   See the License for the specific language governing permissions and
13#   limitations under the License.
14
15import collections
16
17from acts.controllers.ap_lib import hostapd_constants
18
19
20class Security(object):
21    """The Security class for hostapd representing some of the security
22       settings that are allowed in hostapd.  If needed more can be added.
23    """
24
25    def __init__(self,
26                 security_mode=None,
27                 password=None,
28                 wpa_cipher=hostapd_constants.WPA_DEFAULT_CIPHER,
29                 wpa2_cipher=hostapd_constants.WPA2_DEFAULT_CIPER,
30                 wpa_group_rekey=hostapd_constants.WPA_GROUP_KEY_ROTATION_TIME,
31                 wpa_strict_rekey=hostapd_constants.WPA_STRICT_REKEY_DEFAULT):
32        """Gather all of the security settings for WPA-PSK.  This could be
33           expanded later.
34
35        Args:
36            security_mode: Type of security modes.
37                           Options: wpa, wpa2, wpa/wpa2
38            password: The PSK or passphrase for the security mode.
39            wpa_cipher: The cipher to be used for wpa.
40                        Options: TKIP, CCMP, TKIP CCMP
41                        Default: TKIP
42            wpa2_cipher: The cipher to be used for wpa2.
43                         Options: TKIP, CCMP, TKIP CCMP
44                         Default: CCMP
45            wpa_group_rekey: How often to refresh the GTK regardless of network
46                             changes.
47                             Options: An integrer in seconds, None
48                             Default: 600 seconds
49            wpa_strict_rekey: Whether to do a group key update when client
50                              leaves the network or not.
51                              Options: True, False
52                              Default: True
53        """
54        self.wpa_cipher = wpa_cipher
55        self.wpa2_cipher = wpa2_cipher
56        self.wpa_group_rekey = wpa_group_rekey
57        self.wpa_strict_rekey = wpa_strict_rekey
58        if security_mode == hostapd_constants.WPA_STRING:
59            security_mode = hostapd_constants.WPA1
60        elif security_mode == hostapd_constants.WPA2_STRING:
61            security_mode = hostapd_constants.WPA2
62        elif security_mode == hostapd_constants.WPA_MIXED_STRING:
63            security_mode = hostapd_constants.MIXED
64        else:
65            security_mode = None
66        self.security_mode = security_mode
67        if password:
68            if len(password) < hostapd_constants.MIN_WPA_PSK_LENGTH or len(
69                    password) > hostapd_constants.MAX_WPA_PSK_LENGTH:
70                raise ValueError(
71                    'Password must be a minumum of %s characters and a maximum of %s'
72                    % (hostapd_constants.MIN_WPA_PSK_LENGTH,
73                       hostapd_constants.MAX_WPA_PSK_LENGTH))
74            else:
75                self.password = password
76
77    def generate_dict(self):
78        """Returns: an ordered dictionary of settings"""
79        settings = collections.OrderedDict()
80        if self.security_mode:
81            settings['wpa'] = self.security_mode
82            if len(self.password) == hostapd_constants.MAX_WPA_PSK_LENGTH:
83                settings['wpa_psk'] = self.password
84            else:
85                settings['wpa_passphrase'] = self.password
86
87            if self.security_mode == hostapd_constants.MIXED:
88                settings['wpa_pairwise'] = self.wpa_cipher
89                settings['rsn_pairwise'] = self.wpa2_cipher
90            elif self.security_mode == hostapd_constants.WPA1:
91                settings['wpa_pairwise'] = self.wpa_cipher
92            elif self.security_mode == hostapd_constants.WPA2:
93                settings['rsn_pairwise'] = self.wpa2_cipher
94
95            if self.wpa_group_rekey:
96                settings['wpa_group_rekey'] = self.wpa_group_rekey
97            if self.wpa_strict_rekey:
98                settings[
99                    'wpa_strict_rekey'] = hostapd_constants.WPA_STRICT_REKEY
100        return settings
101