xref: /aosp_15_r20/external/autotest/client/cros/enterprise/network_config.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
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