1#!/usr/bin/python3 2 3# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7import os 8import sys 9 10# Prevent Autotest smarts from trying to switch us back to python2. 11os.environ['PY_VERSION'] = '3' 12 13import common 14from autotest_lib.client.cros.networking import wifi_proxy 15 16SERVICE_PROP_PARSERS = { 17 'EAP.AnonymousIdentity': str, 18 'EAP.CACertID': str, 19 'EAP.CACertNSS': str, 20 'EAP.CACertPEM': str, 21 'EAP.CertID': str, 22 'EAP.ClientCert': str, 23 'EAP.EAP': str, 24 'EAP.Identity': str, 25 'EAP.InnerEAP': str, 26 'EAP.KeyID': str, 27 'EAP.KeyMgmt': str, 28 'EAP.Password': str, 29 'EAP.PIN': str, 30 'EAP.SubjectMatch': str, 31 'EAP.UseSystemCAs': bool, 32 wifi_proxy.WifiProxy.SERVICE_PROPERTY_SECURITY_CLASS: str, 33 } 34 35 36def usage(): 37 """ Prints a usage message and returns False. """ 38 cmd = sys.argv[0] 39 print('Usage:') 40 print(cmd, 'connect <ssid> [passphrase] [security]') 41 print(' |security| defaults to "psk" when |passphrase|', end=' ') 42 print('is given without |security|') 43 print() 44 print(cmd, 'disconnect <ssid> [timeout seconds]') 45 print() 46 print(cmd, 'connect_with_props <ssid> <timeout seconds>') 47 print(' <SecurityClass=[none|psk|802_1x]> [Property=Value ...]') 48 print(' for Property in:') 49 print('\n'.join(['\t\t' + x for x in sorted(SERVICE_PROP_PARSERS.keys())])) 50 print() 51 print(cmd, 'configure <ssid> [passphrase] [security]') 52 print(' |security| defaults to "psk" when |passphrase|', end=' ') 53 print('is given without |security|') 54 return False 55 56 57def configure(ssid, security, passphrase): 58 wifi = wifi_proxy.WifiProxy.get_proxy() 59 security_parameters = {} 60 if passphrase is not None: 61 security_parameters[wifi.SERVICE_PROPERTY_PASSPHRASE] = passphrase 62 successful = wifi.configure_wifi_service(ssid, security, 63 security_parameters) 64 if successful: 65 print('Operation succeeded.') 66 else: 67 print('Operation failed.') 68 return successful 69 70 71def connect(ssid, security, credentials, save_credentials, timeout=15): 72 """Attempt to connect to a WiFi network. 73 74 Blocks until we connect successfully to a WiFi network described 75 by the given parameters or time out while attempting to do so. 76 77 @param ssid string Name of the network to connect to. 78 @param security string security type of the network to connect to. 79 @param credentials dict of service properties that includes credentials 80 like the passphrase for psk security. 81 @param save_credentials bool True if credentials should be saved. 82 @return True upon success, False otherwise. 83 84 """ 85 wifi = wifi_proxy.WifiProxy.get_proxy() 86 result = wifi.connect_to_wifi_network(ssid, 87 security, 88 credentials, 89 save_credentials, 90 discovery_timeout_seconds=timeout, 91 association_timeout_seconds=timeout, 92 configuration_timeout_seconds=timeout) 93 (successful, discovery, association, configuration, reason) = result 94 if successful: 95 print('Operation succeeded.') 96 else: 97 print('Operation failed. (%s)' % reason) 98 print('Discovery time: %f.' % discovery) 99 print('Association time: %f.' % association) 100 print('Configuration time: %f.' % configuration) 101 return successful 102 103 104def disconnect(ssid, timeout=None): 105 """Disconnect from the specified network. 106 107 Disconnect from a network with name |ssid|. Note that this 108 method will not fail if we're already disconnected. 109 110 @param ssid string Name of the network to disconnect from. 111 @param timeout float number of seconds to wait for transition 112 to idle state. 113 @return True upon seeing network is in idle state. 114 115 """ 116 wifi = wifi_proxy.WifiProxy.get_proxy() 117 result = wifi.disconnect_from_wifi_network(ssid, timeout) 118 (successful, duration, reason) = result 119 if successful: 120 print('Operation succeeded.') 121 else: 122 print('Operation failed: %s.' % reason) 123 print('Disconnect time: %f.' % duration) 124 return successful 125 126 127def parse_security_class_from_credentials(credentials): 128 """Parses SERVICE_PROPERTY_SECURITY_CLASS from credentials. 129 130 @param credentials dict of service properties that includes credentials 131 like the passphrase for psk security. 132 @return SERVICE_PROPERTY_SECURITY_CLASS value from credentials, 133 or exit if no such key/value in credentials. 134 135 """ 136 security = credentials.pop( 137 wifi_proxy.WifiProxy.SERVICE_PROPERTY_SECURITY_CLASS, None) 138 if security is None: 139 print("Error: security type not provided") 140 usage() 141 sys.exit(1) 142 143 if security not in ['none', 'wep', 'psk', '802_1x']: 144 print("Error: invalid security type %s" % security) 145 usage() 146 sys.exit(1) 147 148 return security 149 150 151def parse_service_property(property_string): 152 """Parses one commandline key=value string into a tuple. 153 154 @param property_string string to be parsed into (key,value). 155 @return parsed tuple of (key,value) or exit on parsing error. 156 157 """ 158 property_name, raw_value = property_string.split('=', 1) 159 160 if not property_name in SERVICE_PROP_PARSERS: 161 print('%s is not a recognized service property' % property_name) 162 usage() 163 sys.exit(1) 164 165 try: 166 return property_name, SERVICE_PROP_PARSERS[property_name](raw_value) 167 except: 168 print('Failed parsing value from %s' % property_string) 169 usage() 170 sys.exit(1) 171 172 173def main(args): 174 """Main method for this script. 175 176 @param args list of arguments to the script, not including script name. 177 @return True on success, False otherwise. 178 179 """ 180 if len(args) < 2: 181 return usage() 182 command = args[0] 183 ssid = args[1] 184 save_credentials = True 185 186 if command == 'configure': 187 security = 'none' 188 passphrase = None 189 if len(args) > 2: 190 security = 'psk' 191 passphrase = args[2] 192 if len(args) > 3: 193 security = args[3] 194 return configure(ssid, security, passphrase) 195 196 if command == 'connect': 197 security = 'none' 198 credentials = {} 199 save_credentials = True 200 if len(args) > 2: 201 credentials[wifi_proxy.WifiProxy.SERVICE_PROPERTY_PASSPHRASE] = \ 202 args[2] 203 security = 'psk' 204 if len(args) > 3: 205 security = args[3] 206 return connect(ssid, security, credentials, save_credentials) 207 208 if command == 'connect_with_props': 209 timeout = float(args[2]) 210 credentials = {} 211 if len(args) > 3: 212 for i in range(3, len(args)): 213 credentials.update((parse_service_property(args[i]),)) 214 security = parse_security_class_from_credentials(credentials) 215 return connect(ssid, security, credentials, save_credentials, timeout) 216 217 if command == 'disconnect': 218 timeout=None 219 if len(args) > 2: 220 timeout = float(args[2]) 221 return disconnect(ssid, timeout) 222 223 return usage() 224 225 226if __name__ == '__main__': 227 if not main(sys.argv[1:]): 228 sys.exit(1) 229