|
1 | 1 | import plistlib
|
2 | 2 | from enum import Enum
|
3 | 3 | from pathlib import Path
|
4 |
| -from typing import Mapping, Optional |
| 4 | +from typing import Any, Mapping, Optional |
5 | 5 | from uuid import uuid4
|
6 | 6 |
|
7 | 7 | from cryptography import x509
|
|
15 | 15 | from pymobiledevice3.services.lockdown_service import LockdownService
|
16 | 16 |
|
17 | 17 | ERROR_CLOUD_CONFIGURATION_ALREADY_PRESENT = 14002
|
| 18 | +GLOBAL_HTTP_PROXY_UUID = '86a52338-52f7-4c09-b005-52baf3dc4882' |
18 | 19 |
|
19 | 20 |
|
20 | 21 | class Purpose(Enum):
|
@@ -124,66 +125,41 @@ def install_wifi_profile(self, encryption_type: str, ssid: str, password: str,
|
124 | 125 | disable_association_mac_randomization: bool = False, hidden_network: bool = False,
|
125 | 126 | is_hotspot: bool = False, keybag_file: Optional[Path] = None) -> None:
|
126 | 127 | payload_uuid = str(uuid4())
|
127 |
| - profile_data = plistlib.dumps({ |
128 |
| - 'PayloadContent': [ |
129 |
| - { |
130 |
| - 'AutoJoin': auto_join, |
131 |
| - 'CaptiveBypass': captive_bypass, |
132 |
| - 'DisableAssociationMACRandomization': disable_association_mac_randomization, |
133 |
| - 'EncryptionType': encryption_type, |
134 |
| - 'HIDDEN_NETWORK': hidden_network, |
135 |
| - 'IsHotspot': is_hotspot, |
136 |
| - 'Password': password, |
137 |
| - 'PayloadDescription': 'Configures Wi-Fi settings', |
138 |
| - 'PayloadDisplayName': 'Wi-Fi', |
139 |
| - 'PayloadIdentifier': f'com.apple.wifi.managed.{payload_uuid}', |
140 |
| - 'PayloadType': 'com.apple.wifi.managed', |
141 |
| - 'PayloadUUID': payload_uuid, |
142 |
| - 'PayloadVersion': 1, |
143 |
| - 'ProxyType': 'None', |
144 |
| - 'SSID_STR': ssid |
145 |
| - } |
146 |
| - ], |
147 |
| - 'PayloadDisplayName': f'WiFi Profile For {ssid}', |
148 |
| - 'PayloadIdentifier': f'MacBook-Pro.{payload_uuid}', |
149 |
| - 'PayloadRemovalDisallowed': False, |
150 |
| - 'PayloadType': 'Configuration', |
| 128 | + self.install_managed_profile(f'WiFi Profile For {ssid}', { |
| 129 | + 'AutoJoin': auto_join, |
| 130 | + 'CaptiveBypass': captive_bypass, |
| 131 | + 'DisableAssociationMACRandomization': disable_association_mac_randomization, |
| 132 | + 'EncryptionType': encryption_type, |
| 133 | + 'HIDDEN_NETWORK': hidden_network, |
| 134 | + 'IsHotspot': is_hotspot, |
| 135 | + 'Password': password, |
| 136 | + 'PayloadDescription': 'Configures Wi-Fi settings', |
| 137 | + 'PayloadDisplayName': 'Wi-Fi', |
| 138 | + 'PayloadIdentifier': f'com.apple.wifi.managed.{payload_uuid}', |
| 139 | + 'PayloadType': 'com.apple.wifi.managed', |
151 | 140 | 'PayloadUUID': payload_uuid,
|
152 |
| - 'PayloadVersion': 1 |
153 |
| - }) |
154 |
| - if keybag_file is not None: |
155 |
| - self.install_profile_silent(keybag_file, profile_data) |
156 |
| - else: |
157 |
| - self.install_profile(profile_data) |
| 141 | + 'PayloadVersion': 1, |
| 142 | + 'ProxyType': 'None', |
| 143 | + 'SSID_STR': ssid |
| 144 | + }, keybag_file=keybag_file) |
158 | 145 |
|
159 | 146 | def install_http_proxy(self, server: str, server_port: int, keybag_file: Optional[Path] = None) -> None:
|
160 | 147 | payload_uuid = str(uuid4())
|
161 |
| - profile_data = plistlib.dumps({ |
162 |
| - 'PayloadContent': [ |
163 |
| - { |
164 |
| - 'PayloadDescription': 'Global HTTP Proxy', |
165 |
| - 'PayloadDisplayName': 'Global HTTP Proxy', |
166 |
| - 'PayloadIdentifier': f'com.apple.proxy.http.global.{payload_uuid}', |
167 |
| - 'PayloadType': 'com.apple.proxy.http.global', |
168 |
| - 'PayloadUUID': payload_uuid, |
169 |
| - 'PayloadVersion': 1, |
170 |
| - 'ProxyCaptiveLoginAllowed': False, |
171 |
| - 'ProxyServer': server, |
172 |
| - 'ProxyServerPort': server_port, |
173 |
| - 'ProxyType': 'Manual' |
174 |
| - } |
175 |
| - ], |
176 |
| - 'PayloadDisplayName': f'HTTP Proxy {server}:{server_port}', |
177 |
| - 'PayloadIdentifier': f'MacBook-Pro.{payload_uuid}', |
178 |
| - 'PayloadRemovalDisallowed': False, |
179 |
| - 'PayloadType': 'Configuration', |
| 148 | + self.install_managed_profile(f'HTTP Proxy for {server}:{server_port}', { |
| 149 | + 'PayloadDescription': 'Global HTTP Proxy', |
| 150 | + 'PayloadDisplayName': 'Global HTTP Proxy', |
| 151 | + 'PayloadIdentifier': f'com.apple.proxy.http.global.{payload_uuid}', |
| 152 | + 'PayloadType': 'com.apple.proxy.http.global', |
180 | 153 | 'PayloadUUID': payload_uuid,
|
181 |
| - 'PayloadVersion': 1 |
182 |
| - }) |
183 |
| - if keybag_file is not None: |
184 |
| - self.install_profile_silent(keybag_file, profile_data) |
185 |
| - else: |
186 |
| - self.install_profile(profile_data) |
| 154 | + 'PayloadVersion': 1, |
| 155 | + 'ProxyCaptiveLoginAllowed': False, |
| 156 | + 'ProxyServer': server, |
| 157 | + 'ProxyServerPort': server_port, |
| 158 | + 'ProxyType': 'Manual' |
| 159 | + }, payload_uuid=GLOBAL_HTTP_PROXY_UUID, keybag_file=keybag_file) |
| 160 | + |
| 161 | + def remove_http_proxy(self) -> None: |
| 162 | + self.remove_profile(GLOBAL_HTTP_PROXY_UUID) |
187 | 163 |
|
188 | 164 | def supervise(self, organization: str, keybag_file: Path) -> None:
|
189 | 165 | cer = x509.load_pem_x509_certificate(keybag_file.read_bytes())
|
@@ -247,3 +223,22 @@ def supervise(self, organization: str, keybag_file: Path) -> None:
|
247 | 223 | public_key
|
248 | 224 | ]
|
249 | 225 | })
|
| 226 | + |
| 227 | + def install_managed_profile(self, display_name: str, payload_content: Mapping[str, Any], |
| 228 | + payload_uuid: str = str(uuid4()), |
| 229 | + keybag_file: Optional[Path] = None) -> None: |
| 230 | + profile_data = plistlib.dumps({ |
| 231 | + 'PayloadContent': [ |
| 232 | + payload_content |
| 233 | + ], |
| 234 | + 'PayloadDisplayName': display_name, |
| 235 | + 'PayloadIdentifier': payload_uuid, |
| 236 | + 'PayloadRemovalDisallowed': False, |
| 237 | + 'PayloadType': 'Configuration', |
| 238 | + 'PayloadUUID': payload_uuid, |
| 239 | + 'PayloadVersion': 1 |
| 240 | + }) |
| 241 | + if keybag_file is not None: |
| 242 | + self.install_profile_silent(keybag_file, profile_data) |
| 243 | + else: |
| 244 | + self.install_profile(profile_data) |
0 commit comments