1# Copyright 2019 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import random 6import string 7 8from autotest_lib.client.common_lib import error 9 10 11def generate_random_guid(): 12 """Create a random 16 character GUID.""" 13 return ''.join(random.choice(string.hexdigits) for _ in range(16)) 14 15 16class NetworkConfig(object): 17 """ 18 NetworkConfig is a client-side representation of a network. 19 20 Its primary purpose is to generate open network configurations. 21 22 """ 23 def __init__(self, ssid=None, security='None', eap=None, password=None, 24 identity=None, autoconnect=None, ca_cert=None, 25 client_cert=None): 26 """ 27 @param ssid: Service set identifier for wireless local area network. 28 @param security: Security of network. Options are: 29 'None', 'WEP-PSK', 'WEP-8021X', 'WPA-PSK', and 'WPA-EAP'. 30 @param eap: EAP type, required if security is 'WEP-8021X' or 'WPA-EAP'. 31 @param identity: Username, if the network type requires it. 32 @param password: Password, if the network type requires it. 33 @param ca_cert: CA certificate in PEM format. Required 34 for EAP networks. 35 @param client_cert: Client certificate in base64-encoded PKCS#12 36 format. Required for EAP-TLS networks. 37 @param autoconnect: True iff network policy should autoconnect. 38 39 """ 40 self.ssid = ssid 41 self.security = security 42 self.eap = eap 43 self.password = password 44 self.identity = identity 45 self.autoconnect = autoconnect 46 self.ca_cert = ca_cert 47 self.client_cert = client_cert 48 self.guid = generate_random_guid() 49 50 51 def policy(self): 52 """ 53 Generate a network configuration policy dictionary. 54 55 @returns conf: A dictionary in the format suitable to setting as a 56 network policy. 57 58 """ 59 conf = { 60 'NetworkConfigurations': [ 61 {'GUID': self.guid, 62 'Name': self.ssid, 63 'Type': 'WiFi', 64 'WiFi': { 65 'SSID': self.ssid, 66 'Security': self.security} 67 } 68 ], 69 } 70 71 # Generate list of certificate dictionaries. 72 certs = [] 73 if self.ca_cert is not None: 74 certs.append( 75 {'GUID': 'CA_CERT', 76 'Type': 'Authority', 77 'X509': self.ca_cert} 78 ) 79 80 if self.client_cert is not None: 81 certs.append( 82 {'GUID': 'CLIENT_CERT', 83 'Type': 'Client', 84 'PKCS12': self.client_cert} 85 ) 86 87 if certs: 88 conf['Certificates'] = certs 89 90 wifi_conf = conf['NetworkConfigurations'][0]['WiFi'] 91 92 if self.autoconnect is not None: 93 wifi_conf['AutoConnect'] = self.autoconnect 94 95 if self.security == 'WPA-PSK': 96 if self.password is None: 97 raise error.TestError( 98 'Password is required for WPA-PSK networks.') 99 wifi_conf['Passphrase'] = self.password 100 101 if self.eap is not None: 102 eap_conf = { 103 'Outer': self.eap, 104 'Identity': self.identity, 105 'ServerCARefs': ['CA_CERT'] 106 } 107 108 if self.password is not None: 109 eap_conf['Password'] = self.password 110 111 if self.eap == 'EAP-TLS': 112 eap_conf['ClientCertType'] = 'Ref' 113 eap_conf['ClientCertRef'] = 'CLIENT_CERT' 114 eap_conf['UseSystemCAs'] = False 115 116 wifi_conf['EAP'] = eap_conf 117 118 return conf 119 120 121class ProxyConfig(object): 122 """ 123 ProxyConfig is a client-side representation of a proxy network. 124 125 Its primary purpose is to generate open network configurations. 126 127 """ 128 def __init__(self, type=None, pac_url=None, host=None, port=None, 129 exclude_urls=None): 130 """ 131 @param type: Proxy type. Direct, Manual, PAC. 132 @param pac_url: URL of PAC file. 133 @param host: Host URL of proxy. 134 @param port: Port of proxy. 135 @param exclude_urls: URLs that should not be handled by the proxy. 136 137 """ 138 self.type = type 139 self.pac_url = pac_url 140 self.host = host 141 self.port = port 142 self.exclude_urls = exclude_urls 143 self.guid = generate_random_guid() 144 145 146 def policy(self): 147 """ 148 Generate a network configuration policy dictionary. 149 150 @returns conf: A dictionary in the format suitable to setting as a 151 network policy. 152 153 """ 154 conf = { 155 'NetworkConfigurations': [ 156 {'GUID': self.guid, 157 'Name': 'Managed_Ethernet', 158 'Ethernet': { 159 'Authentication': 'None'}, 160 'Type': 'Ethernet', 161 'ProxySettings': { 162 'Type': self.type} 163 } 164 ] 165 } 166 167 proxy = conf['NetworkConfigurations'][0]['ProxySettings'] 168 169 if self.pac_url is not None: 170 proxy['PAC'] = self.pac_url 171 172 if self.host is not None and self.port is not None: 173 proxy['Manual'] = { 174 'HTTPProxy': { 175 'Host': self.host, 176 'Port': self.port 177 } 178 } 179 180 if self.exclude_urls is not None: 181 proxy['ExcludeDomains'] = self.exclude_urls 182 183 return conf 184 185 186 def mode(self): 187 """Return ProxyMode consistent with the ProxySettings policy.""" 188 return { 189 'Direct': 'direct', 190 'Manual': 'fixed_servers', 191 'PAC': 'pac_script' 192 }[self.type] 193