From 1521774fff9dc8fe1250b319aaa63f8ae3f6aa4e Mon Sep 17 00:00:00 2001 From: doron zarhi Date: Tue, 15 Feb 2022 13:29:41 +0200 Subject: [PATCH] darwin: network: add power on/off for wifi --- src/ents.plist | 2 + src/rpcclient/rpcclient/client.py | 5 +- src/rpcclient/rpcclient/darwin/network.py | 66 +++++++++++++++++++++-- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/src/ents.plist b/src/ents.plist index f58a5bb3..4208b005 100644 --- a/src/ents.plist +++ b/src/ents.plist @@ -7,5 +7,7 @@ com.apple.wlan.authentication + com.apple.wifi.manager-access + \ No newline at end of file diff --git a/src/rpcclient/rpcclient/client.py b/src/rpcclient/rpcclient/client.py index f4a89184..908dbd9f 100644 --- a/src/rpcclient/rpcclient/client.py +++ b/src/rpcclient/rpcclient/client.py @@ -126,7 +126,10 @@ def call(self, address: int, argv: typing.List[int] = None) -> Symbol: for arg in argv: tmp = arg - if isinstance(arg, str): + if isinstance(arg, bool): + tmp = int(arg) + + elif isinstance(arg, str): tmp = self.symbols.malloc(len(arg) + 1) tmp.poke(arg.encode() + b'\0') free_list.append(tmp) diff --git a/src/rpcclient/rpcclient/darwin/network.py b/src/rpcclient/rpcclient/darwin/network.py index 2ff6d9c2..ae075a80 100644 --- a/src/rpcclient/rpcclient/darwin/network.py +++ b/src/rpcclient/rpcclient/darwin/network.py @@ -2,7 +2,7 @@ import logging from typing import List -from rpcclient.exceptions import BadReturnValueError +from rpcclient.exceptions import BadReturnValueError, RpcClientException from rpcclient.network import Network logger = logging.getLogger(__name__) @@ -47,9 +47,11 @@ def __repr__(self): class WifiInterface: - def __init__(self, client, interface): + def __init__(self, client, interface, wifi_manager_client, device): self._client = client self._interface = interface + self._wifi_manager_client = wifi_manager_client + self._device = device def __enter__(self): return self @@ -73,6 +75,27 @@ def disconnect(self): """ disconnect from current wifi network """ self._client.symbols.Apple80211Disassociate(self._interface) + def _set(self, is_on: bool): + if not is_on: + if self._client.symbols.WiFiManagerClientDisable(self._wifi_manager_client): + raise BadReturnValueError(f'WiFiManagerClientDisable failed ({self._client.last_error})') + + if self._client.symbols.WiFiDeviceClientSetPower(self._device, is_on): + raise BadReturnValueError(f'WiFiDeviceClientSetPower failed ({self._client.last_error})') + + if is_on: + if self._client.symbols.WiFiManagerClientEnable(self._wifi_manager_client): + raise BadReturnValueError(f'WiFiManagerClientEnable failed ({self._client.last_error})') + + def turn_on(self): + self._set(True) + + def turn_off(self): + self._set(False) + + def is_on(self) -> bool: + return self._client.symbols.WiFiDeviceClientGetPower(self._device) == 1 + def close(self): self._client.symbols.Apple80211Close(self._interface) @@ -89,16 +112,49 @@ def _load_wifi_library(self): '/System/Library/Frameworks/CoreWLAN.framework/CoreWLAN', # iOS '/System/Library/PrivateFrameworks/WiFiKit.framework/WiFiKit' - ] + ] for option in options: if self._client.dlopen(option, 2): return logger.warning('WiFi library isn\'t available') - def get_wifi_interface(self, interface_name: str) -> WifiInterface: + @property + def wifi_interfaces(self) -> List[str]: + """ get a list of all available wifi interfaces """ + with self._client.safe_malloc(8) as p_interface: + if self._client.symbols.Apple80211Open(p_interface): + raise BadReturnValueError(f'Apple80211Open failed ({self._client.last_error})') + + with self._client.safe_malloc(8) as p_interface_names: + if self._client.symbols.Apple80211GetIfListCopy(p_interface[0], p_interface_names): + raise BadReturnValueError(f'Apple80211GetIfListCopy failed ({self._client.last_error})') + + return p_interface_names[0].py + + def get_wifi_interface(self, interface_name: str = None) -> WifiInterface: + """ get a specific wifi interface object for remote controlling """ with self._client.safe_malloc(8) as p_interface: if self._client.symbols.Apple80211Open(p_interface): raise BadReturnValueError(f'Apple80211Open failed ({self._client.last_error})') + + if interface_name is None: + wifi_interfaces = self.wifi_interfaces + + if not wifi_interfaces: + raise RpcClientException('no available wifi interfaces were found') + + interface_name = wifi_interfaces[0] + if self._client.symbols.Apple80211BindToInterface(p_interface[0], self._client.cf(interface_name)): raise BadReturnValueError(f'Apple80211BindToInterface failed ({self._client.last_error})') - return WifiInterface(self._client, p_interface[0]) + + wifi_manager_client = self._client.symbols.WiFiManagerClientCreate(0, 0) + if not wifi_manager_client: + raise BadReturnValueError('WiFiManagerClientCreate failed') + + device = self._client.symbols.WiFiManagerClientGetDevice(wifi_manager_client, + self._client.cf(interface_name)) + if not device: + raise BadReturnValueError('WiFiManagerClientGetDevice failed') + + return WifiInterface(self._client, p_interface[0], wifi_manager_client, device)