macOS get SSID changes?

I've had a little personal utility running for several versions of macOS that uses

let client = CWWiFiClient.shared()
if let ssid_name = client.interface()?.ssid() 

to get the current SSID name and prints it (along with a bunch of other active network details.

With the most recent Sonoma Beta 2 and Xcode beta 2, this always returns nil. Doing the same thing in a playground works as expected.
Is this a purposeful change or a bug I should file?

Answered by DTS Engineer in 758611022

I asked the CoreWLAN folks about this, and it looks like this was a deliberate change: Accessing the ssid property now requires the location privilege (r. 108641482).

We called this out in the header doc comments, where <CoreWLAN/CWInterface.h> now says:

SSID information is not available unless Location Services is enabled and the user has authorized the calling app to use location services.

I’d appreciate you filing a bug requested that the official docs be updated with that info.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi @eskimo Because we needed compatibility with macOS 12, we were unable to onboard our launch agents with SMAppService Our login item is instantiated with SMLoginItemSetEnabled, but our launch agent plist files are populated in the post install script of our pkg: /bin/launchctl bootstrap gui/"$CURRENT_UID" "/Library/LaunchAgents/agentName.plist" which loads the agent with the appropriate configs. Essentially what's happening right now is that I codesign the .app with the location entitlement, but unless i explicitly click on the app and it runs in the foreground the locationmanager.requestAlwaysAuthorization() never prompts. Would love to setup a quick consultation with you if you are available. "ajdali" + "@" + "amazon.com"

Perhaps, the location string in the info.plist is required in order to access the protected resource?

As everyone else I am too unable to get the SSID information with Sonoma but it is still not clear to me if when using the location service it should finally work.

ajdali wrote:

Would love to setup a quick consultation

To be clear, DevForums is not a formal support channel. See tip 3 in Quinn’s Top Ten DevForums Tips.

Because we needed compatibility with macOS 12, we were unable to onboard our launch agents with SMAppService

OK, but you don’t have this problem on macOS 12 either. So, installing your agent using SMAppService resolves this problem, you have a path to a solution (use SMAppService where it’s available, use SMLoginItemSetEnabled on older systems). I recommend that you try that.

Our login item is instantiated with SMLoginItemSetEnabled, but our launch agent plist files are populated in the post install script of our pkg: /bin/launchctl bootstrap gui/"$CURRENT_UID" "/Library/LaunchAgents/agentName.plist" which loads the agent with the appropriate configs.

OK, mixing SMLoginItemSetEnabled and a launchctl is less than ideal. However, that doesn’t really matter if you can use SMAppService moving forward. You can just disable this stuff on newer systems and remove it when you drop macOS 12 support.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo Can you please confirm if just using the SMAppService will resolve the problem of obtaining SSID information? Or do I need some additional entitlements or need to make adjustments to Location Services?

I am currently experiencing the same issue with obtaining SSID. Here is the code example I use:

CWWiFiClient *client = [CWWiFiClient sharedWiFiClient];
CWInterface *interface = [client interface];
NSString *ssid = [interface ssid];

It returns nil on Sonoma.
This code is part of a LaunchDaemon with a plist file located in /Library/LaunchDaemons, which was registered using SMJobBless(). I understand that this method is now considered obsolete, but it was working fine before the Sonoma release.

Thanks in advance.

Update: Installing a daemon using SMAppService does not fix the issue (even with 'com.apple.security.personal-information.location' in entitlements).
Does anybody have a clear solution on how to make it work for background daemons on Sonoma?

Can you please confirm if just using the SMAppService will resolve the problem of obtaining SSID information?

SMAppService will let you install an agent and an agent can get the Core Location privilege, but it’s not a solution to this overall problem.

For more on this, see my response here.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

This seems like a really breaking change. To say that any application configured as a launch agent or daemon cannot simply get the connected SSID then what should we expect in the future? How can one single SSID value fingerprint a user or compromise their location? Seems like apple is going down the deep end with all these privacy controls. I'm truly baffled how they connected the dots from a user's connected SSID and their location.

It's still not clear how to request Location Services permissions for a non-UI app.

@eskimo I would greatly appreciate it if you could clarify a few points:

  1. There is no way to obtain location permissions for non-UI apps, like simple console apps. Is that correct?

  2. As far as I understood your previous comments, LaunchAgent installed by SMAppService() can obtain Location permissions and retrieve SSID info. What are the requirements for this? Should SMAppService() be called by the UI app (let's call it the 'installer'), or can a console app also invoke SMAppService()? It's also unclear which app should possess the com.apple.security.personal-information.location entitlement and the NSLocationAlwaysUsageDescription definition: the 'installer' or the LaunchAgent?

Thanks in advance.

ajdali wrote:

To say that any application configured as a launch agent or daemon cannot simply get the connected SSID

Hmmm, that’s not what I said. Rather, there’s a agent vs daemon split here:

  • I think it’s feasible for a launchd agent to get the location privilege and thus get access to this info. See below.

  • In contrast, as things currently stand I don’t think it’s feasible for a daemon to do this.

then what should we expect in the future?

Realistically, more of the same |-: There was a great quote about this way back at WWDC 2017, which I highlighted in a footnote on this post.


stenya wrote:

There is no way to obtain location permissions for non-UI apps, like simple console apps. Is that correct?

There’s no way to answer that as written because the term “console app” isn’t one I use. You’re talking about a Mach-O executable here, but its behaviour depends on the context in which it’s run. For example, whether it’s:

  • Run by the user in Terminal

  • Run by the user over SSH

  • Run by an app as a ‘helper tool’

  • Run by launchd as an agent

  • Run by launchd as a daemon

As far as I understood your previous comments, LaunchAgent installed by SMAppService can obtain Location permissions and retrieve SSID info. What are the requirements for this?

Lemme explain the backstory here…

Most privileges like this are managed by TCC and it has a good understanding of the concept of responsible code [1]. So, if your launchd agent has a GUI app as its responsible code then granting the TCC privilege to the GUI app also grants it to your agent. I’ve tested this numerous times and it works reasonably well.

The tricky part here is Core Location, which doesn’t use the standard TCC infrastructure to manage its privilege [2]. I’ve not actually sat down to test the launchd agent to responsible GUI app path for the location privilege.

If you want to try this out, create a GUI app that acquires both a standard TCC privilege, like Input Monitoring, and the location privilege. Then use that to install an agent and see if it ‘inherits’ those privileges from the responsible GUI app. I know that’ll work for Input Monitoring [3]. Does it work for the location privilege?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] I define that term in On File System Permissions.

[2] Because a) Core Location needs more flexibility than most TCC-managed privileges, and b) Core Location was one of the first privileges like this.

[3] Ah, um, it worked the last time I tested it, on macOS 13. I haven’t tried this on macOS 14 yet. AFAIK nothing has changed there but… *shrug*

@eskimo @stenya Revisiting this after Sonoma 14.4 released: Now our workaround to call a bash script from the launchd daemon/agent is no longer working in Sonoma as well /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | awk '/ SSID/ {print $2}'

I have configured the Launch Agent with the Location Services prompt, and accepted it. Still calling the Apple CoreWLan APIs do not get me any Wifi ssid information that I need. Do we have any certified reccomendation from Apple on how to proceed?

My general advice is to not use a command-line tool when there’s an API equivalent. And doubly so when the command-line tool is buried deep in a framework rather than being on the default shell path.

Still calling the Apple CoreWLAN APIs do not get me any Wifi ssid information that I need.

Let’s start with some fundamentals:

  • Package your agent in an app-like wrapper.

  • Make sure it has a reasonable bundle ID.

  • Sign it with a stable code signing identity, like Apple Development.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Just FYI: I reported a related issue using the feedback assistant and as of build 23E214,21T216 my issue is fixed. Maybe this helps!

The Sonoma update got me too.

I found that in terminal

networksetup getairportnetwork en0

will display the SSID as

Current Network: SSID

and in Python

import subprocess

wifi = subprocess.check_output(['networksetup', 'getairportnetwork', 'en0']).decode('utf-8') will return a string containing the SSID

Hi, all. Thanks for this thread. I incorporated the feedback here and created wifi-unredactor, a small tool that uses a minimal GUI wrapper to trigger a location services prompt and pass those permissions to a CLI program. Works on latest macOS to date (Sonoma 14.6.1).

https://github.com/noperator/wifi-unredactor

Outputs JSON like this:

$ wifi-unredactor
{
  "interface" : "en0",
  "ssid" : "BrightSquirrelNet72",
  "bssid" : "4A:3B:1C:D2:E5:F8"
}
macOS get SSID changes?
 
 
Q