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 16import string 17 18from acts.controllers.ap_lib import hostapd_constants 19 20 21class Security(object): 22 """The Security class for hostapd representing some of the security 23 settings that are allowed in hostapd. If needed more can be added. 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 wep_default_key=hostapd_constants.WEP_DEFAULT_KEY, 33 radius_server_ip=None, 34 radius_server_port=None, 35 radius_server_secret=None): 36 """Gather all of the security settings for WPA-PSK. This could be 37 expanded later. 38 39 Args: 40 security_mode: Type of security modes. 41 Options: wep, wpa, wpa2, wpa/wpa2, wpa3 42 password: The PSK or passphrase for the security mode. 43 wpa_cipher: The cipher to be used for wpa. 44 Options: TKIP, CCMP, TKIP CCMP 45 Default: TKIP 46 wpa2_cipher: The cipher to be used for wpa2. 47 Options: TKIP, CCMP, TKIP CCMP 48 Default: CCMP 49 wpa_group_rekey: How often to refresh the GTK regardless of network 50 changes. 51 Options: An integrer in seconds, None 52 Default: 600 seconds 53 wpa_strict_rekey: Whether to do a group key update when client 54 leaves the network or not. 55 Options: True, False 56 Default: True 57 wep_default_key: The wep key number to use when transmitting. 58 radius_server_ip: Radius server IP for Enterprise auth. 59 radius_server_port: Radius server port for Enterprise auth. 60 radius_server_secret: Radius server secret for Enterprise auth. 61 """ 62 self.wpa_cipher = wpa_cipher 63 self.wpa2_cipher = wpa2_cipher 64 self.wpa3 = security_mode == hostapd_constants.WPA3_STRING 65 self.wpa_group_rekey = wpa_group_rekey 66 self.wpa_strict_rekey = wpa_strict_rekey 67 self.wep_default_key = wep_default_key 68 self.radius_server_ip = radius_server_ip 69 self.radius_server_port = radius_server_port 70 self.radius_server_secret = radius_server_secret 71 if security_mode == hostapd_constants.WPA_STRING: 72 security_mode = hostapd_constants.WPA1 73 # Both wpa2 and wpa3 use hostapd security mode 2, and are distinguished 74 # by their key management field (WPA-PSK and SAE, respectively) 75 elif (security_mode == hostapd_constants.WPA2_STRING 76 or security_mode == hostapd_constants.WPA3_STRING): 77 security_mode = hostapd_constants.WPA2 78 elif security_mode == hostapd_constants.WPA_MIXED_STRING: 79 security_mode = hostapd_constants.MIXED 80 elif security_mode == hostapd_constants.WEP_STRING: 81 security_mode = hostapd_constants.WEP 82 elif security_mode == hostapd_constants.ENT_STRING: 83 security_mode = hostapd_constants.ENT 84 else: 85 security_mode = None 86 self.security_mode = security_mode 87 if password: 88 if security_mode == hostapd_constants.WEP: 89 if len(password) in hostapd_constants.WEP_STR_LENGTH: 90 self.password = '"%s"' % password 91 elif len(password) in hostapd_constants.WEP_HEX_LENGTH and all( 92 c in string.hexdigits for c in password): 93 self.password = password 94 else: 95 raise ValueError( 96 'WEP key must be a hex string of %s characters' % 97 hostapd_constants.WEP_HEX_LENGTH) 98 else: 99 if len(password) < hostapd_constants.MIN_WPA_PSK_LENGTH or len( 100 password) > hostapd_constants.MAX_WPA_PSK_LENGTH: 101 raise ValueError( 102 'Password must be a minumum of %s characters and a maximum of %s' 103 % (hostapd_constants.MIN_WPA_PSK_LENGTH, 104 hostapd_constants.MAX_WPA_PSK_LENGTH)) 105 else: 106 self.password = password 107 108 def generate_dict(self): 109 """Returns: an ordered dictionary of settings""" 110 settings = collections.OrderedDict() 111 if self.security_mode is not None: 112 if self.security_mode == hostapd_constants.WEP: 113 settings['wep_default_key'] = self.wep_default_key 114 settings['wep_key' + str(self.wep_default_key)] = self.password 115 elif self.security_mode == hostapd_constants.ENT: 116 settings['auth_server_addr'] = self.radius_server_ip 117 settings['auth_server_port'] = self.radius_server_port 118 settings[ 119 'auth_server_shared_secret'] = self.radius_server_secret 120 settings['wpa_key_mgmt'] = hostapd_constants.ENT_KEY_MGMT 121 settings['ieee8021x'] = hostapd_constants.IEEE8021X 122 settings['wpa'] = hostapd_constants.WPA2 123 else: 124 settings['wpa'] = self.security_mode 125 if len(self.password) == hostapd_constants.MAX_WPA_PSK_LENGTH: 126 settings['wpa_psk'] = self.password 127 else: 128 settings['wpa_passphrase'] = self.password 129 if self.security_mode == hostapd_constants.MIXED: 130 settings['wpa_pairwise'] = self.wpa_cipher 131 settings['rsn_pairwise'] = self.wpa2_cipher 132 elif self.security_mode == hostapd_constants.WPA1: 133 settings['wpa_pairwise'] = self.wpa_cipher 134 elif self.security_mode == hostapd_constants.WPA2: 135 settings['rsn_pairwise'] = self.wpa2_cipher 136 if self.wpa3: 137 settings['wpa_key_mgmt'] = 'SAE' 138 if self.wpa_group_rekey: 139 settings['wpa_group_rekey'] = self.wpa_group_rekey 140 if self.wpa_strict_rekey: 141 settings[ 142 'wpa_strict_rekey'] = hostapd_constants.WPA_STRICT_REKEY 143 return settings 144