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