From 04409f438123a0a28e29805a2a690ffad1e28cfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 27 Oct 2023 11:50:55 +0800 Subject: [PATCH] Wifi (macOS): better (or worse) support of security detection --- CHANGELOG.md | 2 + CMakeLists.txt | 1 + README.md | 3 +- src/detection/wifi/wifi_apple.m | 91 +++++++++++++++++++++------------ src/modules/wifi/wifi.c | 5 +- 5 files changed, 66 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac2742f03..cd686e92b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,10 +16,12 @@ Features: * Support st terminal font detection (TerminalFont, Linux) * Add option `--migrate-config ` * Support Nvidia GPU temp detection via nvml (GPU) +* Try supporting Wifi authentication type detection in macOS Sonoma. Please file a feature request if you get `to be supported (num)` with result of `/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I | grep auth` (Wifi, macOS) Bugfixes: * Better GPU memory and type detection (GPU, Windows) * Don't print display type twice (Display) +* Detect BSSID instead of Wifi MAC address to align with other platforms (Wifi, macOS) Logos: * Add Black Mesa diff --git a/CMakeLists.txt b/CMakeLists.txt index a32376948..5d9e36098 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -877,6 +877,7 @@ elseif(APPLE) PRIVATE "-weak_framework CoreDisplay" PRIVATE "-weak_framework DisplayServices -F /System/Library/PrivateFrameworks" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" + PRIVATE "-weak_framework IO80211 -F /System/Library/PrivateFrameworks" ) elseif(WIN32) target_compile_definitions(libfastfetch PRIVATE -D_WIN32_WINNT=0x0601) diff --git a/README.md b/README.md index da2e4443c..308ad4900 100644 --- a/README.md +++ b/README.md @@ -76,9 +76,10 @@ The following libraries are used if present at runtime: * [`DirectX-Headers`](https://github.com/microsoft/DirectX-Headers): Used for GPU detection in WSL ### macOS - + * [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system. * [`DisplayServices`](https://developer.apple.com/forums/thread/666383#663154022): Need for screen brightness detection. It's a private framework provided by newer macOS system. +* [`IO80211`](https://code.google.com/archive/p/iphone-wireless/wikis): Need for Wifi detection on Sonoma (and maybe later). It's a private framework provided by newer macOS system. * [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. [`molten-vk`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/molten-vk.rb) * [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick.rb) * [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb) diff --git a/src/detection/wifi/wifi_apple.m b/src/detection/wifi/wifi_apple.m index 188e0b29f..0281f4440 100644 --- a/src/detection/wifi/wifi_apple.m +++ b/src/detection/wifi/wifi_apple.m @@ -3,6 +3,27 @@ #import +struct Apple80211; // https://code.google.com/archive/p/iphone-wireless/wikis/Apple80211.wiki + +// 0 is sucessful; < 0 is failure +int Apple80211Open(struct Apple80211 **handle) __attribute__((weak_import)); +int Apple80211BindToInterface(struct Apple80211 *handle, CFStringRef interface) __attribute__((weak_import)); +int Apple80211GetInfoCopy(struct Apple80211 *handle, CFDictionaryRef *info) __attribute__((weak_import)); +int Apple80211Close(struct Apple80211 *handle) __attribute__((weak_import)); + +static NSDictionary* getWifiInfoByApple80211(NSString* ifName) +{ + if (!Apple80211Open || !Apple80211BindToInterface || !Apple80211GetInfoCopy || !Apple80211Close) return NULL; + + struct Apple80211* handle = NULL; + if (Apple80211Open(&handle) < 0) return NULL; + if (Apple80211BindToInterface(handle, (CFStringRef)ifName) < 0) return NULL; + CFDictionaryRef result; + if (Apple80211GetInfoCopy(handle, &result) < 0) return NULL; + Apple80211Close(handle); + return CFBridgingRelease(result); +} + const char* ffDetectWifi(FFlist* result) { NSArray* interfaces = CWWiFiClient.sharedWiFiClient.interfaces; @@ -28,27 +49,24 @@ const char* ffDetectWifi(FFlist* result) if(!inf.powerOn) continue; - ffStrbufSetStatic(&item->conn.status, inf.serviceActive ? "Active" : "Inactive"); + ffStrbufSetStatic(&item->conn.status, inf.interfaceMode != kCWInterfaceModeNone ? "Active" : "Inactive"); if(!inf.serviceActive) continue; - if (inf.ssid) + NSDictionary* apple = NULL; + + if (inf.ssid) // https://developer.apple.com/forums/thread/732431 ffStrbufAppendS(&item->conn.ssid, inf.ssid.UTF8String); - else if (!ffProcessAppendStdOut(&item->conn.ssid, (char* []) { - "/usr/sbin/networksetup", - "-getairportnetwork", - item->inf.description.chars, - NULL - }) && item->conn.ssid.length > 0) - { - uint32_t index = ffStrbufFirstIndexC(&item->conn.ssid, ':'); - if (index < item->conn.ssid.length) - ffStrbufSubstrAfter(&item->conn.ssid, index + 1); - } + else if (apple || (apple = getWifiInfoByApple80211(inf.interfaceName))) + ffStrbufAppendS(&item->conn.ssid, [[apple valueForKey:@"SSID_STR"] UTF8String]); else ffStrbufSetStatic(&item->conn.ssid, ""); // https://developer.apple.com/forums/thread/732431 - ffStrbufAppendS(&item->conn.macAddress, inf.hardwareAddress.UTF8String); + if (inf.bssid) + ffStrbufAppendS(&item->conn.macAddress, inf.bssid.UTF8String); + else if (apple || (apple = getWifiInfoByApple80211(inf.interfaceName))) + ffStrbufAppendS(&item->conn.macAddress, [[apple valueForKey:@"BSSID"] UTF8String]); + switch(inf.activePHYMode) { case kCWPHYModeNone: @@ -134,28 +152,35 @@ const char* ffDetectWifi(FFlist* result) break; case kCWSecurityUnknown: // Sonoma... + if (apple || (apple = getWifiInfoByApple80211(inf.interfaceName))) { - if (!ffProcessAppendStdOut(&item->conn.security, (char* []) { - "/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport", - "-I", - NULL - })) + NSDictionary* authType = [apple valueForKey:@"AUTH_TYPE"]; + if (authType) { - { - uint32_t ssidIndex = ffStrbufFirstIndexS(&item->conn.security, " SSID: "); - if (ssidIndex == item->conn.security.length) break; - ssidIndex += (uint32_t) strlen(" SSID: "); - uint32_t ssidEndIndex = ffStrbufNextIndexC(&item->conn.security, ssidIndex, '\n'); - if (item->conn.ssid.length != ssidEndIndex - ssidIndex) break; - } + if ([[authType valueForKey:@"AUTH_LOWER"] intValue] != 1) break; // APPLE80211_AUTH_TYPE_UNICAST? - uint32_t linkAuthIndex = ffStrbufFirstIndexS(&item->conn.security, " link auth: "); - if (linkAuthIndex == item->conn.security.length) break; - linkAuthIndex += (uint32_t) strlen(" link auth: "); - uint32_t linkAuthEndIndex = ffStrbufNextIndexC(&item->conn.security, linkAuthIndex, '\n'); - ffStrbufSubstrBefore(&item->conn.security, linkAuthEndIndex); - ffStrbufSubstrAfter(&item->conn.security, linkAuthIndex - 1); - ffStrbufUpperCase(&item->conn.security); + NSNumber* authUpper = [authType valueForKey:@"AUTH_UPPER"]; + if (!authUpper) + ffStrbufSetStatic(&item->conn.security, "Insecure"); + else + { + int authUpperValue = [authUpper intValue]; + switch (authUpperValue) + { + case 4096: + ffStrbufSetStatic(&item->conn.security, "WPA3-SAE"); + break; + case 8: + ffStrbufSetStatic(&item->conn.security, "WPA2-PSK"); + break; + case 4: + ffStrbufSetStatic(&item->conn.security, "WPA2"); + break; + default: // TODO: support more auth types + ffStrbufAppendF(&item->conn.security, "To be supported (%d)", authUpperValue); + break; + } + } } } break; diff --git a/src/modules/wifi/wifi.c b/src/modules/wifi/wifi.c index 152fe86ee..25617d677 100644 --- a/src/modules/wifi/wifi.c +++ b/src/modules/wifi/wifi.c @@ -132,8 +132,9 @@ void ffGenerateWifiJsonResult(FF_MAYBE_UNUSED FFWifiOptions* options, yyjson_mut yyjson_mut_val* conn = yyjson_mut_obj_add_obj(doc, obj, "conn"); yyjson_mut_obj_add_strbuf(doc, conn, "status", &wifi->conn.status); yyjson_mut_obj_add_strbuf(doc, conn, "ssid", &wifi->conn.ssid); - yyjson_mut_obj_add_strbuf(doc, conn, "macAddress", &wifi->conn.macAddress); + yyjson_mut_obj_add_strbuf(doc, conn, "bssid", &wifi->conn.macAddress); yyjson_mut_obj_add_strbuf(doc, conn, "protocol", &wifi->conn.protocol); + yyjson_mut_obj_add_strbuf(doc, conn, "security", &wifi->conn.security); yyjson_mut_obj_add_real(doc, conn, "signalQuality", wifi->conn.signalQuality); yyjson_mut_obj_add_real(doc, conn, "rxRate", wifi->conn.rxRate); yyjson_mut_obj_add_real(doc, conn, "txRate", wifi->conn.txRate); @@ -158,7 +159,7 @@ void ffPrintWifiHelpFormat(void) "Interface status", "Connection status", "Connection SSID", - "Connection mac address", + "Connection BSSID", "Connection protocol", "Connection signal quality (percentage)", "Connection RX rate",