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, wpa2/wpa3, 42 wpa/wpa2/wpa3 43 password: The PSK or passphrase for the security mode. 44 wpa_cipher: The cipher to be used for wpa. 45 Options: TKIP, CCMP, TKIP CCMP 46 Default: TKIP 47 wpa2_cipher: The cipher to be used for wpa2. 48 Options: TKIP, CCMP, TKIP CCMP 49 Default: CCMP 50 wpa_group_rekey: How often to refresh the GTK regardless of network 51 changes. 52 Options: An integrer in seconds, None 53 Default: 600 seconds 54 wpa_strict_rekey: Whether to do a group key update when client 55 leaves the network or not. 56 Options: True, False 57 Default: True 58 wep_default_key: The wep key number to use when transmitting. 59 radius_server_ip: Radius server IP for Enterprise auth. 60 radius_server_port: Radius server port for Enterprise auth. 61 radius_server_secret: Radius server secret for Enterprise auth. 62 """ 63 self.security_mode_string = security_mode 64 self.wpa_cipher = wpa_cipher 65 self.wpa2_cipher = wpa2_cipher 66 self.wpa_group_rekey = wpa_group_rekey 67 self.wpa_strict_rekey = wpa_strict_rekey 68 self.wep_default_key = wep_default_key 69 self.radius_server_ip = radius_server_ip 70 self.radius_server_port = radius_server_port 71 self.radius_server_secret = radius_server_secret 72 self.security_mode = hostapd_constants.SECURITY_STRING_TO_SECURITY_MODE_INT.get( 73 security_mode, None) 74 if password: 75 if self.security_mode == hostapd_constants.WEP: 76 if len(password) in hostapd_constants.WEP_STR_LENGTH: 77 self.password = '"%s"' % password 78 elif len(password) in hostapd_constants.WEP_HEX_LENGTH and all( 79 c in string.hexdigits for c in password): 80 self.password = password 81 else: 82 raise ValueError( 83 'WEP key must be a hex string of %s characters' % 84 hostapd_constants.WEP_HEX_LENGTH) 85 else: 86 if len(password) < hostapd_constants.MIN_WPA_PSK_LENGTH or len( 87 password) > hostapd_constants.MAX_WPA_PSK_LENGTH: 88 raise ValueError( 89 'Password must be a minumum of %s characters and a maximum of %s' 90 % (hostapd_constants.MIN_WPA_PSK_LENGTH, 91 hostapd_constants.MAX_WPA_PSK_LENGTH)) 92 else: 93 self.password = password 94 95 def generate_dict(self): 96 """Returns: an ordered dictionary of settings""" 97 settings = collections.OrderedDict() 98 if self.security_mode is not None: 99 if self.security_mode == hostapd_constants.WEP: 100 settings['wep_default_key'] = self.wep_default_key 101 settings['wep_key' + str(self.wep_default_key)] = self.password 102 elif self.security_mode == hostapd_constants.ENT: 103 settings['auth_server_addr'] = self.radius_server_ip 104 settings['auth_server_port'] = self.radius_server_port 105 settings[ 106 'auth_server_shared_secret'] = self.radius_server_secret 107 settings['wpa_key_mgmt'] = hostapd_constants.ENT_KEY_MGMT 108 settings['ieee8021x'] = hostapd_constants.IEEE8021X 109 settings['wpa'] = hostapd_constants.WPA2 110 else: 111 settings['wpa'] = self.security_mode 112 if len(self.password) == hostapd_constants.MAX_WPA_PSK_LENGTH: 113 settings['wpa_psk'] = self.password 114 else: 115 settings['wpa_passphrase'] = self.password 116 # For wpa, wpa/wpa2, and wpa/wpa2/wpa3, add wpa_pairwise 117 if self.security_mode == hostapd_constants.WPA1 or self.security_mode == hostapd_constants.MIXED: 118 settings['wpa_pairwise'] = self.wpa_cipher 119 # For wpa/wpa2, wpa2, wpa3, and wpa2/wpa3, and wpa/wpa2, wpa3, add rsn_pairwise 120 if self.security_mode == hostapd_constants.WPA2 or self.security_mode == hostapd_constants.MIXED: 121 settings['rsn_pairwise'] = self.wpa2_cipher 122 # Add wpa_key_mgmt based on security mode string 123 if self.security_mode_string in hostapd_constants.SECURITY_STRING_TO_WPA_KEY_MGMT: 124 settings[ 125 'wpa_key_mgmt'] = hostapd_constants.SECURITY_STRING_TO_WPA_KEY_MGMT[ 126 self.security_mode_string] 127 if self.wpa_group_rekey: 128 settings['wpa_group_rekey'] = self.wpa_group_rekey 129 if self.wpa_strict_rekey: 130 settings[ 131 'wpa_strict_rekey'] = hostapd_constants.WPA_STRICT_REKEY 132 return settings 133