Skip to content

Commit

Permalink
Add MacNetworkPlugin (DIS-3024)
Browse files Browse the repository at this point in the history
  • Loading branch information
cecinestpasunepipe committed Sep 3, 2024
1 parent 95f27ae commit 94dd6ef
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 19 deletions.
2 changes: 1 addition & 1 deletion dissect/target/helpers/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def DynamicDescriptor(types): # noqa
[
*COMMON_INTERFACE_ELEMENTS,
("varint", "vlan"),
("string", "proxy"),
("net.ipaddress[]", "proxy"),
("varint", "interface_service_order"),
],
)
20 changes: 2 additions & 18 deletions dissect/target/plugins/os/unix/bsd/osx/_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,8 @@ def hostname(self) -> Optional[str]:
@export(property=True)
def ips(self) -> Optional[list[str]]:
ips = set()

# Static configured IP-addresses
if (preferences := self.target.fs.path(self.SYSTEM)).exists():
network = plistlib.load(preferences.open()).get("NetworkServices")

for interface in network.values():
for addresses in [interface.get("IPv4"), interface.get("IPv6")]:
ips.update(addresses.get("Addresses", []))

# IP-addresses configured by DHCP
if (dhcp := self.target.fs.path("/private/var/db/dhcpclient/leases")).exists():
for lease in dhcp.iterdir():
if lease.is_file():
lease = plistlib.load(lease.open())

if ip := lease.get("IPAddress"):
ips.add(ip)

for ip in self.target.network.ips():
ips.add(str(ip))
return list(ips)

@export(property=True)
Expand Down
133 changes: 133 additions & 0 deletions tests/plugins/os/unix/bsd/osx/test_network.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
from __future__ import annotations

import copy

import pytest

from dissect.target.plugins.os.unix.bsd.osx.network import MacNetworkPlugin
from dissect.target.target import Target

fake_plist = {
"CurrentSet": "/Sets/1",
"NetworkServices": {
"1": {
"DNS": {"ServerAddresses": ["8.8.8.8"]},
"IPv4": {
"Addresses": ["192.122.13.34"],
"Router": "8.8.8.8",
},
"Interface": {
"DeviceName": "en0",
"Type": "Ethernet",
},
"Proxies": {
"GopherProxy": "9.9.9.9",
},
},
},
"Sets": {
"1": {
"Network": {
"Global": {"IPv4": {"ServiceOrder": ["1"]}},
},
},
},
"VirtualNetworkInterfaces": {"VLAN": {"vlan0": {"Interface": "en0", "Tag": 2, "UserDefinedName": "VLANNIE"}}},
}


def vlan0(fake_plist: dict) -> dict:
fake_plist = copy.deepcopy(fake_plist)
fake_plist["NetworkServices"]["1"]["Interface"].update({"DeviceName": "vlan0"})
return fake_plist


def inactive(fake_plist: dict) -> dict:
fake_plist = copy.deepcopy(fake_plist)
fake_plist["NetworkServices"]["1"].update({"__INACTIVE__": True})
return fake_plist


def ipv6(fake_plist: dict) -> dict:
fake_plist = copy.deepcopy(fake_plist)
del fake_plist["NetworkServices"]["1"]["IPv4"]
fake_plist["NetworkServices"]["1"]["IPv6"] = {"Addresses": ["::1"]}
return fake_plist


def reorder(fake_plist: dict) -> dict:
fake_plist = copy.deepcopy(fake_plist)
fake_plist["Sets"]["1"]["Network"]["Global"]["IPv4"]["ServiceOrder"] = ["2", "1"]
return fake_plist


@pytest.mark.parametrize(
"lease,netinfo,expected,count",
[
({"IPAddress": None}, {"CurrentSet": {}}, [], 0),
(
{},
fake_plist,
[
(0, "hostname", ["dummys Mac"]),
(0, "domain", ["None"]),
(0, "name", ["en0"]),
(0, "type", ["Ethernet"]),
(0, "ip", ["192.122.13.34"]),
(0, "proxy", ["9.9.9.9"]),
(0, "gateway", ["8.8.8.8"]),
(0, "dns", ["8.8.8.8"]),
(0, "vlan", ["None"]),
(0, "enabled", ["True"]),
(0, "interface_service_order", ["0"]),
(0, "mac", ["None"]),
(0, "vlan", ["None"]),
],
1,
),
(
{"IPAddress": "10.0.0.2"},
vlan0(fake_plist),
[
(0, "vlan", ["2"]),
],
1,
),
(
{"IPAddress": "10.0.0.2"},
inactive(fake_plist),
[
(0, "enabled", ["False"]),
],
1,
),
(
{},
ipv6(fake_plist),
[
(0, "ip", ["::1"]),
],
1,
),
(
{},
reorder(fake_plist),
[
(0, "interface_service_order", ["1"]),
],
1,
),
],
)
def test_macos_network(target_osx: Target, lease: dict, netinfo: dict, expected: dict, count: int) -> None:
network = MacNetworkPlugin(target_osx)
network.plistlease = lease
network.plistnetwork = netinfo
interfaces = list(network.interfaces())
assert len(interfaces) == count
for index, key, value in expected:
attr = getattr(interfaces[index], key)
if not isinstance(attr, list):
attr = [attr]
attr = list(sorted(map(str, attr)))
assert attr == value

0 comments on commit 94dd6ef

Please sign in to comment.