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