-
Notifications
You must be signed in to change notification settings - Fork 2
Mac Knowledge Bytes
A collection of Mac-specific details, history, and tips. This is not meant to be step-by-step instructions, nor is it all required reading, but rather it's a knowledge collection for reference as-needed.
- Includes Apple's attempt to directly support FTDI USB chipsets through Apple's kernel extension (kext)
- first at
/System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBFTDI.kext
- later at
/System/Library/Extensions/AppleUSBFTDI.kext
(Mac OS X 10.11 "El Capitan")
- first at
- Introduced a new required destination for third-party driver installation destination
- from
/System/Library/Extensions/
- to
/Library/Extensions/
(FTDI's driver must go here)- See "Staged Kexts" in KEXT Admin Tips for additional information
- from
- Apple's FTDI driver (AppleUSBFTDI.kext)
- Didn't support all features Parallax needs (namely, DTR support was missing or inadequate)
- Caused system conflicts on some computers when FTDI's driver was installed (occasional Kernel Panics)
- The occurrence of this grew very rare as time when on (later versions after Mavericks seemed to solve it)
- Sometimes needed manual administrative help to prevent problems; see KEXT Admin Tips
- Apple introduced app hardened runtime, entitlements, notarization, and stapling.
- These are optional features in Mojave and required in Catalina.
- FTDI drivers are still required (v2.4.2)
- Apple enforced app hardened runtime, entitlements, and notarization.
- Apple introduced system extensions (dext) and deprecated kernel extensions (kext) for third-party use.
- Accordingly, Apple's built-in FTDI support changed from kext to dext
- Stored here
/System/Library/DriverExtensions/DriverKit.AppleUSBFTDI.dext
- Works great (on hosts, not on VMs for an unknown reason)
- Stored here
- Accordingly, Apple's built-in FTDI support changed from kext to dext
https://developer.apple.com/documentation/systemextensions
Manually disable Apple's kext driver: sudo kextunload -b com.apple.driver.AppleUSBFTDI
Manually enable FTDI's kext driver: sudo kextload -b com.FTDI.driver.FTDIUSBSerialDriver
Verify FTDI's driver is running:
- Plug in FTDI-based device
-
kextstat | grep FTDI
- If all is well, it will report a line of information with the FTDI driver (not the Apple driver) listed in reverse-domain form (
com.FTDI.driver.FTDIUSBSerialDriver
). - If something's wrong, it won't report anything, or it will report the Apple driver instead (
com.apple.driver.AppleUSBFTDI
).
- If all is well, it will report a line of information with the FTDI driver (not the Apple driver) listed in reverse-domain form (
Staged FTDI Driver:
- Upon reboot, system will create a prelinked kext in /Library/StagedExtensions/Library/Extensions/FTDIUSBSerialDriver.kext based on files present in /Library/Extensions. These staged extensions will get loaded early upon every boot.
- To remove the driver fully:
sudo rm -r /Library/Extensions/FTDIUSBSerialDriver.kext/
-
ls /Library/StagedExtensions/Library/Extensions/
to verify the FTDIUSESerialDriver.kext file is there, and if it is... sudo kextcache --prune-staging
- To remove the driver fully:
- Do not use v2.3 (suffers a "surprise removal" bug)
- Use v2.4.2 only on macOS 10.12 "Sierra" through macOS 10.14 "Mojave"
- Do not use any FTDI driver on macOS 10.15 "Catalina" (or later); it's not needed as Mac's included driver works
- FTDI's v2.4.2 driver (re-signed and re-released 2019-12-24) will not install in Catalina (or Mojave?) due to Apple discontinuing their kext-signing permission on their Developer ID. FTDI is begging Apple to reissue their Developer ID with the kext-signing permission. Meanwhile, Parallax still maintains the formerly-signed v2.4.2 that still installs on Mojave and runs properly.
- This NWJS Issue details the struggle others are experiencing. It was instrumental in getting the NWJS-wrapped BlocklyProp Launcher notarized and runnable on Catalina.
- Gatekeeper on Catalina prevents apps from running unless they are developer-signed and Apple-notarized.
- Can only be overridden by administrators but it remains confusing and nagging.
- NWJS's app bundle contains many libraries and helper applications (bundles), all of which need to be signed (by either the NWJS team or by Parallax) in order for Apple issue a successful notarization.
- Apps need to be signed with the hardened runtime attribute as well as with app-specific special permissions (called entitlements) in order to run properly (as a hardened runtime) and have access to resources they need.
- NWJS seems to require the
com.apple.security.cs.allow-unsigned-executable-memory
entitlement be set to true in order for it to read it's bundle-embedded app (in its /Resources/app.nw/ folder). Without this entitlement, the OS starts NWJS and fails silently (only showing an NWJS menu but no application window).
- NWJS seems to require the
- Recommend nwjs v0.69.1 (which includes Chrome v106.0.5249.61) on Ventura to resolve a failure-to-run issue for nwjs-wrapped apps.
See article about Apple's macOS Code Signing In Depth
- Using Finder's Duplicate feature (on an NWJS bundle) makes a copy of the NWJS-wrapped app but keeps symbolic links to the original nodes. Later, if the original is moved to trash, the duplicate's symbolic links now point to the trash.
- The same behavior may be true of Finder's Copy feature - this seemed to be the behavior witnessed.
- A potential solution is to use the command-line copy; however, developers have noted the same problems.
- It appears that modern versions of macOS support
cp -a
which maintains symbolic links
- It appears that modern versions of macOS support
At the time of this writing, the entitlements below (see "..." values) are required to get the BlocklyProp Launcher to fully run (after install) on macOS 10.15.3 "Catalina." This is from the neededToRun.entitlements file in the repo and is used by the codesign app (called by the "mac_sign..." script).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.automation.apple-events</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.personal-information.addressbook</key>
<true/>
<key>com.apple.security.personal-information.calendars</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
</dict>
</plist>
cd ../dist/BlocklyPropLauncher.app/Contents/Frameworks/nwjs\ Framework.framework/Versions/Current/Libraries
codesign -s "Developer ID Application" --deep -f -v --options runtime --timestamp --entitlements "../../../../../../../../package/mac-resources/neededToRun.entitlements" "libEGL.dylib"
codesign -s "Developer ID Application" --deep -f -v --options runtime --timestamp --entitlements "../../../../../../../../package/mac-resources/neededToRun.entitlements" "libGLESv2.dylib"
codesign -s "Developer ID Application" --deep -f -v --options runtime --timestamp --entitlements "../../../../../../../../package/mac-resources/neededToRun.entitlements" "libswiftshader_libEGL.dylib"
codesign -s "Developer ID Application" --deep -f -v --options runtime --timestamp --entitlements "../../../../../../../../package/mac-resources/neededToRun.entitlements" "libswiftshader_libGLESv2.dylib"
cd ../dist/BlocklyPropLauncher.app/Contents/Frameworks/nwjs\ Framework.framework
codesign -s "Developer ID Application" --deep -f -v --options runtime --timestamp --entitlements "../../../../../package/mac-resources/neededToRun.entitlements" "nwjs Framework"
codesign -vvvv --deep --strict nwjs\ Framework
cd ../../../../../
cd package
./mac_app_sign_and_package.sh -a "BlocklyPropLauncher" -v 0.11.1 -d
xcrun altool --notarize-app --primary-bundle-id "BlocklyPropLauncher" --username "{apple_developer_email_address}" --file "../dist/BlocklyPropLauncher-0.11.1-setup-MacOS.pkg"
xcrun altool -u "{apple_developer_email_address}" --notarization-info d5aedf84-ea23-4e19-a035-c925bed389dd
xcrun stapler staple -v ../dist/BlocklyPropLauncher-0.11.1-setup-MacOS.pkg
NOTE: Any reference to {apple_developer_email_address} must be replaced by the Apple ID email address (Apple developer account) as shown in password database.
BlocklyProp_Launcher % ./MakeRelease
(copy contents of Release folder to the nwjs app bundle at Contents/Resources/app.nw)
(This is achieved in Finder by navigating to the dist/ subfolder, finding the BlocklyPropLauncher app, right-click > Show Package Contents, then follow path above and paste)
(Open nwjs app bundle's Contents/Info.plist with XCode and set the "Bundle versions string, short" value to the proper version number)
(NOTE: The mac_app_sign_and_package script below says it's setting the version, but it fails to do so)
BlocklyProp_Launcher % cd ./package
package % ./mac_app_sign_and_package.sh -a "BlocklyPropLauncher" -v 1.0.4 -d
(OPTIONAL) package % ./mac_app_verify_signatures.sh -a "BlocklyPropLauncher"
package % ./mac_app_notarize.sh -a "BlocklyPropLauncher" -v 1.0.4 -d {apple_developer_email_address}
NOTES: 1) Use the App Notarization password (from Apple Developer account in password database)
2) After entering password, the CLI will appear frozen for a couple minutes; it's okay, it's uploading the package to Apple's notary service.
3) If no errors are reported, wait for notarization email.
(IF NOTARIZATION EMAIL RESPONSE IS SUCCESSFUL...)
package % ./mac_app_staple.sh -a "BlocklyPropLauncher" -v 1.0.4
NOTE: It may complain near the end of the response output that "We do not know how to deal with trailer version..." but this doesn't seem to be fatal
as it later reports "The staple and validate action worked!"
package % mv ../dist/BlocklyPropLauncher-1.0.4-setup-MacOS.pkg ../dist/Setup-BPLauncher-1.0.4-MacOS.pkg
NOTE: Any reference to {apple_developer_email_address} must be replaced by the Apple ID email address (Apple developer account) as shown in password database.
com.apple.security.automation.apple-events
com.apple.security.device.audio-input
com.apple.security.device.camera
com.apple.security.personal-information.addressbook
com.apple.security.personal-information.calendars
Prompting policy for hardened runtime; service: kTCCServiceMicrophone requires entitlement com.apple.security.device.audio-input but it is missing for REQ:{ID: io.nwjs.nwjs, PID[1666], auid: 501, euid: 501, binary path: '/Applications/BlocklyPropLauncher.app/Contents/MacOS/nwjs'}
Prompting policy for hardened runtime; service: kTCCServiceCamera requires entitlement com.apple.security.device.camera but it is missing for REQ:{ID: io.nwjs.nwjs, PID[1666], auid: 501, euid: 501, binary path: '/Applications/BlocklyPropLauncher.app/Contents/MacOS/nwjs'}
Prompting policy for hardened runtime; service: kTCCServiceAddressBook requires entitlement com.apple.security.personal-information.addressbook but it is missing for ACC:{ID: io.nwjs.nwjs, PID[1666], auid: 501, euid: 501, binary path: '/Applications/BlocklyPropLauncher.app/Contents/MacOS/nwjs'}, REQ:{ID: com.apple.mds, PID[118], auid: 0, euid: 0, binary path: '/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Support/mds'}
Prompting policy for hardened runtime; service: kTCCServiceCalendar requires entitlement com.apple.security.personal-information.calendars but it is missing for ACC:{ID: io.nwjs.nwjs, PID[1666], auid: 501, euid: 501, binary path: '/Applications/BlocklyPropLauncher.app/Contents/MacOS/nwjs'}, REQ:{ID: com.apple.mds, PID[118], auid: 0, euid: 0, binary path: '/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Support/mds'}
Prompting policy for hardened runtime; service: kTCCServiceAppleEvents requires entitlement com.apple.security.automation.apple-events but it is missing for ACC:{ID: io.nwjs.nwjs, PID[1666], auid: 501, euid: 501, binary path: '/Applications/BlocklyPropLauncher.app/Contents/MacOS/nwjs'}, REQ:{ID: com.apple.appleeventsd, PID[308], auid: 55, euid: 55, binary path: '/System/Library/CoreServices/appleeventsd'}
- It's been said that Apple will eventually require both hardened runtime and sandboxing in macOS apps. These are two different things- read more.