From 78deefe8e371573ba1c4e975adf72db0dddc81f9 Mon Sep 17 00:00:00 2001 From: Apple Date: Fri, 1 May 2020 18:25:39 +0000 Subject: [PATCH] configd-1061.101.1.tar.gz --- Plugins/InterfaceNamer/Makefile | 64 +- Plugins/InterfaceNamer/ifnamer.c | 650 ++++++--- Plugins/PreferencesMonitor/prefsmon.c | 324 +---- SystemConfiguration.fproj/SCD.c | 15 +- SystemConfiguration.fproj/SCDHostName.c | 24 +- SystemConfiguration.fproj/SCDOpen.c | 35 +- SystemConfiguration.fproj/SCDPrivate.c | 42 +- .../SCNetworkConfigurationInternal.c | 109 +- .../SCNetworkConfigurationInternal.h | 65 +- .../SCNetworkConfigurationPrivate.c | 1169 +++++++++++++++++ .../SCNetworkConfigurationPrivate.h | 34 +- .../SCNetworkInterface.c | 324 +++-- .../SCNetworkMigration.c | 207 ++- SystemConfiguration.fproj/SCNetworkProtocol.c | 6 +- SystemConfiguration.fproj/SCNetworkService.c | 96 +- SystemConfiguration.fproj/SCP.c | 78 +- SystemConfiguration.fproj/SCPCommit.c | 13 +- SystemConfiguration.fproj/SCPOpen.c | 166 ++- .../SCPreferencesInternal.h | 39 +- .../SCPreferencesPrivate.h | 18 +- SystemConfiguration.fproj/SCPrivate.h | 8 +- .../SCSchemaDefinitions.c | 1 + .../SCSchemaDefinitions.h | 2 +- .../SCSchemaDefinitionsPrivate.h | 10 +- SystemConfiguration.fproj/genSCPreferences.c | 13 +- configd.xcodeproj/project.pbxproj | 73 +- sctest/SCTestInterfaceNamer.m | 556 ++++++++ sctest/SCTestOptions.h | 1 + sctest/SCTestUtils.h | 5 +- sctest/genSCTestOptions.c | 3 +- sctest/main.m | 6 +- scutil.tproj/commands.c | 18 +- scutil.tproj/net.c | 134 +- scutil.tproj/net.h | 4 +- scutil.tproj/prefs.c | 64 +- scutil.tproj/prefs.h | 10 +- scutil.tproj/scutil.c | 4 +- scutil.tproj/scutil.h | 8 +- 38 files changed, 3376 insertions(+), 1022 deletions(-) create mode 100644 SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c create mode 100644 sctest/SCTestInterfaceNamer.m diff --git a/Plugins/InterfaceNamer/Makefile b/Plugins/InterfaceNamer/Makefile index 705d8af..aef0460 100644 --- a/Plugins/InterfaceNamer/Makefile +++ b/Plugins/InterfaceNamer/Makefile @@ -1,13 +1,63 @@ -ifnamer: ifnamer.c - cc -Wall -g -DMAIN -o ifnamer ifnamer.c -framework CoreFoundation -framework SystemConfiguration -framework IOKit +ifeq ($(PLATFORM),) +PLATFORM=macosx +endif -snapshot: ifnamer.c - cc -Wall -g -DTEST_SNAPSHOT -o snapshot ifnamer.c -framework CoreFoundation -framework SystemConfiguration -framework IOKit +ifeq ($(PLATFORM),iphoneos) +# iOS internal SDK +ARCHS=arm64 +endif -uuid: ifnamer.c - cc -Wall -g -DTEST_PLATFORM_UUID -o uuid ifnamer.c -framework CoreFoundation -framework SystemConfiguration -framework IOKit +ifeq ($(PLATFORM),macosx) +# Mac OS X internal SDK +ARCHS=x86_64 +endif + + +ifeq ($(USER),ajn) + ifeq ($(PLATFORM),macosx) + PLATFORM=macosx$(OSX_VERSION) + EXTRA=-target $(ARCHS)-apple-macos$(OSX_VERSION) -F${BUILDIT_DIR}/configd-999.roots/Shared/SDKContentRoot/osx/System/Library/Frameworks + endif + ifeq ($(PLATFORM),iphoneos) + PLATFORM=ios$(EMBEDDED_VERSION) + EXTRA=-target $(ARCHS)-apple-ios$(EMBEDDED_VERSION) -F${BUILDIT_DIR}_Embedded/configd-999.roots/Shared/SDKContentRoot/ios/System/Library/Frameworks + endif + EXTRA+=-DDEBUG +endif + + +# Mac OS X or iOS internal SDK +SDK=$(PLATFORM)internal +SYSROOT=$(shell xcodebuild -version -sdk $(SDK) Path) +CC = xcrun -sdk $(SDK) cc + + +all : ifnamer snapshot + +# ---------- ---------- ---------- ---------- ---------- + +InterfaceNamerControlPrefs.o : ../../Plugins/common/InterfaceNamerControlPrefs.c ../../Plugins/common/InterfaceNamerControlPrefs.h Makefile + $(CC) -DOS_ACTIVITY_OBJECT_API=1 -I../../SystemConfiguration.fproj -I../../IPMonitorControl -I../../Plugins/common ${EXTRA} -I${SYSROOT}/System/Library/Frameworks/System.framework/PrivateHeaders -Wall -g -O0 -c ../../Plugins/common/InterfaceNamerControlPrefs.c + +# ---------- ---------- ---------- ---------- ---------- + +ifnamer.o: ifnamer.c Makefile + $(CC) -DOS_ACTIVITY_OBJECT_API=1 -I../../SystemConfiguration.fproj -I../../IPMonitorControl -I../../Plugins/common ${EXTRA} -I${SYSROOT}/System/Library/Frameworks/System.framework/PrivateHeaders -Wall -g -DTEST_INTERFACE_ASSIGNMENT -O0 -c ifnamer.c + +ifnamer: ifnamer.o InterfaceNamerControlPrefs.o Makefile + $(CC) -o ifnamer ifnamer.o InterfaceNamerControlPrefs.o ${EXTRA} -framework CoreFoundation -framework SystemConfiguration -framework IOKit + +# ---------- ---------- ---------- ---------- ---------- + +snapshot.o: ifnamer.c Makefile + $(CC) -DOS_ACTIVITY_OBJECT_API=1 -I../../SystemConfiguration.fproj -I../../IPMonitorControl -I../../Plugins/common ${EXTRA} -I${SYSROOT}/System/Library/Frameworks/System.framework/PrivateHeaders -Wall -g -DTEST_SNAPSHOT -O0 -c -o $@ ifnamer.c + +snapshot: snapshot.o InterfaceNamerControlPrefs.o Makefile + $(CC) -o snapshot snapshot.o InterfaceNamerControlPrefs.o ${EXTRA} -framework CoreFoundation -framework SystemConfiguration -framework IOKit + +# ---------- ---------- ---------- ---------- ---------- clean: - rm -rf ifnamer ifnamer.dSYM snapshot snapshot.dSYM uuid uuid.dSYM + rm -rf *.o ifnamer ifnamer.dSYM snapshot snapshot.dSYM diff --git a/Plugins/InterfaceNamer/ifnamer.c b/Plugins/InterfaceNamer/ifnamer.c index 010f3f8..9d3f0dd 100644 --- a/Plugins/InterfaceNamer/ifnamer.c +++ b/Plugins/InterfaceNamer/ifnamer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2019 Apple Inc. All rights reserved. + * Copyright (c) 2001-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -85,11 +85,17 @@ #include #include #include "SCNetworkConfigurationInternal.h" +#include "SCPreferencesInternal.h" #include "plugin_shared.h" #if !TARGET_OS_IPHONE #include "InterfaceNamerControlPrefs.h" #endif // !TARGET_OS_IPHONE +#ifdef TEST_INTERFACE_ASSIGNMENT +#undef INTERFACES_DEFAULT_CONFIG +#define INTERFACES_DEFAULT_CONFIG CFSTR("/tmp/ifnamer-test-NetworkInterfaces.plist") +#endif // TEST_INTERFACE_ASSIGNMENT + #include #include #include @@ -114,11 +120,6 @@ enum { }; #endif // !USE_REGISTRY_ENTRY_ID -#define kSCNetworkInterfaceActive "Active" -#define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo" -#define kSCNetworkInterfaceType "SCNetworkInterfaceType" -#define kSCNetworkInterfaceMatchingMACs "MatchingMACs" - #define MY_PLUGIN_NAME "InterfaceNamer" #define MY_PLUGIN_ID CFSTR("com.apple.SystemConfiguration." MY_PLUGIN_NAME) @@ -289,9 +290,6 @@ addTimestamp(CFMutableDictionaryRef dict, CFStringRef key) return; } -#define INTERFACES CFSTR("Interfaces") -#define NETWORK_INTERFACES_PREFS CFSTR("NetworkInterfaces.plist") - static CFComparisonResult if_unit_compare(const void *val1, const void *val2, void *context) { @@ -317,57 +315,83 @@ if_unit_compare(const void *val1, const void *val2, void *context) return (CFNumberCompare(unit1, unit2, NULL)); } +static void +writeInterfaceListForModel(SCPreferencesRef prefs, CFStringRef old_model) +{ + Boolean ok; + CFPropertyListRef plist; + SCPreferencesRef savedPrefs; + CFStringRef savedPrefsID; + + savedPrefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-%@"), + INTERFACES_DEFAULT_CONFIG, + old_model); + savedPrefs = SCPreferencesCreate(NULL, CFSTR(MY_PLUGIN_NAME ":writeInterfaceListForModel"), savedPrefsID); + CFRelease(savedPrefsID); + if (savedPrefs == NULL) { + SC_log(LOG_NOTICE, "SCPreferencesCreate(\"NetworkInterfaces-.plist\") failed: %s", SCErrorString(SCError())); + return; + } + + plist = SCPreferencesPathGetValue(prefs, CFSTR("/")); + ok = SCPreferencesPathSetValue(savedPrefs, CFSTR("/"), plist); + if (!ok) { + SC_log(LOG_NOTICE, "SCPreferencesPathSetValue() failed: %s", SCErrorString(SCError())); + } + + ok = SCPreferencesCommitChanges(savedPrefs); + CFRelease(savedPrefs); + if (!ok) { + SC_log(LOG_NOTICE, "SCPreferencesCommitChanges(\"NetworkInterfaces-.plist\") failed: %s", SCErrorString(SCError())); + } + + return; +} + static void writeInterfaceList(CFArrayRef if_list) { CFArrayRef cur_list; CFStringRef new_model; + SCPreferencesRef ni_prefs; CFStringRef old_model; - SCPreferencesRef prefs; - if (isA_CFArray(if_list) == NULL) { + if (!isA_CFArray(if_list)) { return; } - prefs = SCPreferencesCreate(NULL, CFSTR(MY_PLUGIN_NAME ":writeInterfaceList"), NETWORK_INTERFACES_PREFS); - if (prefs == NULL) { - SC_log(LOG_NOTICE, "SCPreferencesCreate() failed: %s", SCErrorString(SCError())); + ni_prefs = SCPreferencesCreate(NULL, CFSTR(MY_PLUGIN_NAME ":writeInterfaceList"), INTERFACES_DEFAULT_CONFIG); + if (ni_prefs == NULL) { + SC_log(LOG_NOTICE, "SCPreferencesCreate(\"NetworkInterfaces.plist\") failed: %s", SCErrorString(SCError())); return; } - cur_list = SCPreferencesGetValue(prefs, INTERFACES); + cur_list = SCPreferencesGetValue(ni_prefs, INTERFACES); if (_SC_CFEqual(cur_list, if_list)) { goto done; } - old_model = SCPreferencesGetValue(prefs, MODEL); + old_model = SCPreferencesGetValue(ni_prefs, MODEL); new_model = _SC_hw_model(FALSE); - if ((new_model != NULL) && !_SC_CFEqual(old_model, new_model)) { + if ((old_model != NULL) && !_SC_CFEqual(old_model, new_model)) { // if new hardware if ((old_model != NULL) && (cur_list != NULL)) { - CFStringRef history; - - // if interface list was created on other hardware - history = CFStringCreateWithFormat(NULL, NULL, - CFSTR("%@:%@"), - INTERFACES, - old_model); - SCPreferencesSetValue(prefs, history, cur_list); - CFRelease(history); - SC_log(LOG_NOTICE, "Hardware model changed\n" " created on \"%@\"\n" " now on \"%@\"", old_model, new_model); + + // save the interface list that was created on "other" hardware + writeInterfaceListForModel(ni_prefs, old_model); } - SCPreferencesSetValue(prefs, MODEL, new_model); + SCPreferencesSetValue(ni_prefs, MODEL, new_model); } - SCPreferencesSetValue(prefs, INTERFACES, if_list); + SCPreferencesSetValue(ni_prefs, INTERFACES, if_list); - if (!SCPreferencesCommitChanges(prefs)) { + if (!SCPreferencesCommitChanges(ni_prefs)) { if (SCError() != EROFS) { SC_log(LOG_NOTICE, "SCPreferencesCommitChanges() failed: %s", SCErrorString(SCError())); } @@ -376,80 +400,52 @@ writeInterfaceList(CFArrayRef if_list) done: - CFRelease(prefs); + CFRelease(ni_prefs); return; } -static CFPropertyListRef -restoreNIPrefsFromBackup(SCPreferencesRef prefs, CFStringRef current_model) -{ - CFPropertyListRef if_list; - CFStringRef key; - - key = CFStringCreateWithFormat(NULL, 0, CFSTR("%@:%@"), INTERFACES, current_model); - if_list = SCPreferencesGetValue(prefs, key); - if_list = isA_CFArray(if_list); - if (if_list != NULL) { - /* Write the previously backed up Interface list for this hardware */ - writeInterfaceList(if_list); - - /* Synchronize the prefs */ - SCPreferencesSynchronize(prefs); - - /* Re-fetch the interface list */ - if_list = SCPreferencesGetValue(prefs, INTERFACES); - if_list = isA_CFArray(if_list); - if (if_list != NULL) { - /* We do not need the old interface list any more */ - SCPreferencesRemoveValue(prefs, key); - if (!SCPreferencesCommitChanges(prefs)) { - if (SCError() != EROFS) { - SC_log(LOG_NOTICE, "SCPreferencesCommitChanges() failed: %s", SCErrorString(SCError())); - } - if_list = NULL; - } - } - } - - CFRelease(key); - return if_list; -} - static CF_RETURNS_RETAINED CFMutableArrayRef readInterfaceList() { - CFArrayRef if_list; - CFStringRef old_model; - CFMutableArrayRef plist = NULL; - SCPreferencesRef prefs = NULL; + CFArrayRef if_list; + SCPreferencesRef ni_prefs; + CFStringRef old_model; + static Boolean once = FALSE; + CFMutableArrayRef plist = NULL; - prefs = SCPreferencesCreate(NULL, CFSTR(MY_PLUGIN_NAME ":readInterfaceList"), NETWORK_INTERFACES_PREFS); - if (prefs == NULL) { + ni_prefs = SCPreferencesCreate(NULL, CFSTR(MY_PLUGIN_NAME ":readInterfaceList"), INTERFACES_DEFAULT_CONFIG); + if (ni_prefs == NULL) { SC_log(LOG_NOTICE, "SCPreferencesCreate() failed: %s", SCErrorString(SCError())); return (NULL); } - if_list = SCPreferencesGetValue(prefs, INTERFACES); + if (!once) { + __SCNetworkConfigurationUpgrade(NULL, &ni_prefs, TRUE); + once = TRUE; + } + + if_list = SCPreferencesGetValue(ni_prefs, INTERFACES); if_list = isA_CFArray(if_list); - old_model = SCPreferencesGetValue(prefs, MODEL); + old_model = SCPreferencesGetValue(ni_prefs, MODEL); if (old_model != NULL) { CFStringRef new_model; new_model = _SC_hw_model(FALSE); if (!_SC_CFEqual(old_model, new_model)) { - /* if interface list was created on other hardware, - Restore if a backup interface list is present */ - if_list = restoreNIPrefsFromBackup(prefs, new_model); + /* + * If the interface list was created on other hardware then + * we start fresh. + */ + if_list = NULL; } } if (if_list != NULL) { - CFIndex i; CFIndex n = CFArrayGetCount(if_list); plist = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - for (i = 0; i < n; i++) { + for (CFIndex i = 0; i < n; i++) { CFDictionaryRef dict; dict = CFArrayGetValueAtIndex(if_list, i); @@ -462,9 +458,15 @@ readInterfaceList() } } - if (prefs != NULL) { - CFRelease(prefs); + if (plist != NULL) { + CFIndex n = CFArrayGetCount(plist); + + if (n > 1) { + CFArraySortValues(plist, CFRangeMake(0, n), if_unit_compare, NULL); + } } + + CFRelease(ni_prefs); return (plist); } @@ -472,7 +474,6 @@ static CF_RETURNS_RETAINED CFMutableArrayRef previouslyActiveInterfaces() { CFMutableArrayRef active; - CFIndex i; CFIndex n; if (S_dblist == NULL) { @@ -482,7 +483,7 @@ previouslyActiveInterfaces() active = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); n = CFArrayGetCount(S_dblist); - for (i = 0; i < n; i++) { + for (CFIndex i = 0; i < n; i++) { CFDictionaryRef if_dict; if_dict = CFArrayGetValueAtIndex(S_dblist, i); @@ -737,6 +738,10 @@ createInterfaceDict(SCNetworkInterfaceRef interface, CFArrayRef matchingMACs) CFSTR(kIOBuiltin), _SCNetworkInterfaceIsBuiltin(interface) ? kCFBooleanTrue : kCFBooleanFalse); + if (_SCNetworkInterfaceIsHiddenConfiguration(interface)) { + CFDictionarySetValue(new_if, kSCNetworkInterfaceHiddenConfigurationKey, kCFBooleanTrue); + } + CFDictionarySetValue(new_if, CFSTR(kSCNetworkInterfaceActive), kCFBooleanTrue); if (matchingMACs != NULL) { @@ -750,7 +755,6 @@ static CFDictionaryRef lookupInterfaceByAddress(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFIndex * where) { CFDataRef addr; - CFIndex i; CFIndex n; CFNumberRef type; @@ -764,7 +768,7 @@ lookupInterfaceByAddress(CFArrayRef db_list, SCNetworkInterfaceRef interface, CF } n = CFArrayGetCount(db_list); - for (i = 0; i < n; i++) { + for (CFIndex i = 0; i < n; i++) { CFDataRef a; CFDictionaryRef dict = CFArrayGetValueAtIndex(db_list, i); CFNumberRef t; @@ -784,10 +788,34 @@ lookupInterfaceByAddress(CFArrayRef db_list, SCNetworkInterfaceRef interface, CF return (NULL); } +static CFDictionaryRef +lookupInterfaceByName(CFArrayRef db_list, CFStringRef bsdName, CFIndex * where) +{ + CFIndex n; + + if (db_list == NULL) { + return (NULL); + } + + n = CFArrayGetCount(db_list); + for (CFIndex i = 0; i < n; i++) { + CFDictionaryRef dict = CFArrayGetValueAtIndex(db_list, i); + CFStringRef name; + + name = CFDictionaryGetValue(dict, CFSTR(kIOBSDNameKey)); + if (_SC_CFEqual(name, bsdName)) { + if (where) { + *where = i; + } + return (dict); + } + } + return (NULL); +} + static CFDictionaryRef lookupInterfaceByUnit(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFIndex * where) { - CFIndex i; CFIndex n; CFNumberRef type; CFNumberRef unit; @@ -802,7 +830,7 @@ lookupInterfaceByUnit(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFInd } n = CFArrayGetCount(db_list); - for (i = 0; i < n; i++) { + for (CFIndex i = 0; i < n; i++) { CFDictionaryRef dict = CFArrayGetValueAtIndex(db_list, i); CFNumberRef t; CFNumberRef u; @@ -838,7 +866,7 @@ thinInterfaceInfo(CFDictionaryRef info) if (CFDictionaryGetValueIfPresent(info, CFSTR(kUSBVendorID), (const void **)&num) && isA_CFNumber(num) && CFNumberGetValue(num, kCFNumberIntType, &vid) - && (vid == kIOUSBVendorIDAppleComputer)) { + && (vid == kIOUSBAppleVendorID)) { CFMutableDictionaryRef thin; // if this is an Apple USB device than we trust that @@ -1245,86 +1273,109 @@ insertInterface(CFMutableArrayRef db_list, SCNetworkInterfaceRef interface, CFDi } static void -replaceInterface(SCNetworkInterfaceRef interface) +removeInterface(CFMutableArrayRef db_list, SCNetworkInterfaceRef interface, CFDictionaryRef *matched) { CFDictionaryRef db_dict; - CFDictionaryRef db_dict_match = NULL; int n = 0; CFIndex where; - if (S_dblist == NULL) { - S_dblist = CFArrayCreateMutable(NULL, 0, - &kCFTypeArrayCallBacks); - } - // remove any dict that has our type/addr while (TRUE) { - db_dict = lookupInterfaceByAddress(S_dblist, interface, &where); + db_dict = lookupInterfaceByAddress(db_list, interface, &where); if (db_dict == NULL) { break; } - if (db_dict_match == NULL) { - db_dict_match = CFRetain(db_dict); + if ((matched != NULL) && (*matched == NULL)) { + *matched = CFRetain(db_dict); } - CFArrayRemoveValueAtIndex(S_dblist, where); + CFArrayRemoveValueAtIndex(db_list, where); n++; } // remove any dict that has the same type/unit while (TRUE) { - db_dict = lookupInterfaceByUnit(S_dblist, interface, &where); + db_dict = lookupInterfaceByUnit(db_list, interface, &where); if (db_dict == NULL) { break; } - if (db_dict_match == NULL) { - db_dict_match = CFRetain(db_dict); + if ((matched != NULL) && (*matched == NULL)) { + *matched = CFRetain(db_dict); } - CFArrayRemoveValueAtIndex(S_dblist, where); + CFArrayRemoveValueAtIndex(db_list, where); n++; } - insertInterface(S_dblist, interface, db_dict_match); - if (db_dict_match != NULL) { - CFRelease(db_dict_match); + if (n > 1) { + SC_log(LOG_ERR, "Multiple interfaces removed from database (n = %d, %@)", n, interface); } - if (n > 1) { - SC_log(LOG_ERR, "Multiple interfaces updated (n = %d, %@)", n, interface); + return; +} + +static void +replaceInterface(SCNetworkInterfaceRef interface) +{ + CFDictionaryRef matched = NULL; + + if (S_dblist == NULL) { + S_dblist = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + } else { + // remove any matching interfaces + removeInterface(S_dblist, interface, &matched); + } + + // [re-]insert the new interface + insertInterface(S_dblist, interface, matched); + + if (matched != NULL) { + CFRelease(matched); } return; } -static CFNumberRef -getHighestUnitForType(CFNumberRef if_type) +static int +getNextUnitForType(CFNumberRef if_type, int requested) { - int i; - CFIndex n; - CFNumberRef ret_unit = NULL; + CFIndex n; if (S_dblist == NULL) { - return (NULL); + return requested; } n = CFArrayGetCount(S_dblist); - for (i = 0; i < n; i++) { + for (CFIndex i = 0; i < n; i++) { CFDictionaryRef dict = CFArrayGetValueAtIndex(S_dblist, i); CFNumberRef type; type = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceType)); if (CFEqual(type, if_type)) { + int u; CFNumberRef unit; unit = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceUnit)); - if (ret_unit == NULL - || (CFNumberCompare(unit, ret_unit, NULL) - == kCFCompareGreaterThan)) { - ret_unit = unit; + if (!isA_CFNumber(unit) || + !CFNumberGetValue(unit, kCFNumberIntType, &u)) { + u = 0; + } + + if (u < requested) { + // if we have not yet found our starting unit # + continue; + } + + if (u == requested) { + // our starting (or now proposed) unit # is "in use" so + // let's keep searching + requested++; + continue; } + + // we've found a unit # gap ... so let's re-assign it! } } - return (ret_unit); + return requested; } /* @@ -1619,13 +1670,35 @@ updateWatchedInterface(void *refCon, io_service_t service, natural_t messageType #pragma unused(messageArgument) switch (messageType) { case kIOMessageServiceIsTerminated : { // if [watched] interface yanked - CFDataRef watched = (CFDataRef)refCon; - WatchedInfo *watchedInfo = (WatchedInfo *)(void *)CFDataGetBytePtr(watched); + SCNetworkInterfaceRef remove = NULL; + CFDataRef watched = (CFDataRef)refCon; + WatchedInfo *watchedInfo = (WatchedInfo *)(void *)CFDataGetBytePtr(watched); + + remove = watchedInfo->interface; + if (!_SCNetworkInterfaceIsBuiltin(remove) && + _SCNetworkInterfaceIsApplePreconfigured(remove)) { + // if not built-in *and* pre-configured, retain for cleanup + CFRetain(remove); + } else { + remove = NULL; + } CFRetain(watched); watchedInfo->callback(watched, messageType, messageArgument); watcherRelease(watched); CFRelease(watched); + + if (remove != NULL) { + // if interface is not built-in *and* pre-configured + SC_log(LOG_INFO, "Interface released unit %@ (from database)", + _SCNetworkInterfaceGetIOInterfaceUnit(remove)); + removeInterface(S_dblist, remove, NULL); + CFRelease(remove); + + // update the DB with the [remaining] interfaces that have been named + writeInterfaceList(S_dblist); + } + break; } @@ -1714,6 +1787,24 @@ watcherRelease(CFDataRef watched) return; } +static Boolean +isWatchedInterface(CFArrayRef watchedInterfaces, SCNetworkInterfaceRef interface) +{ + CFIndex n; + + n = (watchedInterfaces != NULL) ? CFArrayGetCount(watchedInterfaces) : 0; + for (CFIndex i = 0; i < n; i++) { + CFDataRef watched = CFArrayGetValueAtIndex(watchedInterfaces, i); + WatchedInfo *watchedInfo = (WatchedInfo *)(void *)CFDataGetBytePtr(watched); + + if (CFEqual((watchedInfo->interface), interface)) { + return TRUE; + } + } + + return FALSE; +} + #pragma mark - #pragma mark Locked device support [macOS] @@ -2142,13 +2233,25 @@ watchLockedInterface(SCNetworkInterfaceRef interface) #if TARGET_OS_IPHONE + +#include +WEAK_LINK_FORCE_IMPORT(lockdown_is_host_trusted); +WEAK_LINK_FORCE_IMPORT(kLockdownNotificationHostAttached); +WEAK_LINK_FORCE_IMPORT(kLockdownNotificationHostDetached); +WEAK_LINK_FORCE_IMPORT(kLockdownNotificationTrustedHostAttached); +WEAK_LINK_FORCE_IMPORT(kLockdownNotificationTrustedPTPAttached); + static Boolean haveLockdown() { - void * volatile fn_WeakFunction = (void *)&(lockdown_is_host_trusted); Boolean haveLibrary; - haveLibrary = (fn_WeakFunction != NULL) ? TRUE : FALSE; + haveLibrary = ((lockdown_is_host_trusted != NULL) && + (&kLockdownNotificationHostAttached != NULL) && + (&kLockdownNotificationHostDetached != NULL) && + (&kLockdownNotificationTrustedHostAttached != NULL) && + (&kLockdownNotificationTrustedPTPAttached != NULL) + ); return haveLibrary; } @@ -2172,7 +2275,7 @@ shareExcluded() bsdName = SCNetworkInterfaceGetBSDName(watchedInfo->interface); if (bsdName == NULL) { - SC_log(LOG_NOTICE, "[trust required] excluded interface w/no BSD name"); + SC_log(LOG_NOTICE, "[trust required] interface w/no BSD name not excluded"); SC_log(LOG_NOTICE, " interface = %@", watchedInfo->interface); continue; } @@ -2323,26 +2426,6 @@ watchTrustedStatus(CFStringRef notification, CFStringRef reason) return; } -static Boolean -isWatchedInterface(SCNetworkInterfaceRef interface) -{ - Boolean found = FALSE; - CFIndex n; - - n = (S_trustRequired != NULL) ? CFArrayGetCount(S_trustRequired) : 0; - for (CFIndex i = 0; i < n; i++) { - CFDataRef watched = CFArrayGetValueAtIndex(S_trustRequired, i); - WatchedInfo *watchedInfo = (WatchedInfo *)(void *)CFDataGetBytePtr(watched); - - if (CFEqual((watchedInfo->interface), interface)) { - found = TRUE; - break; - } - } - - return found; -} - static void updateTrustRequiredInterfaces(CFArrayRef interfaces) { @@ -2354,13 +2437,21 @@ updateTrustRequiredInterfaces(CFArrayRef interfaces) SCNetworkInterfaceRef interface; interface = CFArrayGetValueAtIndex(interfaces, i); - if (_SCNetworkInterfaceIsTrustRequired(interface) && !isWatchedInterface(interface)) { + if (_SCNetworkInterfaceIsTrustRequired(interface) && + !isWatchedInterface(S_trustRequired, interface)) { CFDataRef watched; watched = watcherCreate(interface, trustRequiredInterfaceUpdated); if (watched != NULL) { - SC_log(LOG_INFO, "watching [trust required] interface: %@", - SCNetworkInterfaceGetBSDName(interface)); + CFStringRef bsdName; + + bsdName = SCNetworkInterfaceGetBSDName(interface); + if (bsdName != NULL) { + SC_log(LOG_INFO, "watching [trust required] interface: %@", bsdName); + } else { + SC_log(LOG_INFO, "watching [trust required] interface w/no BSD name"); + SC_log(LOG_INFO, " interface = %@", interface); + } if (S_trustRequired == NULL) { S_trustRequired = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); @@ -2426,6 +2517,11 @@ sharePreconfigured() WatchedInfo *watchedInfo = (WatchedInfo *)(void *)CFDataGetBytePtr(watched); bsdName = SCNetworkInterfaceGetBSDName(watchedInfo->interface); + if (bsdName == NULL) { + SC_log(LOG_NOTICE, "pre-configured interface w/no BSD name"); + SC_log(LOG_NOTICE, " interface = %@", watchedInfo->interface); + continue; + } CFArrayAppendValue(preconfigured, bsdName); } @@ -2449,8 +2545,15 @@ preconfiguredInterfaceUpdated(CFDataRef watched, natural_t messageType, void *me #pragma unused(messageArgument) switch (messageType) { case kIOMessageServiceIsTerminated : { // if [locked] interface yanked - SC_log(LOG_INFO, "[pre-configured] interface removed: %@", - SCNetworkInterfaceGetBSDName(watchedInfo->interface)); + CFStringRef bsdName; + + bsdName = SCNetworkInterfaceGetBSDName(watchedInfo->interface); + if (bsdName != NULL) { + SC_log(LOG_INFO, "[pre-configured] interface removed: %@", bsdName); + } else { + SC_log(LOG_INFO, "[pre-configured] interface w/no BSD name removed"); + SC_log(LOG_INFO, " interface = %@", watchedInfo->interface); + } if (S_preconfigured != NULL) { CFIndex i; @@ -2492,13 +2595,21 @@ updatePreConfiguredInterfaces(CFArrayRef interfaces) SCNetworkInterfaceRef interface; interface = CFArrayGetValueAtIndex(interfaces, i); - if (_SCNetworkInterfaceIsApplePreconfigured(interface)) { + if (_SCNetworkInterfaceIsApplePreconfigured(interface) && + !isWatchedInterface(S_preconfigured, interface)) { CFDataRef watched; watched = watcherCreate(interface, preconfiguredInterfaceUpdated); if (watched != NULL) { - SC_log(LOG_INFO, "watching [pre-configured] interface: %@", - SCNetworkInterfaceGetBSDName(interface)); + CFStringRef bsdName; + + bsdName = SCNetworkInterfaceGetBSDName(interface); + if (bsdName != NULL) { + SC_log(LOG_INFO, "watching [pre-configured] interface: %@", bsdName); + } else { + SC_log(LOG_INFO, "watching [pre-configured] interface w/no BSD name"); + SC_log(LOG_INFO, " interface = %@", interface); + } if (S_preconfigured == NULL) { S_preconfigured = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); @@ -2707,17 +2818,7 @@ nameInterfaces(CFMutableArrayRef if_list) // not built-in (or built-in unit not available), allocate from // the non-reserved slots next_unit = builtinCount(if_list, n, type); - - unit = getHighestUnitForType(type); - if (unit != NULL) { - int high_unit; - - CFNumberGetValue(unit, kCFNumberIntType, &high_unit); - if (high_unit >= next_unit) { - next_unit = high_unit + 1; - } - } - + next_unit = getNextUnitForType(type, next_unit); unit = CFNumberCreate(NULL, kCFNumberIntType, &next_unit); } @@ -2924,7 +3025,123 @@ updateNetworkConfiguration(CFArrayRef if_list) #endif // !TARGET_OS_IPHONE static void -updateInterfaces() +removeInactiveInterfaces(void) +{ + CFIndex n; + + /* + * remove any previous interfaces that were built-in, + * were active, and were hidden (pre-configured) that + * are no longer plugged in. + */ + + if ((S_dblist == NULL) || (S_prev_active_list == NULL)) { + return; + } + + n = CFArrayGetCount(S_prev_active_list); + for (CFIndex i = n - 1; i >= 0; i--) { + CFBooleanRef builtin; + CFBooleanRef hidden; + CFDictionaryRef if_dict; + CFDictionaryRef info; + CFStringRef name; + CFIndex where; + + if_dict = CFArrayGetValueAtIndex(S_prev_active_list, i); + + // Note: keep the following logic in sync with _SCNetworkInterfaceIsApplePreconfigured() + + name = CFDictionaryGetValue(if_dict, CFSTR(kIOBSDNameKey)); + if (!isA_CFString(name)) { + // if no BSD name + continue; + } + + hidden = CFDictionaryGetValue(if_dict, kSCNetworkInterfaceHiddenConfigurationKey); + if (!isA_CFBoolean(hidden) || !CFBooleanGetValue(hidden)) { + // if not hidden + continue; + } + + builtin = CFDictionaryGetValue(if_dict, CFSTR(kIOBuiltin)); + if (isA_CFBoolean(builtin) && CFBooleanGetValue(builtin)) { + // if [hidden] builtin + goto remove; + } + + info = CFDictionaryGetValue(if_dict, CFSTR(kSCNetworkInterfaceInfo)); + if (isA_CFDictionary(info)) { + int vid; + CFNumberRef vidNum; + + if (CFDictionaryGetValueIfPresent(info, CFSTR(kUSBVendorID), (const void **)&vidNum) && + isA_CFNumber(vidNum) && + CFNumberGetValue(vidNum, kCFNumberIntType, &vid) && + (vid == kIOUSBAppleVendorID)) { + // if [hidden] Apple interface + goto remove; + } + } + + continue; + + remove : + + SC_log(LOG_INFO, "Removing no-longer-active \"hidden\" interface: %@", name); + + if (lookupInterfaceByName(S_dblist, name, &where) != NULL) { + // remove from the list of interfaces we know about + CFArrayRemoveValueAtIndex(S_dblist, where); + // remove from the previously active list + CFArrayRemoveValueAtIndex(S_prev_active_list, i); + } + } + + return; +} + +static void +reportInactiveInterfaces(void) +{ + CFIndex n; + + /* + * report any previous interfaces that are not [yet] active + */ + + if (S_prev_active_list == NULL) { + return; + } + + n = CFArrayGetCount(S_prev_active_list); + if (n > 0) { + SC_log(LOG_INFO, "Interface%s not [yet] active", + (n > 1) ? "s" : ""); + } + for (CFIndex i = 0; i < n; i++) { + CFDictionaryRef if_dict; + CFStringRef name; + CFNumberRef type; + CFNumberRef unit; + + if_dict = CFArrayGetValueAtIndex(S_prev_active_list, i); + name = CFDictionaryGetValue(if_dict, CFSTR(kIOBSDNameKey)); + type = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceType)); + unit = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceUnit)); + SC_log(LOG_INFO, " %s%@%sType: %@, Unit: %@", + (name != NULL) ? "BSD Name: " : "", + (name != NULL) ? name : CFSTR(""), + (name != NULL) ? ", " : "", + type, + unit); + } + + return; +} + +static void +updateInterfaces(void) { if (S_connect == MACH_PORT_NULL) { // if we don't have the "IONetworkStack" connect object @@ -2957,14 +3174,16 @@ updateInterfaces() if (isQuiet()) { /* - * The registry [matching] has quiesced so let's - * - save the DB with the interfaces that have been named - * - update the VLAN/BOND configuration - * - tell everyone that we've finished (at least for now) - * - log those interfaces which are no longer present - * in the HW config (or have yet to show up). + * The registry [matching] has quiesced */ + + // remove any inactive interfaces + removeInactiveInterfaces(); + + // save the DB with the interfaces that have been named writeInterfaceList(S_dblist); + + // update the VLAN/BOND configuration updateVirtualNetworkInterfaceConfiguration(NULL, kSCPreferencesNotificationApply, NULL); #if !TARGET_OS_IPHONE @@ -2978,43 +3197,22 @@ updateInterfaces() } #endif // !TARGET_OS_IPHONE + // tell everyone that we've finished (at least for now) updateStore(); - if (S_iflist != NULL) { - CFRelease(S_iflist); - S_iflist = NULL; - } + // log those interfaces which are no longer present in + // the HW config (or have yet to show up). + reportInactiveInterfaces(); if (S_prev_active_list != NULL) { - CFIndex i; - CFIndex n; - - n = CFArrayGetCount(S_prev_active_list); - if (n > 0) { - SC_log(LOG_INFO, "Interface%s not [yet] active", - (n > 1) ? "s" : ""); - } - for (i = 0; i < n; i++) { - CFDictionaryRef if_dict; - CFStringRef name; - CFNumberRef type; - CFNumberRef unit; - - if_dict = CFArrayGetValueAtIndex(S_prev_active_list, i); - name = CFDictionaryGetValue(if_dict, CFSTR(kIOBSDNameKey)); - type = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceType)); - unit = CFDictionaryGetValue(if_dict, CFSTR(kIOInterfaceUnit)); - SC_log(LOG_INFO, " %s%@%sType: %@, Unit: %@", - (name != NULL) ? "BSD Name: " : "", - (name != NULL) ? name : CFSTR(""), - (name != NULL) ? ", " : "", - type, - unit); - } - CFRelease(S_prev_active_list); S_prev_active_list = NULL; } + + if (S_iflist != NULL) { + CFRelease(S_iflist); + S_iflist = NULL; + } } else { if ((S_prev_active_list != NULL) && (CFArrayGetCount(S_prev_active_list) == 0)) { /* @@ -3607,11 +3805,15 @@ load_InterfaceNamer(CFBundleRef bundle, Boolean bundleVerbose) //------------------------------------------------------------------------ // Main function. -#ifdef MAIN +#ifdef TEST_INTERFACE_ASSIGNMENT int main(int argc, char ** argv) { - CFBundleRef bundle; +#pragma unused(argv) + CFBundleRef bundle; + CFMutableArrayRef interfaces; + CFArrayRef interfaces_all; + CFIndex n; _sc_log = FALSE; _sc_verbose = (argc > 1) ? TRUE : FALSE; @@ -3619,9 +3821,41 @@ main(int argc, char ** argv) bundle = CFBundleGetMainBundle(); CFRetain(bundle); // released in exec_InterfaceNamer - (void)exec_InterfaceNamer(); + // setup + setup_IOKit(bundle); + + // but, when running this test we know that the IORegistry has already quiesced + IOObjectRelease(S_quiet); + S_quiet = MACH_PORT_NULL; + + // collect the interfaces + interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + interfaces_all = SCNetworkInterfaceCopyAll(); + n = CFArrayGetCount(interfaces_all); + for (CFIndex i = 0; i < n; i++) { + SCNetworkInterfaceRef interface = CFArrayGetValueAtIndex(interfaces_all, i); + SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + + if (interfacePrivate->type == NULL) { + // skip interfaces with a kIOInterfaceType property + continue; + } + + if (interfacePrivate->unit != NULL) { + // remove any already assigned unit # + CFRelease(interfacePrivate->unit); + interfacePrivate->unit = NULL; + } + + CFArrayAppendValue(interfaces, interface); + } + CFRelease(interfaces_all); + SC_log(LOG_INFO, "interfaces = %@", interfaces); + + // exercise the interface naming assignments + nameInterfaces(interfaces); + CFRelease(interfaces); - /* not reached */ exit(0); return 0; } @@ -3631,14 +3865,10 @@ main(int argc, char ** argv) int main(int argc, char ** argv) { - CFStringRef snapshot; - _sc_log = FALSE; _sc_verbose = (argc > 1) ? TRUE : FALSE; - snapshot = captureBusy(); - SCPrint(TRUE, stdout, CFSTR("%@\n"), snapshot); - CFRelease(snapshot); + captureBusy(); exit(0); return 0; diff --git a/Plugins/PreferencesMonitor/prefsmon.c b/Plugins/PreferencesMonitor/prefsmon.c index 23d69a5..db757db 100644 --- a/Plugins/PreferencesMonitor/prefsmon.c +++ b/Plugins/PreferencesMonitor/prefsmon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008, 2010, 2012-2019 Apple Inc. All rights reserved. + * Copyright (c) 2000-2008, 2010, 2012-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -36,24 +36,18 @@ #include -#include -#include #include -#include #include - #define SC_LOG_HANDLE __log_PreferencesMonitor #define SC_LOG_HANDLE_TYPE static #include #include #include +#include "SCNetworkConfigurationInternal.h" #include "plugin_shared.h" -#include - - /* globals */ static SCPreferencesRef prefs = NULL; static SCDynamicStoreRef store = NULL; @@ -61,7 +55,7 @@ static SCDynamicStoreRef store = NULL; /* InterfaceNamer[.plugin] monitoring globals */ static CFMutableArrayRef excluded_interfaces = NULL; // of SCNetworkInterfaceRef static CFMutableArrayRef excluded_names = NULL; // of CFStringRef (BSD name) -Boolean haveConfiguration = FALSE; +static Boolean haveConfiguration = FALSE; static CFStringRef namerKey = NULL; static CFMutableArrayRef preconfigured_interfaces= NULL; // of SCNetworkInterfaceRef static CFMutableArrayRef preconfigured_names = NULL; // of CFStringRef (BSD name) @@ -76,7 +70,6 @@ static CFMutableArrayRef unchangedPrefsKeys; /* new prefs keys which match curre static CFMutableArrayRef removedPrefsKeys; /* old prefs keys to be removed */ static Boolean rofs = FALSE; -static Boolean restorePrefs = FALSE; #define MY_PLUGIN_NAME "PreferencesMonitor" #define MY_PLUGIN_ID CFSTR("com.apple.SystemConfiguration." MY_PLUGIN_NAME) @@ -101,116 +94,37 @@ __log_PreferencesMonitor(void) } -static Boolean -restorePreferences() +static void +savePastConfiguration(CFStringRef old_model) { - Boolean ok = FALSE; - CFStringRef currentModel = NULL; - CFMutableStringRef modelPrefixStr = NULL; - CFArrayRef keyList = NULL; - CFIndex keyListCount; - CFIndex idx; - Boolean modified = FALSE; - int sc_status = kSCStatusFailed; - - while (TRUE) { - ok = SCPreferencesLock(prefs, TRUE); - if (ok) { - break; - } + CFDictionaryRef system; - sc_status = SCError(); - if (sc_status == kSCStatusStale) { - SCPreferencesSynchronize(prefs); - } else { - SC_log(LOG_NOTICE, "Could not acquire network configuration lock: %s", - SCErrorString(sc_status)); - return FALSE; - } + // save "/System" (e.g. host names) + system = SCPreferencesGetValue(prefs, kSCPrefSystem); + if (system != NULL) { + CFRetain(system); } - keyList = SCPreferencesCopyKeyList(prefs); - if (keyList == NULL) { - goto error; - } + // save the [previous devices] configuration + __SCNetworkConfigurationSaveModel(prefs, old_model); - currentModel = _SC_hw_model(FALSE); - if (currentModel == NULL) { - goto error; + if (system != NULL) { + // and retain "/System" (e.g. host names) + SCPreferencesSetValue(prefs, kSCPrefSystem, system); + CFRelease(system); } - /* Create "model:" string for prefix-check */ - modelPrefixStr = CFStringCreateMutableCopy(NULL, 0, currentModel); - CFStringAppend(modelPrefixStr, CFSTR(":")); - - keyListCount = CFArrayGetCount(keyList); - for (idx = 0; idx < keyListCount; idx++) { - CFStringRef existingKey = CFArrayGetValueAtIndex(keyList, idx); - CFStringRef key; - CFArrayRef splitKey = NULL; - CFPropertyListRef value; - - if (isA_CFString(existingKey) == NULL) { - continue; - } - - if (!CFStringHasPrefix(existingKey, modelPrefixStr)) { - continue; - } - - splitKey = CFStringCreateArrayBySeparatingStrings(NULL, existingKey, CFSTR(":")); - key = CFArrayGetValueAtIndex(splitKey, 1); - value = SCPreferencesGetValue(prefs, existingKey); - SCPreferencesSetValue(prefs, key, value); - SCPreferencesRemoveValue(prefs, existingKey); - modified = TRUE; - CFRelease(splitKey); - } - - if (modified) { - SCPreferencesRef ni_prefs = NULL; - ni_prefs = SCPreferencesCreate(NULL, MY_PLUGIN_ID, CFSTR("NetworkInterfaces.plist")); - if (ni_prefs == NULL) { - goto error; - } - - ok = _SCNetworkConfigurationCheckValidityWithPreferences(prefs, ni_prefs, NULL); - CFRelease(ni_prefs); - - //Commit the changes only if prefs files valid - if (ok) { - if (!SCPreferencesCommitChanges(prefs)) { - if (SCError() != EROFS) { - SC_log(LOG_NOTICE, "SCPreferencesCommitChanges() failed: %s", - SCErrorString(SCError())); - } - goto error; - - } - - (void) SCPreferencesApplyChanges(prefs); - } - } - -error: - (void) SCPreferencesUnlock(prefs); - - if (keyList != NULL) { - CFRelease(keyList); - } - if (modelPrefixStr != NULL) { - CFRelease(modelPrefixStr); - } - - return modified; + return; } + static Boolean establishNewPreferences() { SCNetworkSetRef current = NULL; CFStringRef new_model; Boolean ok = FALSE; + CFStringRef old_model; int sc_status = kSCStatusFailed; SCNetworkSetRef set = NULL; Boolean updated = FALSE; @@ -231,58 +145,18 @@ establishNewPreferences() } } - /* Ensure that the preferences has the new model */ + // check if we need to regenerate the configuration for a new model + old_model = SCPreferencesGetValue(prefs, MODEL); new_model = _SC_hw_model(FALSE); - - /* Need to regenerate the new configuration for new model */ - if (new_model != NULL) { - CFStringRef old_model; - - old_model = SCPreferencesGetValue(prefs, MODEL); - if ((old_model != NULL) && !_SC_CFEqual(old_model, new_model)) { - CFIndex count; - CFIndex index; - CFArrayRef keys; - - keys = SCPreferencesCopyKeyList(prefs); - count = (keys != NULL) ? CFArrayGetCount(keys) : 0; - // if new hardware - for (index = 0; index < count; index++) { - CFStringRef existing_key; - - existing_key = CFArrayGetValueAtIndex(keys, index); - if (isA_CFString(existing_key) != NULL) { - CFStringRef new_key; - CFPropertyListRef value; - - /* If it already contains a Model - or if it already contains a MODEL:KEY key skip it*/ - if (CFEqual(existing_key, MODEL) - || CFStringFind(existing_key, CFSTR(":"), 0).location - != kCFNotFound) { - continue; - } - - value = SCPreferencesGetValue(prefs, existing_key); - - /* Create a new key as OLD_MODEL:OLD_KEY */ - new_key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:%@"), - old_model, existing_key); - SCPreferencesSetValue(prefs, new_key, value); - if (!CFEqual(existing_key, kSCPrefSystem)) { - /* preserve existing host names */ - SCPreferencesRemoveValue(prefs, existing_key); - } - CFRelease(new_key); - } - } - - if (keys != NULL) { - CFRelease(keys); - } - } - /* Set the new model */ - SCPreferencesSetValue(prefs, MODEL, new_model); + if ((old_model != NULL) && !_SC_CFEqual(old_model, new_model)) { + SC_log(LOG_NOTICE, "Hardware model changed\n" + " created on \"%@\"\n" + " now on \"%@\"", + old_model, + new_model); + + // save (and clean) the configuration that was created for "other" hardware + savePastConfiguration(old_model); } current = SCNetworkSetCopyCurrent(prefs); @@ -389,27 +263,6 @@ watchSCDynamicStore() } -static Boolean -previousConfigurationAvailable() -{ - CFStringRef backupKey = NULL; - CFStringRef currentModel = NULL; - CFPropertyListRef properties = NULL; - - currentModel = _SC_hw_model(FALSE); - if (currentModel == NULL) { - goto done; - } - - /* Currently relying only if a backup of "Sets" is present */ - backupKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:Sets"), currentModel); - properties = SCPreferencesGetValue(prefs, backupKey); - CFRelease(backupKey); -done: - return (properties != NULL); -} - - static Boolean findInterfaces(CFArrayRef interfaces, CFMutableArrayRef *matched_interfaces, CFMutableArrayRef *matched_names) { @@ -571,11 +424,6 @@ storeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) (void) establishNewPreferences(); - if (restorePrefs) { - (void) restorePreferences(); - restorePrefs = FALSE; - } - if (timeout && (logged++ == 0)) { SC_log(LOG_ERR, "Network configuration creation timed out waiting for IORegistry"); } @@ -715,42 +563,6 @@ flatten(SCPreferencesRef prefs, } -static CF_RETURNS_RETAINED CFStringRef -copyInterfaceUUID(CFStringRef bsdName) -{ - union { - unsigned char sha256_bytes[CC_SHA256_DIGEST_LENGTH]; - CFUUIDBytes uuid_bytes; - } bytes; - CC_SHA256_CTX ctx; - char if_name[IF_NAMESIZE]; - CFUUIDRef uuid; - CFStringRef uuid_str; - - // start with interface name - memset(&if_name, 0, sizeof(if_name)); - (void) _SC_cfstring_to_cstring(bsdName, - if_name, - sizeof(if_name), - kCFStringEncodingASCII); - - // create SHA256 hash - memset(&bytes, 0, sizeof(bytes)); - CC_SHA256_Init(&ctx); - CC_SHA256_Update(&ctx, - if_name, - sizeof(if_name)); - CC_SHA256_Final(bytes.sha256_bytes, &ctx); - - // create UUID string - uuid = CFUUIDCreateFromUUIDBytes(NULL, bytes.uuid_bytes); - uuid_str = CFUUIDCreateString(NULL, uuid); - CFRelease(uuid); - - return uuid_str; -} - - static void excludeConfigurations(SCPreferencesRef prefs) { @@ -908,42 +720,12 @@ updatePreConfiguredConfiguration(SCPreferencesRef prefs) CFStringRef bsdName; SCNetworkInterfaceRef interface = CFArrayGetValueAtIndex(preconfigured_interfaces, i); SCNetworkServiceRef service; - CFStringRef serviceID; bsdName = SCNetworkInterfaceGetBSDName(interface); // create network service - service = SCNetworkServiceCreate(prefs, interface); + service = _SCNetworkServiceCreatePreconfigured(prefs, interface); if (service == NULL) { - SC_log(LOG_ERR, "could not create network service for \"%@\": %s", - bsdName, - SCErrorString(SCError())); - continue; - } - - // update network service to use a consistent serviceID - serviceID = copyInterfaceUUID(bsdName); - if (serviceID != NULL) { - ok = _SCNetworkServiceSetServiceID(service, serviceID); - CFRelease(serviceID); - if (!ok) { - SC_log(LOG_ERR, "_SCNetworkServiceSetServiceID() failed: %s", - SCErrorString(SCError())); - // ... and keep whatever random UUID was created for the service - } - } else { - SC_log(LOG_ERR, "could not create serviceID for \"%@\"", bsdName); - // ... and we'll use whatever random UUID was created for the service - } - - // establish [template] configuration - ok = SCNetworkServiceEstablishDefaultConfiguration(service); - if (!ok) { - SC_log(LOG_ERR, "could not establish network service for \"%@\": %s", - bsdName, - SCErrorString(SCError())); - SCNetworkServiceRemove(service); - CFRelease(service); continue; } @@ -1215,6 +997,13 @@ prime_PreferencesMonitor() } +#ifndef MAIN +#define PREFERENCES_MONITOR_PLIST NULL +#else // !MAIN +#define PREFERENCES_MONITOR_PLIST CFSTR("/tmp/preferences.plist") +#endif // !MAIN + + __private_extern__ void load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose) @@ -1235,27 +1024,34 @@ load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose) } /* open a SCPreferences session */ -#ifndef MAIN - prefs = SCPreferencesCreate(NULL, CFSTR("PreferencesMonitor.bundle"), NULL); -#else // !MAIN - prefs = SCPreferencesCreate(NULL, CFSTR("PreferencesMonitor.bundle"), CFSTR("/tmp/preferences.plist")); -#endif // !MAIN + prefs = SCPreferencesCreateWithOptions(NULL, + MY_PLUGIN_ID, + PREFERENCES_MONITOR_PLIST, + NULL, // authorization + NULL); if (prefs != NULL) { Boolean need_update = FALSE; - CFStringRef new_model; + CFStringRef new_model; + CFStringRef old_model; + + // check if we need to update the configuration + __SCNetworkConfigurationUpgrade(&prefs, NULL, TRUE); + // check if we need to regenerate the configuration for a new model + old_model = SCPreferencesGetValue(prefs, MODEL); new_model = _SC_hw_model(FALSE); + if ((old_model != NULL) && !_SC_CFEqual(old_model, new_model)) { + SC_log(LOG_NOTICE, "Hardware model changed\n" + " created on \"%@\"\n" + " now on \"%@\"", + old_model, + new_model); - /* Need to regenerate the new configuration for new model */ - if (new_model != NULL) { - CFStringRef old_model; + // save (and clean) the configuration that was created for "other" hardware + savePastConfiguration(old_model); - old_model = SCPreferencesGetValue(prefs, MODEL); - if (old_model != NULL && !_SC_CFEqual(old_model, new_model)) { - // if new hardware - need_update = TRUE; - restorePrefs = previousConfigurationAvailable(); - } + // ... and we'll update the configuration later (when the IORegistry quiesces) + need_update = TRUE; } if (!need_update) { diff --git a/SystemConfiguration.fproj/SCD.c b/SystemConfiguration.fproj/SCD.c index 3fc0dc0..74a6777 100644 --- a/SystemConfiguration.fproj/SCD.c +++ b/SystemConfiguration.fproj/SCD.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008, 2010-2019 Apple Inc. All rights reserved. + * Copyright (c) 2000-2008, 2010-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -48,9 +48,10 @@ /* framework variables */ int _sc_debug = FALSE; /* non-zero if debugging enabled */ int _sc_verbose = FALSE; /* non-zero if verbose logging enabled */ -int _sc_log = TRUE; /* 0 if SC messages should be written to stdout/stderr, - 1 if SC messages should be logged w/os_log(3), - 2 if SC messages should be written to stdout/stderr AND logged */ +int _sc_log = 1; /* 0 if SC messages should be written to stdout/stderr, + 1 if SC messages should be logged w/os_log(3), + 2 if SC messages should be logged AND written to stdout/stderr + 3 if SC messages should be logged AND written to stdout/stderr (w/o timestamp) */ #pragma mark - @@ -504,6 +505,7 @@ __SC_Log(int level, CFStringRef format_CF, os_log_t log, os_log_type_t type, con * 0 if SC messages should be written to stdout/stderr * 1 if SC messages should be logged w/os_log(3) * 2 if SC messages should be written to stdout/stderr AND logged + * 3 if SC messages should be logged AND written to stdout/stderr (w/o timestamp) */ if (_sc_log > 0) { @@ -532,7 +534,7 @@ __SC_Log(int level, CFStringRef format_CF, os_log_t log, os_log_type_t type, con __SCPrint(stdout, format_CF, args_print, - (_sc_log > 0), // trace + (_sc_log == 2), // trace TRUE); // add newline va_end(args_print); } @@ -559,6 +561,7 @@ SCLog(Boolean condition, int level, CFStringRef formatString, ...) * 0 if SC messages should be written to stdout/stderr * 1 if SC messages should be logged w/os_log(3) * 2 if SC messages should be written to stdout/stderr AND logged + * 3 if SC messages should be logged AND written to stdout/stderr (w/o timestamp) */ if (_sc_log > 0) { @@ -591,7 +594,7 @@ SCLog(Boolean condition, int level, CFStringRef formatString, ...) __SCPrint((LOG_PRI(level) > LOG_NOTICE) ? stderr : stdout, formatString, formatArguments_print, - (_sc_log > 0), // trace + (_sc_log == 2), // trace TRUE); // add newline va_end(formatArguments_print); } diff --git a/SystemConfiguration.fproj/SCDHostName.c b/SystemConfiguration.fproj/SCDHostName.c index 7fabbb6..8c047e1 100644 --- a/SystemConfiguration.fproj/SCDHostName.c +++ b/SystemConfiguration.fproj/SCDHostName.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008, 2011, 2013-2018 Apple Inc. All rights reserved. + * Copyright (c) 2000-2008, 2011, 2013-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -35,6 +35,7 @@ #include #include // for __CFStringGetUserDefaultEncoding #include "SCPreferencesInternal.h" +#include "SCNetworkConfigurationInternal.h" #include "dy_framework.h" @@ -227,12 +228,7 @@ SCPreferencesSetComputerName(SCPreferencesRef prefs, CFDictionaryRemoveValue(newDict, kSCPropSystemComputerNameRegion); } - if (CFDictionaryGetCount(newDict) > 0) { - ok = SCPreferencesPathSetValue(prefs, path, newDict); - } else { - ok = SCPreferencesPathRemoveValue(prefs, path); - } - + ok = __SCNetworkConfigurationSetValue(prefs, path, newDict, FALSE); if (ok) { if (name != NULL) { SC_log(LOG_NOTICE, "attempting to set the computer name to \"%@\"", name); @@ -327,12 +323,7 @@ SCPreferencesSetHostName(SCPreferencesRef prefs, CFDictionaryRemoveValue(newDict, kSCPropSystemHostName); } - if (CFDictionaryGetCount(newDict) > 0) { - ok = SCPreferencesPathSetValue(prefs, path, newDict); - } else { - ok = SCPreferencesPathRemoveValue(prefs, path); - } - + ok = __SCNetworkConfigurationSetValue(prefs, path, newDict, FALSE); if (ok) { if (name != NULL) { SC_log(LOG_NOTICE, "attempting to set the host name to \"%@\"", name); @@ -571,12 +562,7 @@ SCPreferencesSetLocalHostName(SCPreferencesRef prefs, CFDictionaryRemoveValue(newDict, kSCPropNetLocalHostName); } - if (CFDictionaryGetCount(newDict) > 0) { - ok = SCPreferencesPathSetValue(prefs, path, newDict); - } else { - ok = SCPreferencesPathRemoveValue(prefs, path); - } - + ok = __SCNetworkConfigurationSetValue(prefs, path, newDict, FALSE); if (ok) { if (name != NULL) { SC_log(LOG_NOTICE, "attempting to set the local host name to \"%@\"", name); diff --git a/SystemConfiguration.fproj/SCDOpen.c b/SystemConfiguration.fproj/SCDOpen.c index d43a2a1..7ef633b 100644 --- a/SystemConfiguration.fproj/SCDOpen.c +++ b/SystemConfiguration.fproj/SCDOpen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2006, 2008-2019 Apple Inc. All rights reserved. + * Copyright (c) 2000-2006, 2008-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -44,7 +44,6 @@ #include "config.h" /* MiG generated file */ #include "SCD.h" -static CFStringRef _sc_bundleID = NULL; static pthread_mutex_t _sc_lock = PTHREAD_MUTEX_INITIALIZER; static mach_port_t _sc_server = MACH_PORT_NULL; static unsigned int _sc_store_cnt = 0; @@ -222,38 +221,12 @@ static pthread_once_t initialized = PTHREAD_ONCE_INIT; static void __SCDynamicStoreInitialize(void) { - CFBundleRef bundle; - /* register with CoreFoundation */ __kSCDynamicStoreTypeID = _CFRuntimeRegisterClass(&__SCDynamicStoreClass); /* add handler to cleanup after fork() */ (void) pthread_atfork(NULL, NULL, childForkHandler); - /* get the application/executable/bundle name */ - bundle = CFBundleGetMainBundle(); - if (bundle != NULL) { - _sc_bundleID = CFBundleGetIdentifier(bundle); - if (_sc_bundleID != NULL) { - CFRetain(_sc_bundleID); - } else { - CFURLRef url; - - url = CFBundleCopyExecutableURL(bundle); - if (url != NULL) { - _sc_bundleID = CFURLCopyPath(url); - CFRelease(url); - } - } - - if (_sc_bundleID != NULL) { - if (CFEqual(_sc_bundleID, CFSTR("/"))) { - CFRelease(_sc_bundleID); - _sc_bundleID = CFStringCreateWithFormat(NULL, NULL, CFSTR("(%d)"), getpid()); - } - } - } - return; } @@ -805,11 +778,7 @@ SCDynamicStoreCreateWithOptions(CFAllocatorRef allocator, } // set "name" - if (_sc_bundleID != NULL) { - storePrivate->name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:%@"), _sc_bundleID, name); - } else { - storePrivate->name = CFRetain(name); - } + storePrivate->name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:%@"), _SC_getApplicationBundleID(), name); // set "options" diff --git a/SystemConfiguration.fproj/SCDPrivate.c b/SystemConfiguration.fproj/SCDPrivate.c index 485d122..b48c76b 100644 --- a/SystemConfiguration.fproj/SCDPrivate.c +++ b/SystemConfiguration.fproj/SCDPrivate.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2019 Apple Inc. All rights reserved. + * Copyright (c) 2000-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -917,6 +917,46 @@ _SC_unschedule(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode, CFM #pragma mark Bundle +CFStringRef +_SC_getApplicationBundleID(void) +{ + static CFStringRef bundleID = NULL; + static dispatch_once_t once; + + dispatch_once(&once, ^{ + CFBundleRef bundle; + + bundle = CFBundleGetMainBundle(); + if (bundle != NULL) { + bundleID = CFBundleGetIdentifier(bundle); + if (bundleID != NULL) { + CFRetain(bundleID); + } else { + CFURLRef url; + + url = CFBundleCopyExecutableURL(bundle); + if (url != NULL) { + bundleID = CFURLCopyPath(url); + CFRelease(url); + } + } + + if (bundleID != NULL) { + if (CFEqual(bundleID, CFSTR("/"))) { + CFRelease(bundleID); + bundleID = NULL; + } + } + } + if (bundleID == NULL) { + bundleID = CFStringCreateWithFormat(NULL, NULL, CFSTR("Unknown(%d)"), getpid()); + } + }); + + return bundleID; +} + + #define SYSTEMCONFIGURATION_BUNDLE_ID CFSTR("com.apple.SystemConfiguration") #define SYSTEMCONFIGURATION_FRAMEWORK_PATH_LEN (sizeof(SYSTEMCONFIGURATION_FRAMEWORK_PATH) - 1) diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c index c8db81e..d64b6df 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c +++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2007, 2009, 2010-2013, 2015-2018 Apple Inc. All rights reserved. + * Copyright (c) 2004-2007, 2009, 2010-2013, 2015-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -29,8 +29,8 @@ */ -#include "SCPreferencesInternal.h" #include "SCNetworkConfigurationInternal.h" +#include "SCPreferencesInternal.h" #include #include @@ -49,40 +49,54 @@ __log_SCNetworkConfiguration(void) } -__private_extern__ CFDictionaryRef -__getPrefsConfiguration(SCPreferencesRef prefs, CFStringRef path) +static Boolean +isEffectivelyEmptyConfiguration(CFDictionaryRef config) { - CFDictionaryRef config; + Boolean empty = FALSE; CFIndex n; - config = SCPreferencesPathGetValue(prefs, path); - n = isA_CFDictionary(config) ? CFDictionaryGetCount(config) : 0; switch (n) { case 0 : - // ignore empty configuration entities - config = NULL; + // if no keys + empty = TRUE; break; case 1 : if (CFDictionaryContainsKey(config, kSCResvInactive)) { // ignore [effectively] empty configuration entities - config = NULL; + empty = TRUE; } break; default : break; } + return empty; +} + + +__private_extern__ CFDictionaryRef +__SCNetworkConfigurationGetValue(SCPreferencesRef prefs, CFStringRef path) +{ + CFDictionaryRef config; + + config = SCPreferencesPathGetValue(prefs, path); + if (isEffectivelyEmptyConfiguration(config)) { + // ignore [effectively] empty configuration entities + config = NULL; + } + return config; } __private_extern__ Boolean -__setPrefsConfiguration(SCPreferencesRef prefs, - CFStringRef path, - CFDictionaryRef config, - Boolean keepInactive) +__SCNetworkConfigurationSetValue(SCPreferencesRef prefs, + CFStringRef path, + CFDictionaryRef config, + Boolean keepInactive) { + Boolean changed; CFDictionaryRef curConfig; CFMutableDictionaryRef newConfig = NULL; Boolean ok; @@ -93,6 +107,7 @@ __setPrefsConfiguration(SCPreferencesRef prefs, } curConfig = SCPreferencesPathGetValue(prefs, path); + curConfig = isA_CFDictionary(curConfig); if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); @@ -115,16 +130,20 @@ __setPrefsConfiguration(SCPreferencesRef prefs, } } + // check if the configuration changed + changed = !_SC_CFEqual(curConfig, newConfig); + // set new configuration - if (_SC_CFEqual(curConfig, newConfig)) { + if (!changed) { // if no change if (newConfig != NULL) CFRelease(newConfig); ok = TRUE; } else if (newConfig != NULL) { - // if new configuration (or we are preserving a disabled state) + // if new configuration (or we are preserving a disabled state), update the prefs ok = SCPreferencesPathSetValue(prefs, path, newConfig); CFRelease(newConfig); } else { + // update the prefs ok = SCPreferencesPathRemoveValue(prefs, path); if (!ok && (SCError() == kSCStatusNoKey)) { ok = TRUE; @@ -154,9 +173,10 @@ __setPrefsEnabled(SCPreferencesRef prefs, CFStringRef path, Boolean enabled) { - CFDictionaryRef curConfig; - CFMutableDictionaryRef newConfig = NULL; - Boolean ok = FALSE; + Boolean changed; + CFDictionaryRef curConfig; + CFMutableDictionaryRef newConfig = NULL; + Boolean ok = FALSE; // preserve current configuration curConfig = SCPreferencesPathGetValue(prefs, path); @@ -182,13 +202,17 @@ __setPrefsEnabled(SCPreferencesRef prefs, } } + // check if the configuration changed + changed = !_SC_CFEqual(curConfig, newConfig); + // set new configuration - if (_SC_CFEqual(curConfig, newConfig)) { + if (!changed) { // if no change if (newConfig != NULL) CFRelease(newConfig); ok = TRUE; } else if (newConfig != NULL) { // if updated configuration (or we are establishing as disabled) + ok = SCPreferencesPathSetValue(prefs, path, newConfig); CFRelease(newConfig); } else { @@ -671,3 +695,48 @@ __str_to_rank(CFStringRef rankStr, SCNetworkServicePrimaryRank *rank) return TRUE; } + + +#define kSCNetworkConfigurationFlagsBypassSystemInterfaces (1<<0) +#define kSCNetworkConfigurationFlagsBypassSystemInterfacesForced (1<<1) + + +Boolean +_SCNetworkConfigurationBypassSystemInterfaces(SCPreferencesRef prefs) +{ + Boolean bypass; + uint32_t nc_flags; + + nc_flags = __SCPreferencesGetNetworkConfigurationFlags(prefs); + bypass = ((nc_flags & kSCNetworkConfigurationFlagsBypassSystemInterfaces) != 0); + if (bypass || + (nc_flags & kSCNetworkConfigurationFlagsBypassSystemInterfacesForced) != 0) { + // if bypass flag explicitly requested + return bypass; + } + + if (!__SCPreferencesUsingDefaultPrefs(prefs)) { + // if not using the default prefs (i.e. /L/P/SC/preferences.plist) + return TRUE; + } + + return FALSE; +} + + +void +_SCNetworkConfigurationSetBypassSystemInterfaces(SCPreferencesRef prefs, Boolean shouldBypass) +{ + uint32_t nc_flags; + + nc_flags = __SCPreferencesGetNetworkConfigurationFlags(prefs); + if (shouldBypass) { + nc_flags |= kSCNetworkConfigurationFlagsBypassSystemInterfaces; + } else { + nc_flags &= ~kSCNetworkConfigurationFlagsBypassSystemInterfaces; + } + nc_flags |= kSCNetworkConfigurationFlagsBypassSystemInterfacesForced; + __SCPreferencesSetNetworkConfigurationFlags(prefs, nc_flags); + + return; +} diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h index dc2f7bc..9470344 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h +++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2018 Apple Inc. All rights reserved. + * Copyright (c) 2004-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -39,6 +39,9 @@ #include +#define NETWORK_CONFIGURATION_VERSION 20191120 + + typedef struct { // base CFType information @@ -166,6 +169,7 @@ typedef struct { } usb; // misc + CFArrayRef matchingMACs; unsigned int sort_order; // sort order for this interface // for BOND interfaces @@ -199,10 +203,18 @@ typedef struct { __BEGIN_DECLS +#pragma mark - +#pragma mark SCNetworkConfiguration (internal) + + +Boolean +__SCNetworkConfigurationBackup (SCPreferencesRef prefs) SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0)); + #pragma mark - #pragma mark SCNetworkInterface configuration (internal) + Boolean __SCNetworkInterfaceMatchesName (CFStringRef name, CFStringRef key); @@ -210,17 +222,6 @@ __SCNetworkInterfaceMatchesName (CFStringRef name, CFArrayRef __SCNetworkInterfaceCopyAll_IONetworkInterface (Boolean keep_pre_configured); -/*! - @function __SCNetworkInterfaceCopyStorageEntity - @discussion Create interface entity of network interface as seen in - NetworkInterfaces.plist - @param interface The network interface from which interface entity is create - @result Dictionary which contains information about interface entity - You must release the returned value. - */ -CFDictionaryRef -__SCNetworkInterfaceCopyStorageEntity (SCNetworkInterfaceRef interface); - /*! @function __SCNetworkInterfaceCopyStoredWithPreferences @discussion Create an array of network interfaces, which is present in the preferences @@ -371,7 +372,6 @@ __SCNetworkInterfaceSetDeepConfiguration (SCNetworkSetRef set, @discussion Will allow the caller to set IO Interface Unit @param interface The network interface @param unit The new interface unit to set - */ void __SCNetworkInterfaceSetIOInterfaceUnit (SCNetworkInterfaceRef interface, @@ -402,6 +402,36 @@ _SCNetworkInterfaceCacheOpen(void); void _SCNetworkInterfaceCacheClose(void); + +#pragma mark - +#pragma mark SCNetworkInterface (NetworkInterfaces.plist) configuration (internal) + + +#define kSCNetworkInterfaceActive "Active" +#define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo" +#define kSCNetworkInterfaceType "SCNetworkInterfaceType" +#define kSCNetworkInterfaceBSDName kIOBSDNameKey +#define kSCNetworkInterfaceIOBuiltin kIOBuiltin +#define kSCNetworkInterfaceIOInterfaceNamePrefix kIOInterfaceNamePrefix +#define kSCNetworkInterfaceIOInterfaceType kIOInterfaceType +#define kSCNetworkInterfaceIOInterfaceUnit kIOInterfaceUnit +#define kSCNetworkInterfaceIOMACAddress kIOMACAddress +#define kSCNetworkInterfaceIOPathMatch kIOPathMatchKey +#define kSCNetworkInterfaceMatchingMACs "MatchingMACs" + + +/*! + @function __SCNetworkInterfaceCopyStorageEntity + @discussion Create interface entity of network interface as seen in + NetworkInterfaces.plist + @param interface The network interface from which interface entity is create + @result Dictionary which contains information about interface entity. + You must release the returned value. + */ +CFDictionaryRef +__SCNetworkInterfaceCopyStorageEntity (SCNetworkInterfaceRef interface); + + #pragma mark - #pragma mark SCNetworkProtocol configuration (internal) @@ -447,8 +477,8 @@ Boolean __SCNetworkServiceIsPPTP (SCNetworkServiceRef service); -SCPreferencesRef -__SCNetworkCreateDefaultNIPrefs (CFStringRef prefsID); +void +__SCNetworkPopulateDefaultNIPrefs (SCPreferencesRef ni_prefs); /*! @function __SCNetworkServiceMigrateNew @@ -471,6 +501,7 @@ __SCNetworkServiceAddProtocolToService (SCNetworkServiceRef service, CFDictionaryRef configuration, Boolean enabled); + #pragma mark - #pragma mark SCNetworkSet configuration (internal) @@ -501,11 +532,11 @@ __copyProtocolTemplate (CFStringRef interfaceType, CFStringRef protocolType); CFDictionaryRef -__getPrefsConfiguration (SCPreferencesRef prefs, +__SCNetworkConfigurationGetValue (SCPreferencesRef prefs, CFStringRef path); Boolean -__setPrefsConfiguration (SCPreferencesRef prefs, +__SCNetworkConfigurationSetValue (SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef config, Boolean keepInactive); diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c new file mode 100644 index 0000000..9bab431 --- /dev/null +++ b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.c @@ -0,0 +1,1169 @@ +/* + * Copyright (c) 2019, 2020 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Modification History + * + * October 4, 2018 Allan Nathanson + * - initial revision + */ + + +#define USE_SC_LOG_OR_PRINT 1 // use '_sc_log' to control os_log, printf + +#include "SCNetworkConfigurationInternal.h" +#include "SCPreferencesInternal.h" +#include + + +static Boolean +savePreferences(SCPreferencesRef prefs, + CFStringRef save_prefsID, + CFStringRef prefix, + Boolean remove, + CFStringRef extra_key, + CFPropertyListRef extra_value) +{ + const CFStringRef keys[] = { + kSCPrefCurrentSet, + MODEL, + kSCPrefNetworkServices, + kSCPrefSets, + kSCPrefSystem, + kSCPrefVersion, + kSCPrefVirtualNetworkInterfaces + }; + Boolean ok; + SCPreferencesRef save_prefs; + + // open [companion] backup + save_prefs = SCPreferencesCreateCompanion(prefs, save_prefsID); + + for (CFIndex i = 0; i < (CFIndex)(sizeof(keys)/sizeof(keys[0])); i++) { + CFStringRef key = keys[i]; + CFStringRef src_key; + CFTypeRef val; + + src_key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), prefix, key); + val = SCPreferencesGetValue(prefs, src_key); + if (val != NULL) { + SCPreferencesSetValue(save_prefs, key, val); + if (remove) { + SCPreferencesRemoveValue(prefs, src_key); + } + } + CFRelease(src_key); + } + + if (extra_key != NULL) { + SCPreferencesSetValue(save_prefs, extra_key, extra_value); + } + + ok = SCPreferencesCommitChanges(save_prefs); + CFRelease(save_prefs); + if (!ok) { + SC_log(LOG_ERR, "could not save preferences (%@): %s", + save_prefsID, + SCErrorString(SCError())); + } + return ok; +} + + +__private_extern__ +Boolean +__SCNetworkConfigurationBackup(SCPreferencesRef prefs) +{ + Boolean ok; + CFStringRef save_prefsID; + struct tm tm_now; + struct timeval tv_now; + + SC_log(LOG_NOTICE, "creating [configuration] backup"); + + (void)gettimeofday(&tv_now, NULL); + (void)localtime_r(&tv_now.tv_sec, &tm_now); + save_prefsID = CFStringCreateWithFormat(NULL, + NULL, + CFSTR("preferences-%4d-%02d-%02d-%02d%02d%02d.plist"), + tm_now.tm_year + 1900, + tm_now.tm_mon + 1, + tm_now.tm_mday, + tm_now.tm_hour, + tm_now.tm_min, + tm_now.tm_sec); + ok = savePreferences(prefs, save_prefsID, CFSTR(""), FALSE, NULL, NULL); + CFRelease(save_prefsID); + return ok; +} + + +Boolean +__SCNetworkConfigurationSaveModel(SCPreferencesRef prefs, CFStringRef model) +{ + Boolean ok; + CFStringRef save_prefsID; + + SC_log(LOG_NOTICE, "creating [per-device] backup: %@", model); + + save_prefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("preferences-%@.plist"), model); + ok = savePreferences(prefs, save_prefsID, CFSTR(""), TRUE, MODEL, model); + CFRelease(save_prefsID); + return ok; +} + + +static Boolean +needsUpdate(SCPreferencesRef prefs, int new_version) +{ + CFNumberRef num; + int old_version = 0; + + if (prefs == NULL) { + // if no prefs, no updated needed + return FALSE; + } + + num = SCPreferencesGetValue(prefs, kSCPrefVersion); + if (!isA_CFNumber(num) || + !CFNumberGetValue(num, kCFNumberIntType, &old_version)) { + old_version = 0; + } + if (old_version == new_version) { + // if no update is needed + return FALSE; + } + + return TRUE; +} + + +static Boolean +lockWithSync(SCPreferencesRef prefs) +{ + Boolean ok; + + assert(prefs != NULL); + ok = SCPreferencesLock(prefs, TRUE); + if (!ok && (SCError() == kSCStatusStale)) { + SCPreferencesSynchronize(prefs); + ok = SCPreferencesLock(prefs, TRUE); + } + + return ok; +} + + +Boolean +__SCNetworkConfigurationUpgrade(SCPreferencesRef *prefs_p, + SCPreferencesRef *ni_prefs_p, + Boolean commit) +{ + SCPreferencesRef ni_prefs = NULL; + Boolean ni_prefs_added = FALSE; + const int new_version = NETWORK_CONFIGURATION_VERSION; + CFNumberRef num; + Boolean ok = FALSE; + SCPreferencesRef prefs = NULL; + Boolean prefs_added = FALSE; + + // + // The following table describes how the SPI is called (input parameters), what actions + // are performed, and whether any changes should be committed as part of the call. + // + // +====================+===========================+===========================+========+ + // | | preferences.plist | NetworkInterfaces.plist | | + // | +=============+=============+=============+=============+ COMMIT | + // | | ptr | plist | ptr | plist | | + // +====================+=============+=============+=============+=============+========+ + // | InterfaceNamer | NULL | CREATE, REL | &ni_prefs | USE | YES | + // +====================+=============+=============+=============+=============+========+ + // | PreferencesMonitor | &prefs | USE | NULL | NO UPDATE | YES | + // +====================+=============+=============+=============+=============+========+ + // | scutil | &prefs | USE | &ni_prefs | USE/CREATE | NO | + // +====================+=============+=============+=============+=============+========+ + // + // For InterfaceNamer, we are passed a reference to the SCPreferences[Ref] for the + // NetworkInterfaces.plist. During the upgrade process we create (and then release) + // the companion preferences.plist. Any needed changes will be committed to both + // plists. + // + // For PreferencesMonitor, we are passed a reference to the SCPreferences[Ref] for + // the preferences.plist. Any needed changes to the plist will be committed. The + // companion NetworkInterfaces.plist is not passed nor is it referenced/modified. + // + // For scutil, we are passed references to the SCPreferences[Ref] for both the + // preferences.plist and NetworkInterfaces.plist. The NetworkInterfaces.plist + // reference will be used, if already open. Else, the companion will be created + // and returned. Regardless, any changes made will not be committed (we expect + // one to use scutil's "commit" command). + // + + if (prefs_p != NULL) { + prefs = *prefs_p; + } + + if (ni_prefs_p != NULL) { + ni_prefs = *ni_prefs_p; + } + + if ((prefs_p == NULL) && (ni_prefs_p != NULL) && (ni_prefs != NULL)) { + // Here, we have been called by InterfaceNamer and need to get the [companion] + // preferences.plist (we need to update both) + prefs = SCPreferencesCreateCompanion(ni_prefs, NULL); + if (prefs == NULL) { + SC_log(LOG_ERR, + "__SCNetworkConfigurationUpgrade(): could not open [preferences.plist]: %s", + SCErrorString(SCError())); + return FALSE; + } + prefs_added = TRUE; + } + + if ((prefs_p != NULL) && (prefs != NULL) && (ni_prefs_p != NULL) && (ni_prefs == NULL)) { + // Here, we have been called by scutil with the [companion] NetworkInterfaces.plist + // not yet open. Open the companion so that we can update both. + ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG); + if (ni_prefs == NULL) { + SC_log(LOG_ERR, + "__SCNetworkConfigurationUpgrade(): could not open [NetworkInterfaces.plist]: %s", + SCErrorString(SCError())); + return FALSE; + } + ni_prefs_added = TRUE; + } + + if (!needsUpdate(prefs, NETWORK_CONFIGURATION_VERSION) && + !needsUpdate(ni_prefs, NETWORK_CONFIGURATION_VERSION)) { + goto done; + } + + // lock [preferences.plist] changes while we are updating + ok = lockWithSync(prefs); + if (!ok) { + SC_log(LOG_ERR, + "__SCNetworkConfigurationUpgrade(): could not lock [preferences.plist]: %s", + SCErrorString(SCError())); + goto done; + } + + if (ni_prefs != NULL) { + // lock [NetworkInterfaces.plist] changes while we are updating + ok = lockWithSync(ni_prefs); + if (!ok) { + SC_log(LOG_ERR, + "__SCNetworkConfigurationUpgrade(): could not lock [NetworkInterfaces.plist]: %s", + SCErrorString(SCError())); + SCPreferencesUnlock(prefs); + goto done; + } + } + + // first, cleanup any leftover cruft from the configuration + __SCNetworkConfigurationClean(prefs, ni_prefs); + + // update the version(s) + num = CFNumberCreate(NULL, kCFNumberIntType, &new_version); + SCPreferencesSetValue(prefs, kSCPrefVersion, num); + CFRelease(num); + if (ni_prefs != NULL) { + num = CFNumberCreate(NULL, kCFNumberIntType, &new_version); + SCPreferencesSetValue(ni_prefs, kSCPrefVersion, num); + CFRelease(num); + } + + if (commit) { + // commit the [preferences.plist] changes + ok = SCPreferencesCommitChanges(prefs); + if (!ok) { + SC_log(LOG_ERR, + "__SCNetworkConfigurationUpgrade(): update not saved [preferences.plist]: %s", + SCErrorString(SCError())); + } + if (ok) { + ok = SCPreferencesApplyChanges(prefs); + if (!ok) { + SC_log(LOG_ERR, + "__SCNetworkConfigurationUpgrade(): update not applied [preferences.plist]: %s", + SCErrorString(SCError())); + } + } + } + SCPreferencesUnlock(prefs); + + if (ni_prefs != NULL) { + if (commit) { + // commit the [NetworkInterfaces.plist] changes + if (ok) { + ok = SCPreferencesCommitChanges(ni_prefs); + if (!ok) { + SC_log(LOG_ERR, + "__SCNetworkConfigurationUpgrade(): update not saved [NetworkInterfaces.plist]: %s", + SCErrorString(SCError())); + } + } + } + SCPreferencesUnlock(ni_prefs); + } + + done : + + if (prefs_added) { +// if (ok && (prefs_p != NULL)) { +// *prefs_p = CFRetain(prefs); +// } + CFRelease(prefs); + } + + if (ni_prefs_added) { + if (ok && (ni_prefs_p != NULL)) { + *ni_prefs_p = CFRetain(ni_prefs); + } + CFRelease(ni_prefs); + } + + return ok; +} + + +#pragma mark - +#pragma mark Remove "Hidden" Interface Configurations + + +static Boolean +isThin(CFArrayRef interfaces, CFStringRef bsdName) +{ + Boolean thin; + + thin = CFArrayContainsValue(interfaces, + CFRangeMake(0, CFArrayGetCount(interfaces)), + bsdName); + return thin; +} + + +static Boolean +thinAdd(CFMutableArrayRef interfaces, CFStringRef bsdName) +{ + if (!CFArrayContainsValue(interfaces, + CFRangeMake(0, CFArrayGetCount(interfaces)), + bsdName)) { + CFArrayAppendValue(interfaces, bsdName); + return TRUE; + } + + return FALSE; +} + + +static Boolean +thinRemove(CFMutableArrayRef interfaces, CFStringRef bsdName) +{ + CFIndex n; + + n = CFArrayGetFirstIndexOfValue(interfaces, + CFRangeMake(0, CFArrayGetCount(interfaces)), + bsdName); + if (n != kCFNotFound) { + CFArrayRemoveValueAtIndex(interfaces, n); + return TRUE; + } + + return FALSE; +} + + +static CF_RETURNS_RETAINED CFStringRef +serviceMatchesTemplate(SCPreferencesRef prefs, SCNetworkServiceRef existingService) +{ + CFStringRef conflict = NULL; + SCNetworkInterfaceRef existingInterface; + CFIndex n; + CFArrayRef protocols; + CFMutableArrayRef protocolTypes; + SCNetworkServiceRef templateService; + + // create a temporary network service (so that we can get the template configuration) + existingInterface = SCNetworkServiceGetInterface(existingService); + if (existingInterface == NULL) { + conflict = CFStringCreateCopy(NULL, CFSTR("could not get interface for service")); + return conflict; + } + + templateService = SCNetworkServiceCreate(prefs, existingInterface); + if (templateService == NULL) { + conflict = CFStringCreateCopy(NULL, CFSTR("could not create service for interface")); + return conflict; + } + + (void) SCNetworkServiceEstablishDefaultConfiguration(templateService); + + protocolTypes = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + // get protocol types from the existing service + protocols = SCNetworkServiceCopyProtocols(existingService); + if (protocols != NULL) { + n = CFArrayGetCount(protocols); + + for (CFIndex i = 0; i < n; i++) { + SCNetworkProtocolRef protocol; + CFStringRef protocolType; + + protocol = CFArrayGetValueAtIndex(protocols, i); + protocolType = SCNetworkProtocolGetProtocolType(protocol); + if (!CFArrayContainsValue(protocolTypes, + CFRangeMake(0, CFArrayGetCount(protocolTypes)), + protocolType)) { + CFArrayAppendValue(protocolTypes, protocolType); + } + } + + CFRelease(protocols); + } + + // get protocol types from the template service + protocols = SCNetworkServiceCopyProtocols(templateService); + if (protocols != NULL) { + n = CFArrayGetCount(protocols); + + for (CFIndex i = 0; i < n; i++) { + SCNetworkProtocolRef protocol; + CFStringRef protocolType; + + protocol = CFArrayGetValueAtIndex(protocols, i); + protocolType = SCNetworkProtocolGetProtocolType(protocol); + if (!CFArrayContainsValue(protocolTypes, + CFRangeMake(0, CFArrayGetCount(protocolTypes)), + protocolType)) { + CFArrayAppendValue(protocolTypes, protocolType); + } + } + + CFRelease(protocols); + } + + // compare the existing protocols with the template + n = CFArrayGetCount(protocolTypes); + for (CFIndex i = 0; i < n; i++) { + CFDictionaryRef existingConfiguration = NULL; + SCNetworkProtocolRef existingProtocol; + Boolean match; + CFStringRef protocolType; + CFDictionaryRef templateConfiguration = NULL; + SCNetworkProtocolRef templateProtocol; + + protocolType = CFArrayGetValueAtIndex(protocolTypes, i); + existingProtocol = SCNetworkServiceCopyProtocol(existingService, protocolType); + templateProtocol = SCNetworkServiceCopyProtocol(templateService, protocolType); + + do { + // compare "enabled" + match = ((existingProtocol != NULL) && + (templateProtocol != NULL) && + (SCNetworkProtocolGetEnabled(existingProtocol) == SCNetworkProtocolGetEnabled(templateProtocol))); + if (!match) { + conflict = CFStringCreateWithFormat(NULL, NULL, + CFSTR("conflicting %@ enable/disable"), + protocolType); + break; // if enable/disable conflict + } + + if (existingProtocol != NULL) { + existingConfiguration = SCNetworkProtocolGetConfiguration(existingProtocol); + } + if (templateProtocol != NULL) { + templateConfiguration = SCNetworkProtocolGetConfiguration(templateProtocol); + } + match = _SC_CFEqual(existingConfiguration, templateConfiguration); + if (!match) { + conflict = CFStringCreateWithFormat(NULL, NULL, + CFSTR("conflicting %@ configuration"), + protocolType); + break; // if configuration conflict + } + } while (FALSE); + + if (existingProtocol != NULL) CFRelease(existingProtocol); + if (templateProtocol != NULL) CFRelease(templateProtocol); + if (!match) { + break; + } + } + + (void) SCNetworkServiceRemove(templateService); + CFRelease(templateService); + CFRelease(protocolTypes); + return conflict; +} + + +static Boolean +effectivelyHiddenConfiguration(SCNetworkInterfaceRef interface) +{ + const CFStringRef known[] = { + CFSTR("Apple TV"), + CFSTR("Watch"), + CFSTR("iPad"), + CFSTR("iPhone"), + CFSTR("iPod"), + }; + CFStringRef name; + + name = SCNetworkInterfaceGetLocalizedDisplayName(interface); + for (int i = 0; i < (int)(sizeof(known) / sizeof(known[0])); i++) { + if (CFStringHasPrefix(name, known[i])) { + return TRUE; + } + } + + return FALSE; +} + + +static Boolean +__SCNetworkConfigurationCleanHiddenInterfaces(SCPreferencesRef prefs, SCPreferencesRef ni_prefs) +{ +#pragma unused(prefs) +#pragma unused(ni_prefs) + CFStringRef bsdName; + Boolean changed = FALSE; + CFArrayRef interfaces; + CFMutableArrayRef interfaces_thin; + CFIndex n; + CFDictionaryRef nat_config; + SCPreferencesRef nat_prefs; + CFArrayRef services; + int updated = 0; + + // build a list of interfaces we "could" remove + + interfaces_thin = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + services = SCNetworkServiceCopyAll(prefs); + if (services != NULL) { + n = CFArrayGetCount(services); + for (CFIndex i = 0; i < n; i++) { + CFStringRef conflict; + SCNetworkInterfaceRef interface; + SCNetworkServiceRef service; + const char *thin = NULL; + + service = CFArrayGetValueAtIndex(services, i); + interface = SCNetworkServiceGetInterface(service); + bsdName = SCNetworkInterfaceGetBSDName(interface); + + if (bsdName == NULL) { + // if no interface name + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_INFO, + "skipping service : %@ : %@ (no interface)", + SCNetworkServiceGetServiceID(service), + SCNetworkServiceGetName(service)); + } + continue; + } + + if (_SCNetworkInterfaceIsHiddenConfiguration(interface)) { + thin = "hidden"; + } else if (effectivelyHiddenConfiguration(interface)) { + thin = "effectively hidden"; + } else { + // if not HiddenConfiguration + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_INFO, + "skipping service : %@ : %@ : %@ (not hidden)", + SCNetworkServiceGetServiceID(service), + SCNetworkServiceGetName(service), + bsdName); + } + continue; + } + + conflict = serviceMatchesTemplate(prefs, service); + if (conflict != NULL) { + // if any part of the service's configuration was changed + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_INFO, + "skipping service : %@ : %@ : %@ (%s, non-default, %@)", + SCNetworkServiceGetServiceID(service), + SCNetworkServiceGetName(service), + bsdName, + thin, + conflict); + } + CFRelease(conflict); + continue; + } + + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_INFO, "candidate interface : %@ (%s)", bsdName, thin); + } + + thinAdd(interfaces_thin, bsdName); + } + } + + // remove any virtual interfaces from the list + +#if !TARGET_OS_IPHONE + interfaces = SCBondInterfaceCopyAll(prefs); + if (interfaces != NULL) { + CFIndex n; + + n = CFArrayGetCount(interfaces); + for (CFIndex i = 0; i < n; i++) { + SCBondInterfaceRef bondInterface; + CFArrayRef members; + CFIndex nn; + + bondInterface = CFArrayGetValueAtIndex(interfaces, i); + members = SCBondInterfaceGetMemberInterfaces(bondInterface); + nn = (members != NULL) ? CFArrayGetCount(members) : 0; + for (CFIndex ii = 0; ii < nn; ii++) { + SCNetworkInterfaceRef member; + + member = CFArrayGetValueAtIndex(members, ii); + bsdName = SCNetworkInterfaceGetBSDName(member); + if ((bsdName != NULL) && + thinRemove(interfaces_thin, bsdName)) { + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_INFO, "skipping interface : %@ (bond member)", bsdName); + } + } + } + } + + CFRelease(interfaces); + } +#endif // !TARGET_OS_IPHONE + + interfaces = SCBridgeInterfaceCopyAll(prefs); + if (interfaces != NULL) { + CFIndex n; + + n = CFArrayGetCount(interfaces); + for (CFIndex i = 0; i < n; i++) { + SCBridgeInterfaceRef bridgeInterface; + CFArrayRef members; + CFIndex nn; + + bridgeInterface = CFArrayGetValueAtIndex(interfaces, i); + members = SCBridgeInterfaceGetMemberInterfaces(bridgeInterface); + nn = (members != NULL) ? CFArrayGetCount(members) : 0; + for (CFIndex ii = 0; ii < nn; ii++) { + SCNetworkInterfaceRef member; + + member = CFArrayGetValueAtIndex(members, ii); + bsdName = SCNetworkInterfaceGetBSDName(member); + if ((bsdName != NULL) && + thinRemove(interfaces_thin, bsdName)) { + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_INFO, "skipping interface : %@ (bridge member)", bsdName); + } + } + } + } + + CFRelease(interfaces); + } + + interfaces = SCVLANInterfaceCopyAll(prefs); + if (interfaces != NULL) { + CFIndex n; + + n = CFArrayGetCount(interfaces); + for (CFIndex i = 0; i < n; i++) { + SCBridgeInterfaceRef vlanInterface; + SCNetworkInterfaceRef physicalInterface; + + vlanInterface = CFArrayGetValueAtIndex(interfaces, i); + physicalInterface = SCVLANInterfaceGetPhysicalInterface(vlanInterface); + bsdName = SCNetworkInterfaceGetBSDName(physicalInterface); + if ((bsdName != NULL) && + thinRemove(interfaces_thin, bsdName)) { + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_INFO, "skipping interface : %@ (vlan physical)", bsdName); + } + } + } + + CFRelease(interfaces); + } + + // remove any "shared" interfaces from the list + + nat_prefs = SCPreferencesCreateCompanion(prefs, CFSTR("com.apple.nat.plist")); + nat_config = SCPreferencesGetValue(nat_prefs, CFSTR("NAT")); + if (isA_CFDictionary(nat_config)) { + CFStringRef sharedFrom = NULL; + CFArrayRef sharedTo = NULL; + + if (CFDictionaryGetValueIfPresent(nat_config, + CFSTR("PrimaryService"), + (const void **)&sharedFrom) && + isA_CFString(sharedFrom)) { + SCNetworkInterfaceRef interface; + SCNetworkServiceRef service; + + // if "Share your connection from" service configured + service = SCNetworkServiceCopy(prefs, sharedFrom); + if (service != NULL) { + interface = SCNetworkServiceGetInterface(service); + bsdName = SCNetworkInterfaceGetBSDName(interface); + if ((bsdName != NULL) && + thinRemove(interfaces_thin, bsdName)) { + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_INFO, "skipping interface : %@ (Share your connection from)", bsdName); + } + } + CFRelease(service); + } else { + SC_log(LOG_INFO, "keeping [not found] service : %@ (Share your connection from)", sharedFrom); + } + } + + if (CFDictionaryGetValueIfPresent(nat_config, + CFSTR("SharingDevices"), + (const void **)&sharedTo) && + isA_CFArray(sharedTo)) { + // if "To computers using" interfaces configured + n = CFArrayGetCount(sharedTo); + for (CFIndex i = 0; i < n; i++) { + bsdName = CFArrayGetValueAtIndex(sharedTo, i); + if (thinRemove(interfaces_thin, bsdName)) { + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_INFO, "skipping interface : %@ (To computers using)", bsdName); + } + } + } + } + } + CFRelease(nat_prefs); + + // thin preferences.plist + n = (services != NULL) ? CFArrayGetCount(services) : 0; + if (n > 0) { + updated = 0; + + for (CFIndex i = 0; i < n; i++) { + SCNetworkInterfaceRef interface; + SCNetworkServiceRef service; + + service = CFArrayGetValueAtIndex(services, i); + interface = SCNetworkServiceGetInterface(service); + bsdName = SCNetworkInterfaceGetBSDName(interface); + if (bsdName == NULL) { + // if no interface name + continue; + } + + if (!isThin(interfaces_thin, bsdName)) { + // if not thinned + continue; + } + + // remove this service associated with a "thinned" interface + if ((_sc_log == 1) || _sc_verbose) { + SC_log(LOG_INFO, + "thinned network service : %@ : %@ : %@", + SCNetworkServiceGetServiceID(service), + SCNetworkServiceGetName(service), + bsdName); + } + SCNetworkServiceRemove(service); + updated++; + } + + if (updated > 0) { + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_NOTICE, + "Updating \"preferences.plist\" (thinned %d service%s)", + updated, + (updated != 1) ? "s" : ""); + } + changed = TRUE; + } + } + + // thin NetworkInterfaces.plist + interfaces = SCPreferencesGetValue(ni_prefs, INTERFACES); + interfaces = isA_CFArray(interfaces); + n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0; + if (n > 0) { + CFMutableArrayRef interfaces_new; + + updated = 0; + + interfaces_new = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + n = CFArrayGetCount(interfaces); + for (CFIndex i = 0; i < n; i++) { + CFDictionaryRef if_dict; + + if_dict = CFArrayGetValueAtIndex(interfaces, i); + bsdName = CFDictionaryGetValue(if_dict, CFSTR(kIOBSDNameKey)); + if (isThin(interfaces_thin, bsdName)) { + // remove this "thinned" interface + if ((_sc_log == 1) || _sc_verbose) { + SC_log(LOG_INFO, "thinned network interface : %@", bsdName); + } + updated++; + continue; + } + + CFArrayAppendValue(interfaces_new, if_dict); + } + SCPreferencesSetValue(ni_prefs, INTERFACES, interfaces_new); + CFRelease(interfaces_new); + + if (updated > 0) { + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_INFO, + "Updating \"NetworkInterfaces.plist\" (thinned %d interface%s)", + updated, + (updated != 1) ? "s" : ""); + } + changed = TRUE; + } + } + + if (services != NULL) CFRelease(services); + CFRelease(interfaces_thin); + return changed; +} + + +#pragma mark - +#pragma mark Remove [SCNetworkMigration] Inline Backups + + +static void +thinInlineBackup(const void *value, void *context) +{ + CFStringRef backup = (CFStringRef)value; + char *backup_str; + SCPreferencesRef prefs = (SCPreferencesRef)context; + CFStringRef save_prefix; + CFStringRef save_prefsID = NULL; + + SC_log(LOG_NOTICE, "thinning [inline] backup: %@", backup); + + save_prefix = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ : "), backup); + backup_str = _SC_cfstring_to_cstring(backup, NULL, 0, kCFStringEncodingASCII); + if (backup_str != NULL) { + struct tm save_tm = { 0 }; + + if (strptime(backup_str, "%Y-%m-%d %H:%M:%S", &save_tm) != NULL) { + save_prefsID = CFStringCreateWithFormat(NULL, + NULL, + CFSTR("preferences-%4d-%02d-%02d-%02d%02d%02d.plist"), + save_tm.tm_year + 1900, + save_tm.tm_mon + 1, + save_tm.tm_mday, + save_tm.tm_hour, + save_tm.tm_min, + save_tm.tm_sec); + } + CFAllocatorDeallocate(NULL, backup_str); + } + if (save_prefsID == NULL) { + save_prefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("preferences-%@.plist"), backup); + } + savePreferences(prefs, save_prefsID, save_prefix, TRUE, NULL, NULL); + CFRelease(save_prefsID); + CFRelease(save_prefix); + return; +} + + +static Boolean +__SCNetworkConfigurationCleanInlineBackups(SCPreferencesRef prefs) +{ + CFMutableSetRef backups = NULL; + Boolean cleaned = FALSE; + CFArrayRef keys; + CFIndex n; + CFStringRef suffix; + + keys = SCPreferencesCopyKeyList(prefs); + if (keys == NULL) { + return FALSE; + } + + suffix = CFStringCreateWithFormat(NULL, NULL, CFSTR(" : %@"), kSCPrefSets); + n = CFArrayGetCount(keys); + for (CFIndex i = 0; i < n; i++) { + CFStringRef key = CFArrayGetValueAtIndex(keys, i); + CFMutableStringRef str; + + if (CFStringHasSuffix(key, suffix)) { + // if " : Sets" + if (backups == NULL) { + backups = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); + } + str = CFStringCreateMutableCopy(NULL, 0, key); + CFStringTrim(str, suffix); + CFSetAddValue(backups, str); + CFRelease(str); + continue; + } + } + CFRelease(suffix); + CFRelease(keys); + + if (backups != NULL) { + CFSetApplyFunction(backups, thinInlineBackup, (void *)prefs); + CFRelease(backups); + cleaned = TRUE; + } + + return cleaned; +} + + +#pragma mark - +#pragma mark Remove [new device type] Inline Backups + + +static void +thinInlineModel(const void *value, void *context) +{ + CFStringRef model = (CFStringRef)value; + SCPreferencesRef prefs = (SCPreferencesRef)context; + CFStringRef save_prefix; + CFStringRef save_prefsID; + + SC_log(LOG_NOTICE, "thinning [per-model] backup: %@", model); + + save_prefix = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:"), model); + save_prefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("preferences-%@.plist"), model); + savePreferences(prefs, save_prefsID, save_prefix, TRUE, MODEL, model); + CFRelease(save_prefsID); + CFRelease(save_prefix); + return; +} + + +static Boolean +__SCNetworkConfigurationCleanInlineModels(SCPreferencesRef prefs) +{ + Boolean cleaned = FALSE; + CFArrayRef keys; + CFMutableSetRef models = NULL; + CFIndex n; + CFStringRef suffix; + + keys = SCPreferencesCopyKeyList(prefs); + if (keys == NULL) { + return FALSE; + } + + suffix = CFStringCreateWithFormat(NULL, NULL, CFSTR(":%@"), kSCPrefSets); + n = CFArrayGetCount(keys); + for (CFIndex i = 0; i < n; i++) { + CFStringRef key = CFArrayGetValueAtIndex(keys, i); + CFMutableStringRef str; + + if (CFStringHasSuffix(key, suffix)) { + // if " : Sets" + if (models == NULL) { + models = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); + } + str = CFStringCreateMutableCopy(NULL, 0, key); + CFStringTrim(str, suffix); + CFSetAddValue(models, str); + CFRelease(str); + continue; + } + } + CFRelease(suffix); + CFRelease(keys); + + if (models != NULL) { + CFSetApplyFunction(models, thinInlineModel, (void *)prefs); + CFRelease(models); + cleaned = TRUE; + } + + return cleaned; +} + + +#pragma mark - +#pragma mark Remove Orphaned Services + + +/* +static Boolean +__SCNetworkConfigurationCleanOrphanedServices(SCPreferencesRef prefs) +{ +#pragma unused(prefs) + return FALSE; +} +*/ + + +#pragma mark - +#pragma mark Cleanup network service order issues + + +static Boolean +__SCNetworkConfigurationCleanServiceOrderIssues(SCPreferencesRef prefs) +{ +#pragma unused(prefs) + Boolean cleaned = FALSE; + CFIndex nSets; + CFArrayRef sets; + + sets = SCNetworkSetCopyAll(prefs); + nSets = (sets != NULL) ? CFArrayGetCount(sets) : 0; + for (CFIndex iSets = 0; iSets < nSets; iSets++) { + CFIndex iServices; + CFMutableSetRef known = NULL; + CFIndex nServices; + SCNetworkSetRef set = CFArrayGetValueAtIndex(sets, iSets); + CFStringRef setID = SCNetworkSetGetSetID(set); + CFArrayRef order = SCNetworkSetGetServiceOrder(set); + CFMutableArrayRef newOrder = NULL; + + iServices = 0; + nServices = (order != NULL) ? CFArrayGetCount(order) : 0; + if (nServices > 0) { + known = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); + newOrder = CFArrayCreateMutableCopy(NULL, 0, order); + } + + while (iServices < nServices) { + SCNetworkServiceRef service; + CFStringRef serviceID = CFArrayGetValueAtIndex(newOrder, iServices); + + // check if serviceID already known/processed + if (CFSetContainsValue(known, serviceID)) { + // if duplicate/removed service, remove from serviceOrder + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_NOTICE, + "set: %@, removing serviceID %@ (duplicate/removed)", + setID, + serviceID); + } + CFArrayRemoveValueAtIndex(newOrder, iServices); + nServices--; + cleaned = TRUE; + continue; + } + + // track this serviceID as known, already removed, or removed below + CFSetAddValue(known, serviceID); + + // validate serviceID + service = SCNetworkServiceCopy(prefs, serviceID); + if (service == NULL) { + // if no service, remove from serviceOrder + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_NOTICE, + "set: %@, removing serviceID %@ (no service)", + setID, + serviceID); + } + CFArrayRemoveValueAtIndex(newOrder, iServices); + nServices--; + cleaned = TRUE; + continue; + } + + if (!__SCNetworkServiceExists(service)) { + // if service already removed, remove from serviceOrder + if ((_sc_log == 1) || _sc_debug) { + SC_log(LOG_NOTICE, + "set: %@, removing serviceID %@ (service already removed)", + setID, + serviceID); + } + CFArrayRemoveValueAtIndex(newOrder, iServices); + nServices--; + cleaned = TRUE; + CFRelease(service); + continue; + } + + CFRelease(service); + iServices++; + } + + if (known != NULL) { + CFRelease(known); + } + + if (newOrder != NULL) { + if (cleaned) { + SCNetworkSetSetServiceOrder(set, newOrder); + } + CFRelease(newOrder); + } + } + + if (sets != NULL) { + CFRelease(sets); + } + + return cleaned; +} + + +#pragma mark - +#pragma mark Cleanup Network Configuration(s) + + +Boolean +__SCNetworkConfigurationClean(SCPreferencesRef prefs, SCPreferencesRef ni_prefs) +{ + Boolean changed; + Boolean updated = FALSE; + + changed = __SCNetworkConfigurationCleanInlineBackups(prefs); + if (changed) { + SC_log(LOG_NOTICE, "network configuration: unwanted inline backups removed"); + updated = TRUE; + } + + changed = __SCNetworkConfigurationCleanInlineModels(prefs); + if (changed) { + SC_log(LOG_NOTICE, "network configuration: unwanted device backups removed"); + updated = TRUE; + } + + if (ni_prefs != NULL) { + changed = __SCNetworkConfigurationCleanHiddenInterfaces(prefs, ni_prefs); + if (changed) { + SC_log(LOG_NOTICE, "network configuration: hidden interface configurations removed"); + updated = TRUE; + } + } + + changed = __SCNetworkConfigurationCleanServiceOrderIssues(prefs); + if (changed) { + SC_log(LOG_NOTICE, "network configuration: ServiceOrder cleaned"); + updated = TRUE; + } + + return updated; +} diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h index e1346b0..3129569 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h +++ b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005-2018 Apple Inc. All rights reserved. + * Copyright (c) 2005-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -88,6 +88,34 @@ typedef CF_ENUM(uint32_t, SCNetworkServicePrimaryRank) { kSCNetworkServicePrimaryRankScoped = 4 }; +#pragma mark - +#pragma mark SCNetworkConfiguration (SPI) + +/*! + @group Configuration + */ + +Boolean +_SCNetworkConfigurationBypassSystemInterfaces (SCPreferencesRef prefs) SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0)); + +void +_SCNetworkConfigurationSetBypassSystemInterfaces (SCPreferencesRef prefs, + Boolean shouldBypass) SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0)); + +Boolean +__SCNetworkConfigurationClean (SCPreferencesRef prefs, + SCPreferencesRef ni_prefs) SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0)); + +Boolean +__SCNetworkConfigurationSaveModel (SCPreferencesRef prefs, + CFStringRef model) SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0)); + +Boolean +__SCNetworkConfigurationUpgrade (SCPreferencesRef *prefs, + SCPreferencesRef *ni_prefs, + Boolean commit) SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0)); + + #pragma mark - #pragma mark SCNetworkInterface configuration (SPI) @@ -211,6 +239,10 @@ _SCNetworkInterfaceCopyBTPANInterface (void) API_AVAILABLE(macos(10.9)) A CFStringRef _SCNetworkInterfaceCopySlashDevPath (SCNetworkInterfaceRef interface) API_AVAILABLE(macos(10.6), ios(3.0)); +SCNetworkServiceRef +_SCNetworkServiceCreatePreconfigured (SCPreferencesRef prefs, + SCNetworkInterfaceRef interface) SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0)); + #define kIncludeNoVirtualInterfaces 0x0 #define kIncludeVLANInterfaces 0x1 #define kIncludeBondInterfaces 0x2 diff --git a/SystemConfiguration.fproj/SCNetworkInterface.c b/SystemConfiguration.fproj/SCNetworkInterface.c index 32c6c61..9179550 100644 --- a/SystemConfiguration.fproj/SCNetworkInterface.c +++ b/SystemConfiguration.fproj/SCNetworkInterface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2019 Apple Inc. All rights reserved. + * Copyright (c) 2004-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -272,18 +272,6 @@ static const struct { }; -#define kSCNetworkInterfaceActive "Active" -#define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo" -#define kSCNetworkInterfaceType "SCNetworkInterfaceType" -#define kSCNetworkInterfaceBSDName kIOBSDNameKey -#define kSCNetworkInterfaceIOBuiltin kIOBuiltin -#define kSCNetworkInterfaceIOInterfaceNamePrefix kIOInterfaceNamePrefix -#define kSCNetworkInterfaceIOInterfaceType kIOInterfaceType -#define kSCNetworkInterfaceIOInterfaceUnit kIOInterfaceUnit -#define kSCNetworkInterfaceIOMACAddress kIOMACAddress -#define kSCNetworkInterfaceIOPathMatch kIOPathMatchKey - - #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface") static CFBundleRef bundle = NULL; @@ -1604,7 +1592,7 @@ isBluetoothBuiltin(Boolean *haveController) if (isA_CFNumber(idVendor) && CFNumberGetValue(idVendor, kCFNumberIntType, &idVendorVal) && - (idVendorVal == kIOUSBVendorIDAppleComputer)) { + (idVendorVal == kIOUSBAppleVendorID)) { builtin = TRUE; } @@ -2016,7 +2004,8 @@ processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, #if !TARGET_OS_SIMULATOR if (CFEqual(provider, CFSTR(kIOUSBDeviceClassName)) || CFEqual(provider, CFSTR(kIOUSBInterfaceClassName)) || - CFEqual(provider, CFSTR(kIOUSBHostInterfaceClassName))) { + CFEqual(provider, CFSTR(kIOUSBHostInterfaceClassName)) || + (_SC_isAppleInternal() && IOObjectConformsTo(node, "IOUserEthernetController"))) { // get USB info (if available) processUSBInterface(interfacePrivate, interface, @@ -3038,7 +3027,7 @@ extendedConfigurationTypes(SCNetworkInterfaceRef interface) SCNetworkSetGetSetID(set), // set interfacePrivate->entity_device, // service NULL); // entity - configs = __getPrefsConfiguration(interfacePrivate->prefs, path); + configs = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path); CFRelease(path); if (isA_CFDictionary(configs)) { CFDictionaryApplyFunction(configs, @@ -3465,7 +3454,7 @@ _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName) UniChar lastChar; CFIndex length = 0; - if (isA_CFString(bsdName) == NULL) { + if (!isA_CFString(bsdName)) { SC_log(LOG_DEBUG, "no BSD name"); goto done; } @@ -3500,7 +3489,7 @@ __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface, CFStringRef c Boolean success = FALSE; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; - if (isA_SCNetworkInterface(interface) == NULL) { + if (!isA_SCNetworkInterface(interface)) { SC_log(LOG_INFO, "No interface"); goto done; } @@ -3530,7 +3519,7 @@ __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface) // Using the BSD Name update the path oldPath = interfacePrivate->path; - if (isA_CFString(oldPath) == NULL) { + if (!isA_CFString(oldPath)) { goto done; } newPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("Migrated_From: %@"), oldPath); @@ -3554,7 +3543,7 @@ __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface, { SCNetworkInterfacePrivateRef interfacePrivate; - if (isA_CFString(prefix) == NULL) { + if (!isA_CFString(prefix)) { return; } @@ -3580,7 +3569,7 @@ __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface, CFStringRef newBSDName = NULL; CFStringRef oldBSDName = NULL; - if (isA_CFNumber(unit) == NULL) { + if (!isA_CFNumber(unit)) { return; } interfacePrivate = (SCNetworkInterfacePrivateRef) interface; @@ -3588,7 +3577,7 @@ __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface, oldBSDName = SCNetworkInterfaceGetBSDName(interface); if (interfacePrivate->prefix == NULL) { - if (isA_CFString(interfacePrivate->entity_device) != NULL) { + if (isA_CFString(interfacePrivate->entity_device)) { CFStringRef interfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate->entity_device); if (interfaceNamePrefix == NULL) { SC_log(LOG_INFO, "interfaceNamePrefix is NULL"); @@ -3633,22 +3622,17 @@ __private_extern__ CFDictionaryRef __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface) { - CFMutableDictionaryRef interface_entity = NULL; - SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; - CFBooleanRef active = NULL; - CFStringRef bsdName = NULL; - CFBooleanRef builtin = NULL; - CFStringRef interfaceNamePrefix = NULL; - CFNumberRef interfaceType = NULL; - CFNumberRef interfaceUnit = NULL; - CFDataRef macAddress = NULL; - CFStringRef pathMatch = NULL; - CFDictionaryRef info = NULL; - CFStringRef type = NULL; - - if (interfacePrivate->active) { - active = kCFBooleanTrue; - } + CFMutableDictionaryRef interface_entity = NULL; + SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + CFStringRef bsdName; + CFBooleanRef builtin; + CFStringRef interfaceNamePrefix; + CFNumberRef interfaceType; + CFNumberRef interfaceUnit; + CFDataRef macAddress; + CFStringRef pathMatch; + CFDictionaryRef info = NULL; + CFStringRef type; bsdName = SCNetworkInterfaceGetBSDName(interface); if (!isA_CFString(bsdName)) { @@ -3656,6 +3640,7 @@ __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface) } builtin = interfacePrivate->builtin ? kCFBooleanTrue : kCFBooleanFalse; + interfaceNamePrefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface); if (!isA_CFString(interfaceNamePrefix)) { goto done; @@ -3694,12 +3679,13 @@ __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface) interface_entity = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - if (isA_CFBoolean(active) != NULL) { - CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceActive), active); + if (interfacePrivate->active) { + CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceActive), kCFBooleanTrue); } - CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName), bsdName); + if (interfacePrivate->hidden) { + CFDictionaryAddValue(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey, kCFBooleanTrue); + } CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin), builtin); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix), interfaceNamePrefix); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType), interfaceType); @@ -3708,7 +3694,12 @@ __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface) CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch), pathMatch); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo), info); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceType), type); -done: + if (isA_CFArray(interfacePrivate->matchingMACs)) { + CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceMatchingMACs), interfacePrivate->matchingMACs); + } + + done: + if (info != NULL) { CFRelease(info); } @@ -3791,50 +3782,57 @@ __SCNetworkInterfaceMatchesName(CFStringRef name, CFStringRef key) static SCNetworkInterfaceRef -__SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator, - CFDictionaryRef interface_entity) +__SCNetworkInterfaceCreateWithStorageEntity(CFDictionaryRef interface_entity) { -#pragma unused(allocator) - SCNetworkInterfacePrivateRef interfacePrivate = NULL; - CFBooleanRef active = NULL; - CFStringRef bsdName = NULL; - CFBooleanRef ioBuiltin = NULL; - CFStringRef ioInterfaceNamePrefix = NULL; - CFNumberRef ioInterfaceType = NULL; - int ioInterfaceTypeNum; - CFNumberRef ioInterfaceUnit = NULL; - CFDataRef ioMACAddress = NULL; - CFStringRef ioPathMatch = NULL; - CFDictionaryRef SCNetworkInterfaceInfo = NULL; - CFStringRef userDefinedName = NULL; - CFStringRef usbProductName = NULL; - CFNumberRef idProduct = NULL; - CFNumberRef idVendor = NULL; - CFStringRef type = NULL; + CFIndex interfaceIndex; + SCNetworkInterfacePrivateRef interfacePrivate = NULL; + CFBooleanRef active; + CFStringRef bsdName; + CFBooleanRef hidden; + CFDictionaryRef interfaceInfo; + CFBooleanRef ioBuiltin; + CFStringRef ioInterfaceNamePrefix = NULL; + CFNumberRef ioInterfaceType; + int ioInterfaceTypeNum; + CFNumberRef ioInterfaceUnit; + CFDataRef ioMACAddress; + CFStringRef ioPathMatch; + CFArrayRef matchingMacs; + CFStringRef userDefinedName; +#if !TARGET_OS_SIMULATOR + CFStringRef usbProductName; + CFNumberRef idProduct; + CFNumberRef idVendor; +#endif // !TARGET_OS_SIMULATOR + CFStringRef type; /* initialize runtime */ pthread_once(&initialized, __SCNetworkInterfaceInitialize); - if (isA_CFDictionary(interface_entity) == NULL) { + if (!isA_CFDictionary(interface_entity)) { SC_log(LOG_INFO, "No interface entity"); goto done; } active = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceActive)); - if (isA_CFBoolean(active) == NULL) { + if (!isA_CFBoolean(active)) { active = kCFBooleanFalse; } bsdName = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName)); - if (isA_CFString(bsdName) == NULL) { + if (!isA_CFString(bsdName)) { SC_log(LOG_INFO, "No BSD name"); goto done; } + hidden = CFDictionaryGetValue(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey); + if (!isA_CFBoolean(hidden)) { + hidden = kCFBooleanFalse; + } ioBuiltin = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin)); - if (isA_CFBoolean(ioBuiltin) == NULL) { + if (!isA_CFBoolean(ioBuiltin)) { SC_log(LOG_INFO, "No IOBuiltin property"); goto done; } ioInterfaceNamePrefix = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix)); - if (isA_CFString(ioInterfaceNamePrefix) == NULL) { + if (!isA_CFString(ioInterfaceNamePrefix)) { ioInterfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName); if (ioInterfaceNamePrefix == NULL) { SC_log(LOG_INFO, "No BSD interface name prefix"); @@ -3844,7 +3842,7 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator, CFRetain(ioInterfaceNamePrefix); } ioInterfaceType = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType)); - if (isA_CFNumber(ioInterfaceType) == NULL) { + if (!isA_CFNumber(ioInterfaceType)) { SC_log(LOG_INFO, "No IOInterfaceType"); goto done; } @@ -3852,37 +3850,37 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator, SC_log(LOG_NOTICE, "Count not extract value from ioInterfaceType"); } ioInterfaceUnit = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceUnit)); - if (isA_CFNumber(ioInterfaceUnit) == NULL) { + if (!isA_CFNumber(ioInterfaceUnit)) { SC_log(LOG_INFO, "No IOInterfaceUnit"); - goto done; } ioMACAddress = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOMACAddress)); - if (isA_CFData(ioMACAddress) == NULL) { + if (!isA_CFData(ioMACAddress)) { SC_log(LOG_INFO, "No IOMACAddress"); goto done; } ioPathMatch = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch)); - if (isA_CFString(ioPathMatch) == NULL) { + if (!isA_CFString(ioPathMatch)) { SC_log(LOG_INFO, "No IOPathMatch"); goto done; } else { // Check if Path contains the BSD Name in the end } - SCNetworkInterfaceInfo = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo)); - if (isA_CFDictionary(SCNetworkInterfaceInfo) == NULL) { + interfaceInfo = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo)); + if (!isA_CFDictionary(interfaceInfo)) { SC_log(LOG_INFO, "No SCNetworkInterfaceInfo"); goto done; } - userDefinedName = CFDictionaryGetValue(SCNetworkInterfaceInfo, kSCPropUserDefinedName); + userDefinedName = CFDictionaryGetValue(interfaceInfo, kSCPropUserDefinedName); #if !TARGET_OS_SIMULATOR - usbProductName = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBProductString)); - idProduct = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBProductID)); - idVendor = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBVendorID)); + usbProductName = CFDictionaryGetValue(interfaceInfo, CFSTR(kUSBProductString)); + idProduct = CFDictionaryGetValue(interfaceInfo, CFSTR(kUSBProductID)); + idVendor = CFDictionaryGetValue(interfaceInfo, CFSTR(kUSBVendorID)); #endif // !TARGET_OS_SIMULATOR + matchingMacs = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceMatchingMACs)); type = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceType)); - if (isA_CFString(type) == NULL) { + if (!isA_CFString(type)) { SC_log(LOG_INFO, "No SCNetworkInterfaceType"); goto done; } @@ -3891,6 +3889,7 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator, interfacePrivate->active = CFBooleanGetValue(active); interfacePrivate->entity_device = CFRetain(bsdName); interfacePrivate->builtin = CFBooleanGetValue(ioBuiltin); + interfacePrivate->hidden = CFBooleanGetValue(hidden); interfacePrivate->prefix = CFRetain(ioInterfaceNamePrefix); interfacePrivate->type = CFRetain(ioInterfaceType); interfacePrivate->unit = CFRetain(ioInterfaceUnit); @@ -3898,13 +3897,14 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator, interfacePrivate->path = CFRetain(ioPathMatch); interfacePrivate->name = ((userDefinedName != NULL) ? CFRetain(userDefinedName) : NULL); interfacePrivate->localized_name = ((userDefinedName != NULL) ? CFRetain(userDefinedName) : NULL); +#if !TARGET_OS_SIMULATOR interfacePrivate->usb.name = ((usbProductName != NULL) ? CFRetain(usbProductName) : NULL); interfacePrivate->usb.pid = ((idProduct != NULL) ? CFRetain(idProduct) : NULL); interfacePrivate->usb.vid = ((idVendor != NULL) ? CFRetain(idVendor) : NULL); +#endif // !TARGET_OS_SIMULATOR + interfacePrivate->matchingMACs = ((matchingMacs != NULL) ? CFRetain(matchingMacs) : NULL); // Handling interface types to be seen in NetworkInterfaces.plist - CFIndex interfaceIndex; - interfaceIndex = findConfiguration(type); if (interfaceIndex != kCFNotFound) { interfacePrivate->interface_type = *configurations[interfaceIndex].interface_type; @@ -3918,7 +3918,9 @@ __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator, } else if (ioInterfaceTypeNum == kInterfaceTypeFirewireValue) { interfacePrivate->entity_type = kSCValNetInterfaceTypeFireWire; } -done: + + done: + if (ioInterfaceNamePrefix != NULL) { CFRelease(ioInterfaceNamePrefix); } @@ -4013,8 +4015,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, if (service != NULL) { servicePref = ((SCNetworkServicePrivateRef)service)->prefs; - useSystemInterfaces = ((__SCPreferencesUsingDefaultPrefs(servicePref)) && - (!__SCPreferencesGetLimitSCNetworkConfiguration(servicePref))); + useSystemInterfaces = !_SCNetworkConfigurationBypassSystemInterfaces(servicePref); } ifType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceType); @@ -5145,7 +5146,7 @@ __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set, SCNetworkInterf interfacePrivate->entity_device, // interface defaultType); // entity if (path != NULL) { - config = __getPrefsConfiguration(interfacePrivate->prefs, path); + config = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path); CFRelease(path); if (config == NULL) { @@ -5185,7 +5186,7 @@ __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface, CFStringRef path; path = CFArrayGetValueAtIndex(paths, 0); - config = __getPrefsConfiguration(interfacePrivate->prefs, path); + config = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path); CFRelease(paths); } else { @@ -5232,7 +5233,7 @@ SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface) path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator interfacePrivate->serviceID, // service kSCEntNetAirPort); // entity - config = __getPrefsConfiguration(interfacePrivate->prefs, path); + config = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path); CFRelease(path); } } @@ -5699,7 +5700,7 @@ __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set, interfacePrivate->entity_device, // interface defaultType); // entity if (path != NULL) { - ok = __setPrefsConfiguration(interfacePrivate->prefs, path, config, FALSE); + ok = __SCNetworkConfigurationSetValue(interfacePrivate->prefs, path, config, FALSE); CFRelease(path); if (ok) { // if configuration has been saved @@ -5771,7 +5772,7 @@ __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface, CFStringRef path; path = CFArrayGetValueAtIndex(paths, i); - ok = __setPrefsConfiguration(interfacePrivate->prefs, path, config, FALSE); + ok = __SCNetworkConfigurationSetValue(interfacePrivate->prefs, path, config, FALSE); if (!ok) { break; } @@ -7571,20 +7572,8 @@ _SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface) return FALSE; } - if ((interfacePrivate->overrides == NULL) || - (!CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv4) && - !CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv6))) { - // if no [IPv4/IPv6] configuration overrides - return FALSE; - } - if (_SCNetworkInterfaceIsBuiltin(interface)) { - // if built-in (and overrides are present) - return TRUE; - } - - if (_SCNetworkInterfaceIsCarPlay(interface)) { - // if CarPlay (and overrides are present) + // if built-in return TRUE; } @@ -7592,8 +7581,18 @@ _SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface) int vid; if (CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid) && - (vid == kIOUSBVendorIDAppleComputer)) { - // if Apple interface (and overrides are present) + (vid == kIOUSBAppleVendorID)) { + // if Apple interface + return TRUE; + } + } + + if (_SCNetworkInterfaceIsCarPlay(interface)) { + // if CarPlay + if ((interfacePrivate->overrides != NULL) && + (CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv4) || + CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv6))) { + // and overrides are present return TRUE; } } @@ -7994,7 +7993,9 @@ __SCNetworkInterfaceIsMember(SCPreferencesRef prefs, SCNetworkInterfaceRef inter __private_extern__ void -__SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set, SCNetworkInterfaceRef interface, CFArrayRef configs) +__SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set, + SCNetworkInterfaceRef interface, + CFArrayRef configs) { CFIndex i; @@ -8171,7 +8172,7 @@ SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface) CFDictionaryRef config; CFStringRef path = CFArrayGetValueAtIndex(path_list, 0); - config = __getPrefsConfiguration(interfacePrivate->prefs, path); + config = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path); CFRelease(path_list); if (config != NULL) { int disable = 0; @@ -8232,7 +8233,7 @@ __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface, CFMutableDictionaryRef new_config; CFStringRef path = CFArrayGetValueAtIndex(path_list, i); - config = __getPrefsConfiguration(interfacePrivate->prefs, path); + config = __SCNetworkConfigurationGetValue(interfacePrivate->prefs, path); if (config != NULL) { new_config = CFDictionaryCreateMutableCopy(NULL, 0, config); @@ -8247,10 +8248,10 @@ __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface, } else { CFDictionaryRemoveValue(new_config, kSCPropDisableUntilNeeded); } - ok = __setPrefsConfiguration(interfacePrivate->prefs, - path, - (CFDictionaryGetCount(new_config) > 0) ? new_config : NULL, - FALSE); + ok = __SCNetworkConfigurationSetValue(interfacePrivate->prefs, + path, + (CFDictionaryGetCount(new_config) > 0) ? new_config : NULL, + FALSE); CFRelease(new_config); if (!ok) { break; @@ -8325,120 +8326,105 @@ __private_extern__ CFArrayRef // SCNetworkInterfaceRef __SCNetworkInterfaceCopyStoredWithPreferences(SCPreferencesRef ni_prefs) { - CFStringRef defaultNetworkInterfacePath = NULL; CFArrayRef if_list; - CFMutableArrayRef interfaceList = NULL; - SCNetworkInterfaceRef interfaceNamer = NULL; + CFMutableArrayRef interfaceList = NULL; /* initialize runtime */ pthread_once(&initialized, __SCNetworkInterfaceInitialize); - if (ni_prefs == NULL) { - defaultNetworkInterfacePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS); - assert(defaultNetworkInterfacePath != NULL); - ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath); + if (ni_prefs != NULL) { + CFRetain(ni_prefs); + } else { + ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG); + assert(ni_prefs); } if_list = SCPreferencesGetValue(ni_prefs, INTERFACES); if (isA_CFArray(if_list)) { - CFIndex i; CFIndex n = CFArrayGetCount(if_list); interfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - for (i = 0; i < n; i++) { + for (CFIndex i = 0; i < n; i++) { CFDictionaryRef dict; dict = CFArrayGetValueAtIndex(if_list, i); if (isA_CFDictionary(dict) != NULL) { - interfaceNamer = __SCNetworkInterfaceCreateWithStorageEntity(NULL, dict); + SCNetworkInterfaceRef interface; - if (interfaceNamer != NULL) { - CFArrayAppendValue(interfaceList, interfaceNamer); - CFRelease(interfaceNamer); + interface = __SCNetworkInterfaceCreateWithStorageEntity(dict); + if (interface != NULL) { + CFArrayAppendValue(interfaceList, interface); + CFRelease(interface); } } } } - if (defaultNetworkInterfacePath != NULL) { - CFRelease(defaultNetworkInterfacePath); - // prefs were created in the function, and hence need to be released - CFRelease(ni_prefs); - } + CFRelease(ni_prefs); return interfaceList; } __private_extern__ Boolean -__SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs, CFArrayRef interfacesToSave) +__SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef ni_prefs, CFArrayRef interfacesToSave) { - CFStringRef defaultNetworkInterfacePath = NULL; - Boolean success = FALSE; + Boolean ok; - if (prefs == NULL) { // TODO: Get the default preferences on the system - defaultNetworkInterfacePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS); - assert(defaultNetworkInterfacePath != NULL); - prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath); + if (!isA_CFArray(interfacesToSave)) { + return FALSE; } - if (isA_CFArray(interfacesToSave) == NULL) { - SC_log(LOG_INFO, "No interfaces to save"); - goto done; - } - SCPreferencesSetValue(prefs, INTERFACES, interfacesToSave); - success = TRUE; -done: - if (defaultNetworkInterfacePath != NULL) { - CFRelease(defaultNetworkInterfacePath); - // prefs were created in the function, and hence need to be released - CFRelease(prefs); + if (ni_prefs != NULL) { + CFRetain(ni_prefs); + } else { + ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG); + assert(ni_prefs); } - return success; + ok = SCPreferencesSetValue(ni_prefs, INTERFACES, interfacesToSave); + CFRelease(ni_prefs); + return ok; } __private_extern__ SCNetworkInterfaceRef __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator, SCPreferencesRef ni_prefs, CFStringRef bsdName) { - CFArrayRef if_list; - SCNetworkInterfaceRef interface = NULL; - CFStringRef defaultNetworkInterfacePath; +#pragma unused(allocator) + CFArrayRef if_list; + SCNetworkInterfaceRef interface = NULL; /* initialize runtime */ pthread_once(&initialized, __SCNetworkInterfaceInitialize); - if (ni_prefs == NULL) { - defaultNetworkInterfacePath = CFStringCreateWithFormat(allocator, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS); - ni_prefs = SCPreferencesCreate(allocator, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath); - CFRelease(defaultNetworkInterfacePath); - } - else { + if (ni_prefs != NULL) { CFRetain(ni_prefs); + } else { + ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG); + assert(ni_prefs); } if_list = SCPreferencesGetValue(ni_prefs, INTERFACES); + if (isA_CFArray(if_list)) { + CFIndex n = CFArrayGetCount(if_list); - if (isA_CFArray(if_list) != NULL) { - CFIndex idx; - CFIndex count = CFArrayGetCount(if_list); - - for (idx = 0; idx < count; idx++) { - CFDictionaryRef dict; - CFStringRef tmp_bsdName; + for (CFIndex i = 0; i < n; i++) { + CFDictionaryRef dict; + CFStringRef tmp_bsdName; - dict = CFArrayGetValueAtIndex(if_list, idx); - if (isA_CFDictionary(dict) == NULL) { + dict = CFArrayGetValueAtIndex(if_list, i); + if (!isA_CFDictionary(dict)) { continue; } tmp_bsdName = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceBSDName)); - if (tmp_bsdName == NULL) { + if (!isA_CFString(tmp_bsdName)) { continue; } + if (CFEqual(bsdName, tmp_bsdName)) { - interface = __SCNetworkInterfaceCreateWithStorageEntity(allocator, dict); + interface = __SCNetworkInterfaceCreateWithStorageEntity(dict); break; } } @@ -8468,7 +8454,7 @@ __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces) interface = (SCNetworkInterfaceRef) CFArrayGetValueAtIndex(interfaces, idx); bsdName = SCNetworkInterfaceGetBSDName(interface); - if (isA_CFString(bsdName) == NULL) { + if (!isA_CFString(bsdName)) { SC_log(LOG_INFO, "No BSD name"); continue; } diff --git a/SystemConfiguration.fproj/SCNetworkMigration.c b/SystemConfiguration.fproj/SCNetworkMigration.c index 27c7d8b..f38e15c 100644 --- a/SystemConfiguration.fproj/SCNetworkMigration.c +++ b/SystemConfiguration.fproj/SCNetworkMigration.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018 Apple Inc. All rights reserved. + * Copyright (c) 2014-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -41,10 +41,6 @@ #define BACK_TO_MY_MAC CFSTR("BackToMyMac") #define BACK_TO_MY_MAC_DSIDS CFSTR("BackToMyMacDSIDs") -#define PREFS_DEFAULT_DIR_PLIST "/Library/Preferences/SystemConfiguration" -#define PREFS_DEFAULT_DIR_RELATIVE CFSTR("Library/Preferences/SystemConfiguration/") -#define PREFS_DEFAULT_CONFIG_PLIST "preferences.plist" -#define NETWORK_INTERFACES_PREFS_PLIST "NetworkInterfaces.plist" #define NUM_MIGRATION_PATHS 2 #define PLUGIN_ID CFSTR("System Migration") #define PREFERENCES_PLIST_INDEX 0 @@ -82,8 +78,8 @@ _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(CFURLRef baseURL, CFURLRef CFRetain(baseURL); } else { baseURL = CFURLCreateFromFileSystemRepresentation(NULL, - (UInt8*)PREFS_DEFAULT_DIR_PLIST, - sizeof(PREFS_DEFAULT_DIR_PLIST) - 1, + (UInt8*)PREFS_DEFAULT_DIR_PATH, + sizeof(PREFS_DEFAULT_DIR_PATH) - 1, TRUE); } @@ -94,8 +90,8 @@ _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(CFURLRef baseURL, CFURLRef baseURL); *interfaces = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, - (UInt8*)NETWORK_INTERFACES_PREFS_PLIST, - sizeof(NETWORK_INTERFACES_PREFS_PLIST) - 1, + (UInt8*)INTERFACES_DEFAULT_CONFIG_PLIST, + sizeof(INTERFACES_DEFAULT_CONFIG_PLIST) - 1, FALSE, baseURL); CFRelease(baseURL); @@ -350,31 +346,24 @@ __SCNetworkCreateDefaultPref(CFStringRef prefsID) } __private_extern__ -SCPreferencesRef -__SCNetworkCreateDefaultNIPrefs(CFStringRef prefsID) +void +__SCNetworkPopulateDefaultNIPrefs(SCPreferencesRef ni_prefs) { CFMutableArrayRef interfaces = NULL; CFStringRef model; CFArrayRef networkInterfaces; - SCPreferencesRef ni_prefs; CFComparisonResult res; + interfaces = (CFMutableArrayRef)SCPreferencesGetValue(ni_prefs, INTERFACES); + if (isA_CFArray(interfaces)) { + // if already populated + return; + } + networkInterfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface(TRUE); if (networkInterfaces == NULL) { SC_log(LOG_NOTICE, "networkInterfaces is NULL"); - return NULL; - } - - if (prefsID == NULL) { - prefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS); - } else { - CFRetain(prefsID); - } - ni_prefs = SCPreferencesCreate(NULL, PLUGIN_ID, prefsID); - CFRelease(prefsID); - if (ni_prefs == NULL) { - SC_log(LOG_NOTICE, "ni_prefs is NULL"); - goto done; + return; } interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); @@ -384,15 +373,15 @@ __SCNetworkCreateDefaultNIPrefs(CFStringRef prefsID) CFNumberRef if_type; CFNumberRef if_unit; SCNetworkInterfaceRef interface = CFArrayGetValueAtIndex(networkInterfaces, idx); - CFDictionaryRef interfaceEntity = __SCNetworkInterfaceCopyStorageEntity(interface); + CFDictionaryRef interfaceEntity; + interfaceEntity = __SCNetworkInterfaceCopyStorageEntity(interface); if (interfaceEntity == NULL) { continue; } if_type = _SCNetworkInterfaceGetIOInterfaceType(interface); if_unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface); - if ((if_type == NULL) || (if_unit == NULL)) { CFRelease(interfaceEntity); continue; @@ -417,22 +406,19 @@ __SCNetworkCreateDefaultNIPrefs(CFStringRef prefsID) CFRelease(interfaceEntity); } + SCPreferencesSetValue(ni_prefs, INTERFACES, interfaces); + CFRelease(interfaces); model = SCPreferencesGetValue(ni_prefs, MODEL); if (model == NULL) { model = _SC_hw_model(FALSE); SCPreferencesSetValue(ni_prefs, MODEL, model); } -done: - if (interfaces != NULL) { - CFRelease(interfaces); - } - if (networkInterfaces != NULL) { - CFRelease(networkInterfaces); - } - return ni_prefs; + CFRelease(networkInterfaces); + + return; } @@ -485,17 +471,29 @@ _SCNetworkConfigurationPerformMigration(CFURLRef sourceDir, CFURLRef currentDir, if (sourceDir == NULL) { sourceDirConfig = CFRetain(currentSystemPath); } else { - sourceDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, sourceDir); + sourceDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, + PREFS_DEFAULT_DIR_RELATIVE, + kCFURLPOSIXPathStyle, + TRUE, + sourceDir); } if (currentDir != NULL) { - currentDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, currentDir); + currentDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, + PREFS_DEFAULT_DIR_RELATIVE, + kCFURLPOSIXPathStyle, + TRUE, + currentDir); } // If the targetDir is not provided then migration will take place in currentDir if (targetDir == NULL) { targetDirConfig = CFRetain(currentSystemPath); } else { - targetDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, targetDir); + targetDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, + PREFS_DEFAULT_DIR_RELATIVE, + kCFURLPOSIXPathStyle, + TRUE, + targetDir); } // Source directory cannot be the same as Target Directory if (CFEqual(sourceDirConfig, targetDirConfig)) { @@ -1291,52 +1289,6 @@ remove_service(const void *value, void *context) } } -static void -_SCNetworkConfigurationSaveOldConfiguration(SCPreferencesRef prefs) -{ - CFAbsoluteTime absoluteTime; - CFCalendarRef currentCalendar; - int day; - int hour; - CFStringRef keyList[] = { - kSCPrefCurrentSet, - MODEL, - kSCPrefNetworkServices, - kSCPrefSets, - kSCPrefSystem, - kSCPrefVirtualNetworkInterfaces - }; - CFIndex keyListCount; - int minute; - int month; - int second; - int year; - - currentCalendar = CFCalendarCopyCurrent(); - absoluteTime = CFAbsoluteTimeGetCurrent(); - - if (!CFCalendarDecomposeAbsoluteTime(currentCalendar, absoluteTime, "yMdHms", - &year, &month, &day, &hour, &minute, &second)) { - SC_log(LOG_INFO, "CFCalendarDecomposeAbsoluteTime() failed"); - } - keyListCount = (CFIndex)sizeof(keyList)/sizeof(CFStringRef); - - for (CFIndex idx = 0; idx < keyListCount; idx++) { - CFStringRef newKey; - CFTypeRef value = SCPreferencesGetValue(prefs, keyList[idx]); - - if (value != NULL) { - newKey = CFStringCreateWithFormat(NULL, NULL, - CFSTR("%d-%d-%d %d:%d:%d : %@"), - year, month, day, hour, - minute, second, keyList[idx]); - SCPreferencesSetValue(prefs, newKey, value); - CFRelease(newKey); - } - } - CFRelease(currentCalendar); -} - static Boolean _SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs, SCNetworkConfigurationValidityContext *context) @@ -1355,7 +1307,7 @@ _SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs, return FALSE; } // Backup current preferences before making changes - _SCNetworkConfigurationSaveOldConfiguration(prefs); + __SCNetworkConfigurationBackup(prefs); serviceList = SCNetworkServiceCopyAll(prefs); CFArrayApplyFunction(serviceList, CFRangeMake(0, CFArrayGetCount(serviceList)), create_bsd_name_service_protocol_mapping, context); @@ -1491,7 +1443,7 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs, CFStringRef model = NULL; CFStringRef ni_model = NULL; Boolean repairConfiguration = FALSE; - Boolean revertLimitNetworkConfiguration = FALSE; + Boolean revertBypassSystemInterfaces = FALSE; CFArrayRef setServiceOrder = NULL; CFArrayRef setServices = NULL; @@ -1501,9 +1453,9 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs, repairConfiguration = CFBooleanGetValue(repair); } } - if (!__SCPreferencesGetLimitSCNetworkConfiguration(prefs)) { - __SCPreferencesSetLimitSCNetworkConfiguration(prefs, TRUE); - revertLimitNetworkConfiguration = TRUE; + if (!_SCNetworkConfigurationBypassSystemInterfaces(prefs)) { + _SCNetworkConfigurationSetBypassSystemInterfaces(prefs, TRUE); + revertBypassSystemInterfaces = TRUE; } /* @@ -1719,8 +1671,8 @@ done: if (bsdNameServiceProtocolPreserveMapping != NULL) { CFRelease(bsdNameServiceProtocolPreserveMapping); } - if (revertLimitNetworkConfiguration) { - __SCPreferencesSetLimitSCNetworkConfiguration(prefs, FALSE); + if (revertBypassSystemInterfaces) { + _SCNetworkConfigurationSetBypassSystemInterfaces(prefs, FALSE); } return isValid; } @@ -1744,11 +1696,22 @@ _SCNetworkConfigurationCheckValidity(CFURLRef configDir, CFDictionaryRef options (configDir == NULL) ? CFSTR("NULL") : CFURLGetString(configDir)); goto done; } - baseURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, - kCFURLPOSIXPathStyle, TRUE, configDir); + baseURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, + PREFS_DEFAULT_DIR_RELATIVE, + kCFURLPOSIXPathStyle, + TRUE, + configDir); - configPreferenceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseURL); - configNetworkInterfaceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseURL); + configPreferenceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, + (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, + sizeof(PREFS_DEFAULT_CONFIG_PLIST), + FALSE, + baseURL); + configNetworkInterfaceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, + (const UInt8*)INTERFACES_DEFAULT_CONFIG_PLIST, + sizeof(INTERFACES_DEFAULT_CONFIG_PLIST), + FALSE, + baseURL); if (!CFURLGetFileSystemRepresentation(configPreferenceFile, TRUE, (UInt8*)prefsStr, sizeof(prefsStr))) { SC_log(LOG_NOTICE, "Cannot get file system representation for url: %@", configPreferenceFile); @@ -3195,7 +3158,7 @@ preserve_service_order(const void *key, const void *value, void *context) migrated_context.success = success; // Creating a list of service IDs which were migrated in the target set - // while maintaining the service order or the source set + // while maintaining the service order of the source set CFArrayApplyFunction(sourceServiceOrder, CFRangeMake(0, CFArrayGetCount(sourceServiceOrder)), create_migrated_order, &migrated_context); if (*success == FALSE) { goto done; @@ -3347,10 +3310,9 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD } } else { targetPrefs = __SCNetworkCreateDefaultPref(targetPreferencesFileString); - targetNetworkInterfacePrefs = __SCNetworkCreateDefaultNIPrefs(targetNetworkInterfaceFileString); + targetNetworkInterfacePrefs = __SCPreferencesCreateNIPrefsFromPrefs(targetPrefs); - if (targetPrefs == NULL || - targetNetworkInterfacePrefs == NULL) { + if ((targetPrefs == NULL) || (targetNetworkInterfacePrefs == NULL)) { SC_log(LOG_DEBUG, "Could not create default configuration"); goto done; } @@ -3370,8 +3332,8 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD targetNetworkInterfaceFileString); // Setting Bypass Interface to avoid looking at system interfaces - __SCPreferencesSetLimitSCNetworkConfiguration(sourcePrefs, TRUE); - __SCPreferencesSetLimitSCNetworkConfiguration(targetPrefs, TRUE); + _SCNetworkConfigurationSetBypassSystemInterfaces(sourcePrefs, TRUE); + _SCNetworkConfigurationSetBypassSystemInterfaces(targetPrefs, TRUE); sourceModel = SCPreferencesGetValue(sourcePrefs, MODEL); targetModel = SCPreferencesGetValue(targetPrefs, MODEL); @@ -3773,15 +3735,27 @@ _SCNetworkMigrationAreConfigurationsIdentical (CFURLRef configurationURL, expectedConfigurationURL == NULL) { return FALSE; } - baseConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, configurationURL); - configPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*) PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseConfigURL); + baseConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, + PREFS_DEFAULT_DIR_RELATIVE, + kCFURLPOSIXPathStyle, + TRUE, + configurationURL); + configPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, + (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, + sizeof(PREFS_DEFAULT_CONFIG_PLIST), + FALSE, + baseConfigURL); if (!CFURLResourceIsReachable(configPreferencesURL, NULL)) { SC_log(LOG_INFO, "No preferences.plist file"); goto done; } - configNetworkInterfacesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseConfigURL); + configNetworkInterfacesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, + (const UInt8*)INTERFACES_DEFAULT_CONFIG_PLIST, + sizeof(INTERFACES_DEFAULT_CONFIG_PLIST), + FALSE, + baseConfigURL); if (!CFURLResourceIsReachable(configNetworkInterfacesURL, NULL)) { SC_log(LOG_INFO, "No NetworkInterfaces.plist file"); @@ -3797,15 +3771,27 @@ _SCNetworkMigrationAreConfigurationsIdentical (CFURLRef configurationURL, goto done; } - baseExpectedConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, expectedConfigurationURL); - expectedPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseExpectedConfigURL); + baseExpectedConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, + PREFS_DEFAULT_DIR_RELATIVE, + kCFURLPOSIXPathStyle, + TRUE, + expectedConfigurationURL); + expectedPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, + (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, + sizeof(PREFS_DEFAULT_CONFIG_PLIST), + FALSE, + baseExpectedConfigURL); if (!CFURLResourceIsReachable(expectedPreferencesURL, NULL)) { SC_log(LOG_INFO, "No expected preferences.plist file"); goto done; } - expectedNetworkInterfaceURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseExpectedConfigURL); + expectedNetworkInterfaceURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, + (const UInt8*)INTERFACES_DEFAULT_CONFIG_PLIST, + sizeof(INTERFACES_DEFAULT_CONFIG_PLIST), + FALSE, + baseExpectedConfigURL); if (!CFURLResourceIsReachable(expectedNetworkInterfaceURL, NULL)) { SC_log(LOG_INFO, "No expected NetworkInterfaces.plist file"); @@ -3902,8 +3888,11 @@ _SCNetworkConfigurationCopyMigrationRemovePaths (CFArrayRef targetPaths, SC_log(LOG_NOTICE, "Cannot get file system representation for url: %@", affectedURL); continue; } - targetFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)filePath, - strnlen(filePath, sizeof(filePath)), FALSE, targetDir); + targetFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, + (const UInt8*)filePath, + strnlen(filePath, sizeof(filePath)), + FALSE, + targetDir); if (!CFURLResourceIsReachable(targetFile, NULL)) { CFArrayAppendValue(toBeRemoved, affectedURL); diff --git a/SystemConfiguration.fproj/SCNetworkProtocol.c b/SystemConfiguration.fproj/SCNetworkProtocol.c index d0cd41e..b09f20d 100644 --- a/SystemConfiguration.fproj/SCNetworkProtocol.c +++ b/SystemConfiguration.fproj/SCNetworkProtocol.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2008, 2016-2018 Apple Inc. All rights reserved. + * Copyright (c) 2004-2008, 2016-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -261,7 +261,7 @@ SCNetworkProtocolGetConfiguration(SCNetworkProtocolRef protocol) servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service; path = copyProtocolConfigurationPath(protocolPrivate); - config = __getPrefsConfiguration(servicePrivate->prefs, path); + config = __SCNetworkConfigurationGetValue(servicePrivate->prefs, path); CFRelease(path); return config; @@ -330,7 +330,7 @@ SCNetworkProtocolSetConfiguration(SCNetworkProtocolRef protocol, CFDictionaryRef } path = copyProtocolConfigurationPath(protocolPrivate); - ok = __setPrefsConfiguration(servicePrivate->prefs, path, config, TRUE); + ok = __SCNetworkConfigurationSetValue(servicePrivate->prefs, path, config, TRUE); CFRelease(path); if (ok) { diff --git a/SystemConfiguration.fproj/SCNetworkService.c b/SystemConfiguration.fproj/SCNetworkService.c index d9c8d4b..c643116 100644 --- a/SystemConfiguration.fproj/SCNetworkService.c +++ b/SystemConfiguration.fproj/SCNetworkService.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2018 Apple Inc. All rights reserved. + * Copyright (c) 2004-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -34,8 +34,11 @@ #include "SCNetworkConfigurationInternal.h" #include "SCPreferencesInternal.h" +#include #include +#include + #define EXTERNAL_ID_DOMAIN_PREFIX "_" static CFStringRef __SCNetworkServiceCopyDescription (CFTypeRef cf); @@ -424,7 +427,7 @@ SCNetworkServiceAddProtocolType(SCNetworkServiceRef service, CFStringRef protoco newEntity = _protocolTemplate(service, protocolType); assert(newEntity != NULL); - + ok = SCNetworkProtocolSetConfiguration(protocol, newEntity); if (!ok) { // could not set default configuration @@ -460,6 +463,7 @@ SCNetworkServiceCopyAll(SCPreferencesRef prefs) CFStringRef path; CFDictionaryRef services; + path = SCPreferencesPathKeyCreateNetworkServices(NULL); services = SCPreferencesPathGetValue(prefs, path); CFRelease(path); @@ -977,6 +981,91 @@ SCNetworkServiceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef interface) } +static CF_RETURNS_RETAINED CFStringRef +copyInterfaceUUID(CFStringRef bsdName) +{ + union { + unsigned char sha256_bytes[CC_SHA256_DIGEST_LENGTH]; + CFUUIDBytes uuid_bytes; + } bytes; + CC_SHA256_CTX ctx; + char if_name[IF_NAMESIZE]; + CFUUIDRef uuid; + CFStringRef uuid_str; + + // start with interface name + memset(&if_name, 0, sizeof(if_name)); + (void) _SC_cfstring_to_cstring(bsdName, + if_name, + sizeof(if_name), + kCFStringEncodingASCII); + + // create SHA256 hash + memset(&bytes, 0, sizeof(bytes)); + CC_SHA256_Init(&ctx); + CC_SHA256_Update(&ctx, + if_name, + sizeof(if_name)); + CC_SHA256_Final(bytes.sha256_bytes, &ctx); + + // create UUID string + uuid = CFUUIDCreateFromUUIDBytes(NULL, bytes.uuid_bytes); + uuid_str = CFUUIDCreateString(NULL, uuid); + CFRelease(uuid); + + return uuid_str; +} + + +SCNetworkServiceRef +_SCNetworkServiceCreatePreconfigured(SCPreferencesRef prefs, SCNetworkInterfaceRef interface) +{ + CFStringRef bsdName; + Boolean ok; + SCNetworkServiceRef service; + CFStringRef serviceID; + + bsdName = SCNetworkInterfaceGetBSDName(interface); + + // create network service + service = SCNetworkServiceCreate(prefs, interface); + if (service == NULL) { + SC_log(LOG_ERR, "could not create network service for \"%@\": %s", + bsdName, + SCErrorString(SCError())); + return NULL; + } + + // update network service to use a consistent serviceID + serviceID = copyInterfaceUUID(bsdName); + if (serviceID != NULL) { + ok = _SCNetworkServiceSetServiceID(service, serviceID); + CFRelease(serviceID); + if (!ok) { + SC_log(LOG_ERR, "_SCNetworkServiceSetServiceID() failed: %s", + SCErrorString(SCError())); + // ... and keep whatever random UUID was created for the service + } + } else { + SC_log(LOG_ERR, "could not create serviceID for \"%@\"", bsdName); + // ... and we'll use whatever random UUID was created for the service + } + + // establish [template] configuration + ok = SCNetworkServiceEstablishDefaultConfiguration(service); + if (!ok) { + SC_log(LOG_ERR, "could not establish network service for \"%@\": %s", + bsdName, + SCErrorString(SCError())); + SCNetworkServiceRemove(service); + CFRelease(service); + service = NULL; + } + + return service; +} + + Boolean SCNetworkServiceEstablishDefaultConfiguration(SCNetworkServiceRef service) { @@ -1115,8 +1204,7 @@ SCNetworkServiceGetName(SCNetworkServiceRef service) entity = SCPreferencesPathGetValue(servicePrivate->prefs, path); CFRelease(path); - useSystemInterfaces = ((__SCPreferencesUsingDefaultPrefs(servicePrivate->prefs)) && - !__SCPreferencesGetLimitSCNetworkConfiguration(servicePrivate->prefs)); + useSystemInterfaces = !_SCNetworkConfigurationBypassSystemInterfaces(servicePrivate->prefs); if (isA_CFDictionary(entity)) { name = CFDictionaryGetValue(entity, kSCPropUserDefinedName); diff --git a/SystemConfiguration.fproj/SCP.c b/SystemConfiguration.fproj/SCP.c index 2e223eb..80181cf 100644 --- a/SystemConfiguration.fproj/SCP.c +++ b/SystemConfiguration.fproj/SCP.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, 2003-2005, 2007-2009, 2011, 2014-2018 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2003-2005, 2007-2009, 2011, 2014-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -61,6 +61,29 @@ __SCPSignatureFromStatbuf(const struct stat *statBuf) } +__private_extern__ +uint32_t +__SCPreferencesGetNetworkConfigurationFlags(SCPreferencesRef prefs) +{ + SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; + + return (prefs != NULL) ? prefsPrivate->nc_flags : 0; +} + +__private_extern__ +void +__SCPreferencesSetNetworkConfigurationFlags(SCPreferencesRef prefs, uint32_t nc_flags) +{ + SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; + + if (prefs != NULL) { + prefsPrivate->nc_flags = nc_flags; + } + + return; +} + + __private_extern__ char * __SCPreferencesPath(CFAllocatorRef allocator, CFStringRef prefsID, @@ -119,19 +142,6 @@ __SCPreferencesPath(CFAllocatorRef allocator, } -__private_extern__ -Boolean -__SCPreferencesGetLimitSCNetworkConfiguration(SCPreferencesRef prefs) -{ - SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; - - if (prefs == NULL) { - return FALSE; - } - return prefsPrivate->limit_SCNetworkConfiguration; -} - - __private_extern__ off_t __SCPreferencesPrefsSize(SCPreferencesRef prefs) @@ -179,31 +189,13 @@ __private_extern__ SCPreferencesRef __SCPreferencesCreateNIPrefsFromPrefs(SCPreferencesRef prefs) { - CFMutableStringRef newPath = NULL; - CFURLRef newURL = NULL; - SCPreferencesRef ni_prefs = NULL; - SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; - char * prefsPath = __SCPreferencesPath(NULL, prefsPrivate->prefsID, FALSE); - - - newPath = CFStringCreateMutable(NULL, 0); - CFStringAppendFormat(newPath, NULL, CFSTR("%s"), prefsPath); + SCPreferencesRef ni_prefs; - CFStringFindAndReplace(newPath, - PREFS_DEFAULT_CONFIG, - NETWORK_INTERFACES_PREFS, - CFRangeMake(0, CFStringGetLength(newPath)), - kCFCompareBackwards); + // open [companion] NetworkInterfaces.plist + ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG); - newURL = CFURLCreateWithFileSystemPath(NULL, newPath, kCFURLPOSIXPathStyle, FALSE); - if (!CFURLResourceIsReachable(newURL, NULL)) { - ni_prefs = __SCNetworkCreateDefaultNIPrefs(newPath); - } else { - ni_prefs = SCPreferencesCreate(NULL, prefsPrivate->name, newPath); - } - CFAllocatorDeallocate(NULL, prefsPath); - CFRelease(newPath); - CFRelease(newURL); + // if needed, populate + __SCNetworkPopulateDefaultNIPrefs(ni_prefs); return ni_prefs; } @@ -280,15 +272,3 @@ SCDynamicStoreKeyCreatePreferences(CFAllocatorRef allocator, return _SCPNotificationKey(allocator, prefsID, keyType); } - -__private_extern__ void -__SCPreferencesSetLimitSCNetworkConfiguration(SCPreferencesRef prefs, - Boolean limit_SCNetworkConfiguration) -{ - SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; - - if (prefs == NULL) { - return; - } - prefsPrivate->limit_SCNetworkConfiguration = limit_SCNetworkConfiguration; -} diff --git a/SystemConfiguration.fproj/SCPCommit.c b/SystemConfiguration.fproj/SCPCommit.c index 42b9890..fa358df 100644 --- a/SystemConfiguration.fproj/SCPCommit.c +++ b/SystemConfiguration.fproj/SCPCommit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008, 2010-2013, 2015-2018 Apple Inc. All rights reserved. + * Copyright (c) 2000-2008, 2010-2013, 2015-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -332,9 +332,14 @@ SCPreferencesCommitChanges(SCPreferencesRef prefs) committed : - SC_log(LOG_INFO, "SCPreferences() commit: %s, size=%lld", - prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path, - __SCPreferencesPrefsSize(prefs)); + if (prefsPrivate->changed) { + SC_log(LOG_INFO, "SCPreferences() commit: %s, size=%lld", + prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path, + __SCPreferencesPrefsSize(prefs)); + } else { + SC_log(LOG_INFO, "SCPreferences() commit: %s, w/no changes", + prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path); + } /* post notification */ ok = SCDynamicStoreNotifyValue(NULL, prefsPrivate->sessionKeyCommit); diff --git a/SystemConfiguration.fproj/SCPOpen.c b/SystemConfiguration.fproj/SCPOpen.c index 05ef3a3..ebaddeb 100644 --- a/SystemConfiguration.fproj/SCPOpen.c +++ b/SystemConfiguration.fproj/SCPOpen.c @@ -1,5 +1,5 @@ /* - * Copyright(c) 2000-2019 Apple Inc. All rights reserved. + * Copyright(c) 2000-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -65,13 +65,6 @@ __log_SCPreferences(void) } -static __inline__ CFTypeRef -isA_SCPreferences(CFTypeRef obj) -{ - return (isA_CFType(obj, SCPreferencesGetTypeID())); -} - - static CFStringRef __SCPreferencesCopyDescription(CFTypeRef cf) { CFAllocatorRef allocator = CFGetAllocator(cf); @@ -119,6 +112,19 @@ __SCPreferencesDeallocate(CFTypeRef cf) pthread_mutex_destroy(&prefsPrivate->lock); + if (prefsPrivate->parent != NULL) { + SCPreferencesPrivateRef parentPrivate = (SCPreferencesPrivateRef)prefsPrivate->parent; + + // remove [weak] reference from parent to this companion + pthread_mutex_lock(&parentPrivate->lock); + CFDictionaryRemoveValue(parentPrivate->companions, prefsPrivate->prefsID); + pthread_mutex_unlock(&parentPrivate->lock); + + // remove [strong] reference from companion to parent + CFRelease(prefsPrivate->parent); + } + if (prefsPrivate->companions != NULL) CFRelease(prefsPrivate->companions); + if (prefsPrivate->name) CFRelease(prefsPrivate->name); if (prefsPrivate->prefsID) CFRelease(prefsPrivate->prefsID); if (prefsPrivate->options) CFRelease(prefsPrivate->options); @@ -662,8 +668,7 @@ SCPreferencesCreateWithOptions(CFAllocatorRef allocator, if (authorization != NULL) { CFMutableDictionaryRef authorizationDict; - CFBundleRef bundle; - CFStringRef bundleID = NULL; + CFStringRef bundleID; authorizationDict = CFDictionaryCreateMutable(NULL, 0, @@ -691,36 +696,10 @@ SCPreferencesCreateWithOptions(CFAllocatorRef allocator, } #endif // !TARGET_OS_IPHONE - /* get the application/executable/bundle name */ - bundle = CFBundleGetMainBundle(); - if (bundle != NULL) { - bundleID = CFBundleGetIdentifier(bundle); - if (bundleID != NULL) { - CFRetain(bundleID); - } else { - CFURLRef url; - - url = CFBundleCopyExecutableURL(bundle); - if (url != NULL) { - bundleID = CFURLCopyPath(url); - CFRelease(url); - } - } - - if (bundleID != NULL) { - if (CFEqual(bundleID, CFSTR("/"))) { - CFRelease(bundleID); - bundleID = NULL; - } - } - } - if (bundleID == NULL) { - bundleID = CFStringCreateWithFormat(NULL, NULL, CFSTR("Unknown(%d)"), getpid()); - } + bundleID = _SC_getApplicationBundleID(); CFDictionaryAddValue(authorizationDict, kSCHelperAuthCallerInfo, bundleID); - CFRelease(bundleID); if (authorizationDict != NULL) { (void) _SCSerialize((CFPropertyListRef)authorizationDict, @@ -761,6 +740,119 @@ SCPreferencesCreateWithOptions(CFAllocatorRef allocator, } +SCPreferencesRef +SCPreferencesCreateCompanion(SCPreferencesRef prefs, CFStringRef companionPrefsID) +{ + CFAllocatorRef allocator = CFGetAllocator(prefs); + SCPreferencesPrivateRef companionPrefs = NULL; + CFMutableStringRef newPrefsID; + SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; + + if (companionPrefsID == NULL) { + companionPrefsID = PREFS_DEFAULT_CONFIG; + } else { + if (CFStringFindWithOptions(companionPrefsID, + CFSTR("/"), + CFRangeMake(0, CFStringGetLength(companionPrefsID)), + kCFCompareBackwards, + NULL)) { + // if companion prefsID contains a "/" + _SCErrorSet(kSCStatusInvalidArgument); + return NULL; + } + } + + if (prefsPrivate->prefsID == NULL) { + if (CFEqual(companionPrefsID, PREFS_DEFAULT_CONFIG)) { + // if prefsID and companionPrefsID match + _SCErrorSet(kSCStatusInvalidArgument); + return NULL; + } + newPrefsID = CFStringCreateMutableCopy(allocator, 0, companionPrefsID); + } else { + CFIndex prefsIDLen = CFStringGetLength(prefsPrivate->prefsID); + CFRange range; + + if (CFStringFindWithOptions(prefsPrivate->prefsID, + CFSTR("/"), + CFRangeMake(0, prefsIDLen), + kCFCompareBackwards, + &range)) { + Boolean match; + CFStringRef suffix; + + // if slash, check suffix + range.location++; + if (range.location >= prefsIDLen) { + // if no suffix + _SCErrorSet(kSCStatusInvalidArgument); + return NULL; + } + range.length = prefsIDLen - range.location; + suffix = CFStringCreateWithSubstring(allocator, prefsPrivate->prefsID, range); + match = CFEqual(suffix, companionPrefsID); + CFRelease(suffix); + if (match) { + // if prefsID [suffix] and companionPrefsID match + _SCErrorSet(kSCStatusInvalidArgument); + return NULL; + } + + // replace the suffix + newPrefsID = CFStringCreateMutableCopy(NULL, 0, prefsPrivate->prefsID); + CFStringReplace(newPrefsID, range, companionPrefsID); + } else if (!CFEqual(prefsPrivate->prefsID, companionPrefsID)) { + // if no slash, prefsID and companionPrefsID differ + newPrefsID = CFStringCreateMutableCopy(NULL, 0, companionPrefsID); + } else { + // if no slash, prefsID and companionPrefsID match + _SCErrorSet(kSCStatusInvalidArgument); + return NULL; + } + } + assert(newPrefsID != NULL); + + pthread_mutex_lock(&prefsPrivate->lock); + if ((prefsPrivate->companions != NULL) && + CFDictionaryGetValueIfPresent(prefsPrivate->companions, + newPrefsID, + (const void **)&companionPrefs) && + (companionPrefs != NULL)) { + // if we already have a companion + SC_log(LOG_DEBUG, "create [companion] reference %@", companionPrefs); + CFRetain(companionPrefs); + } else { + companionPrefs = __SCPreferencesCreate(allocator, + prefsPrivate->name, + newPrefsID, + prefsPrivate->authorizationData, + prefsPrivate->options); + if (companionPrefs != NULL) { + SCPreferencesPrivateRef companionPrefsPrivate = (SCPreferencesPrivateRef)companionPrefs; + + SC_log(LOG_DEBUG, "create [companion] %@", companionPrefs); + + // add [strong] reference from companion to parent + companionPrefsPrivate->parent = CFRetain(prefs); + + // add [weak] reference from parent to this companion + if (prefsPrivate->companions == NULL) { + prefsPrivate->companions = CFDictionaryCreateMutable(NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + NULL); + } + CFDictionarySetValue(prefsPrivate->companions, newPrefsID, companionPrefs); + } + } + pthread_mutex_unlock(&prefsPrivate->lock); + + CFRelease(newPrefsID); + + return (SCPreferencesRef)companionPrefs; +} + + CFTypeID SCPreferencesGetTypeID(void) { pthread_once(&initialized, __SCPreferencesInitialize); /* initialize runtime */ diff --git a/SystemConfiguration.fproj/SCPreferencesInternal.h b/SystemConfiguration.fproj/SCPreferencesInternal.h index 4201dc4..af98043 100644 --- a/SystemConfiguration.fproj/SCPreferencesInternal.h +++ b/SystemConfiguration.fproj/SCPreferencesInternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, 2003-2005, 2007-2011, 2013-2018 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2003-2005, 2007-2011, 2013-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -44,15 +44,22 @@ #include -#define PREFS_DEFAULT_DIR CFSTR("/Library/Preferences/SystemConfiguration") -#define PREFS_DEFAULT_CONFIG CFSTR("preferences.plist") +#define PREFS_DEFAULT_DIR_PATH_RELATIVE "Library/Preferences/SystemConfiguration" +#define PREFS_DEFAULT_DIR_RELATIVE CFSTR(PREFS_DEFAULT_DIR_PATH_RELATIVE "/") + +#define PREFS_DEFAULT_DIR_PATH "/" PREFS_DEFAULT_DIR_PATH_RELATIVE +#define PREFS_DEFAULT_DIR CFSTR(PREFS_DEFAULT_DIR_PATH) + +#define PREFS_DEFAULT_CONFIG_PLIST "preferences.plist" +#define PREFS_DEFAULT_CONFIG CFSTR(PREFS_DEFAULT_CONFIG_PLIST) #define PREFS_DEFAULT_DIR_OLD CFSTR("/var/db/SystemConfiguration") #define PREFS_DEFAULT_CONFIG_OLD CFSTR("preferences.xml") #define PREFS_DEFAULT_USER_DIR CFSTR("Library/Preferences") -#define NETWORK_INTERFACES_PREFS CFSTR("NetworkInterfaces.plist") +#define INTERFACES_DEFAULT_CONFIG_PLIST "NetworkInterfaces.plist" +#define INTERFACES_DEFAULT_CONFIG CFSTR(INTERFACES_DEFAULT_CONFIG_PLIST) #define INTERFACES CFSTR("Interfaces") @@ -108,11 +115,15 @@ typedef struct { /* preferences */ CFMutableDictionaryRef prefs; + /* companion preferences, manipulate under lock */ + SCPreferencesRef parent; // [strong] reference from companion to parent + CFMutableDictionaryRef companions; // [weak] reference from parent to companions + /* flags */ Boolean accessed; Boolean changed; Boolean isRoot; - Boolean limit_SCNetworkConfiguration; + uint32_t nc_flags; // SCNetworkConfiguration flags /* authorization, helper */ CFDataRef authorizationData; @@ -133,6 +144,12 @@ typedef struct { __BEGIN_DECLS +static __inline__ CFTypeRef +isA_SCPreferences(CFTypeRef obj) +{ + return (isA_CFType(obj, SCPreferencesGetTypeID())); +} + os_log_t __log_SCPreferences (void); @@ -172,16 +189,18 @@ CFStringRef _SCPNotificationKey (CFAllocatorRef allocator, CFStringRef prefsID, int keyType); -Boolean -__SCPreferencesGetLimitSCNetworkConfiguration (SCPreferencesRef prefs); + +uint32_t +__SCPreferencesGetNetworkConfigurationFlags + (SCPreferencesRef prefs); void -__SCPreferencesSetLimitSCNetworkConfiguration +__SCPreferencesSetNetworkConfigurationFlags (SCPreferencesRef prefs, - Boolean limit_SCNetworkConfiguration); + uint32_t nc_flags); Boolean -__SCPreferencesUsingDefaultPrefs (SCPreferencesRef prefs); +__SCPreferencesUsingDefaultPrefs (SCPreferencesRef prefs); SCPreferencesRef __SCPreferencesCreateNIPrefsFromPrefs (SCPreferencesRef prefs); diff --git a/SystemConfiguration.fproj/SCPreferencesPrivate.h b/SystemConfiguration.fproj/SCPreferencesPrivate.h index eabdba3..86230ca 100644 --- a/SystemConfiguration.fproj/SCPreferencesPrivate.h +++ b/SystemConfiguration.fproj/SCPreferencesPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005, 2007-2009, 2011, 2012, 2017, 2018 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2007-2009, 2011, 2012, 2017-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -122,6 +122,22 @@ SCDynamicStoreKeyCreatePreferences ( SCPreferencesKeyType keyType ) API_DEPRECATED("No longer supported", macos(10.1,10.4), ios(2.0,2.0)); +/*! + @function SCPreferencesCreateCompanion + @discussion Initiates access to a [companion] of the configuration + preferences. + @param prefs The base preferences session. + @param companionPrefsID A string that identifies the companion name + of the group of preferences to be accessed or updated. + @result Returns a reference to the new SCPreferences. + You must release the returned value. +*/ +SCPreferencesRef +SCPreferencesCreateCompanion ( + SCPreferencesRef prefs, + CFStringRef companionPrefsID + ) SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0)); + /*! @function SCPreferencesCreateWithOptions @discussion Initiates access to the per-system set of configuration diff --git a/SystemConfiguration.fproj/SCPrivate.h b/SystemConfiguration.fproj/SCPrivate.h index f9bf278..b721acd 100644 --- a/SystemConfiguration.fproj/SCPrivate.h +++ b/SystemConfiguration.fproj/SCPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2019 Apple Inc. All rights reserved. + * Copyright (c) 2000-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -106,7 +106,8 @@ extern int _sc_debug; /* non-zero if debugging enabled */ extern int _sc_verbose; /* non-zero if verbose logging enabled */ extern int _sc_log; /* 0 if SC messages should be written to stdout/stderr, 1 if SC messages should be logged w/os_log(3), - 2 if SC messages should be written to stdout/stderr AND logged */ + 2 if SC messages should be logged AND written to stdout/stderr + 3 if SC messages should be logged AND written to stdout/stderr (w/o timestamp) */ /* notify(3) keys */ @@ -767,6 +768,9 @@ _SC_dos_encoding_and_codepage (CFStringEncoding macEncoding, #pragma mark Bundle +CFStringRef +_SC_getApplicationBundleID (void); + /* * bundle access */ diff --git a/SystemConfiguration.fproj/SCSchemaDefinitions.c b/SystemConfiguration.fproj/SCSchemaDefinitions.c index ebb53ab..3d3ee59 100644 --- a/SystemConfiguration.fproj/SCSchemaDefinitions.c +++ b/SystemConfiguration.fproj/SCSchemaDefinitions.c @@ -19,6 +19,7 @@ const CFStringRef kSCPrefCurrentSet = CFSTR("Curr const CFStringRef kSCPrefNetworkServices = CFSTR("NetworkServices"); const CFStringRef kSCPrefSets = CFSTR("Sets"); const CFStringRef kSCPrefSystem = CFSTR("System"); +const CFStringRef kSCPrefVersion = CFSTR("__VERSION__"); const CFStringRef kSCPrefVirtualNetworkInterfaces = CFSTR("VirtualNetworkInterfaces"); const CFStringRef kSCCompNetwork = CFSTR("Network"); const CFStringRef kSCCompService = CFSTR("Service"); diff --git a/SystemConfiguration.fproj/SCSchemaDefinitions.h b/SystemConfiguration.fproj/SCSchemaDefinitions.h index 94d61c9..012652a 100644 --- a/SystemConfiguration.fproj/SCSchemaDefinitions.h +++ b/SystemConfiguration.fproj/SCSchemaDefinitions.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2019 Apple Inc. All rights reserved. + * Copyright (c) 2000-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * diff --git a/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h b/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h index 35b00fd..ad84324 100644 --- a/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h +++ b/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2019 Apple Inc. All rights reserved. + * Copyright (c) 2000-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -35,6 +35,7 @@ * * Preference Keys * + * kSCPrefVersion "__VERSION__" CFString * kSCPrefVirtualNetworkInterfaces "VirtualNetworkInterfaces" CFDictionary * * Network Entity Keys @@ -355,6 +356,13 @@ extern const CFStringRef kSCPropDisableUntilNeeded API_ @group Preference Keys */ +/*! + @const kSCPrefVersion + @discussion Value is a CFString + */ +extern const CFStringRef kSCPrefVersion API_AVAILABLE(macos(10.15.4)) SPI_AVAILABLE(ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0)); +#define kSCPrefVersion kSCPrefVersion + /*! @const kSCPrefVirtualNetworkInterfaces @discussion Value is a CFDictionary diff --git a/SystemConfiguration.fproj/genSCPreferences.c b/SystemConfiguration.fproj/genSCPreferences.c index 07ba693..c9ed85f 100644 --- a/SystemConfiguration.fproj/genSCPreferences.c +++ b/SystemConfiguration.fproj/genSCPreferences.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2019 Apple Inc. All rights reserved. + * Copyright (c) 2000-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -62,7 +62,7 @@ char copyright_string[] = "/*\n" -" * Copyright (c) 2000-2019 Apple Inc. All rights reserved.\n" +" * Copyright (c) 2000-2020 Apple Inc. All rights reserved.\n" " *\n" " * @APPLE_LICENSE_HEADER_START@\n" " *\n" @@ -129,6 +129,7 @@ typedef enum { SC_10_13_IPHONE_11_0_PRIVATE, SC_10_14_IPHONE_12_0_PRIVATE, SC_10_15_IPHONE_13_0_PRIVATE, + SC_10_15_4_IPHONE_13_4_PRIVATE, SC_IPHONE_2_0_PRIVATE, SC_IPHONE_7_0_PRIVATE, SC_IPHONE_8_0_PRIVATE, @@ -563,6 +564,7 @@ static schemaDefinition names[] = { { GROUP_PRIVATE, PREF, "Preference Keys", NULL, NULL }, + { SC_10_15_4_IPHONE_13_4_PRIVATE, PREF, VERSION, "__VERSION__", CFSTRING }, { SC_10_5_PRIVATE, PREF, VIRTUALNETWORKINTERFACES, NULL, CFDICTIONARY }, { COMMENT_PRIVATE, "", NULL, NULL, NULL }, @@ -1519,6 +1521,9 @@ print_headerdoc(schemaDefinition *def) case SC_10_15_IPHONE_13_0_PRIVATE: printf(" API_AVAILABLE(macos(10.15)) SPI_AVAILABLE(ios(13.0), tvos(13.0), watchos(6.0), bridgeos(4.0));\n"); break; + case SC_10_15_4_IPHONE_13_4_PRIVATE: + printf(" API_AVAILABLE(macos(10.15.4)) SPI_AVAILABLE(ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));\n"); + break; case SC_IPHONE_2_0_PRIVATE: printf(" SPI_AVAILABLE(macos(10.6), ios(2.0), tvos(9.0), watchos(1.0), bridgeos(1.0));\n"); break; @@ -1707,6 +1712,7 @@ dump_names(int type) case SC_10_13_IPHONE_11_0_PRIVATE: case SC_10_14_IPHONE_12_0_PRIVATE: case SC_10_15_IPHONE_13_0_PRIVATE: + case SC_10_15_4_IPHONE_13_4_PRIVATE: case SC_IPHONE_2_0_PRIVATE: case SC_IPHONE_7_0_PRIVATE: case SC_IPHONE_8_0_PRIVATE: @@ -1746,6 +1752,7 @@ dump_names(int type) case SC_10_13_IPHONE_11_0_PRIVATE: case SC_10_14_IPHONE_12_0_PRIVATE: case SC_10_15_IPHONE_13_0_PRIVATE: + case SC_10_15_4_IPHONE_13_4_PRIVATE: case SC_IPHONE_2_0_PRIVATE: case SC_IPHONE_7_0_PRIVATE: case SC_IPHONE_8_0_PRIVATE: @@ -1776,6 +1783,7 @@ dump_names(int type) case SC_10_13_IPHONE_11_0_PRIVATE: case SC_10_14_IPHONE_12_0_PRIVATE: case SC_10_15_IPHONE_13_0_PRIVATE: + case SC_10_15_4_IPHONE_13_4_PRIVATE: case SC_IPHONE_2_0_PRIVATE: case SC_IPHONE_7_0_PRIVATE: case SC_IPHONE_8_0_PRIVATE: @@ -1804,6 +1812,7 @@ dump_names(int type) case SC_10_13_IPHONE_11_0_PRIVATE: case SC_10_14_IPHONE_12_0_PRIVATE: case SC_10_15_IPHONE_13_0_PRIVATE: + case SC_10_15_4_IPHONE_13_4_PRIVATE: case SC_IPHONE_2_0_PRIVATE: case SC_IPHONE_7_0_PRIVATE: case SC_IPHONE_8_0_PRIVATE: diff --git a/configd.xcodeproj/project.pbxproj b/configd.xcodeproj/project.pbxproj index 5cc8c6d..6d1d504 100644 --- a/configd.xcodeproj/project.pbxproj +++ b/configd.xcodeproj/project.pbxproj @@ -289,6 +289,9 @@ 152439E8180399D800D91708 /* CoreWLAN.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 152439E7180399D800D91708 /* CoreWLAN.framework */; }; 152439E91805CC6C00D91708 /* ev_extra.h in Headers */ = {isa = PBXBuildFile; fileRef = 152439E318038E5B00D91708 /* ev_extra.h */; }; 152439EA1805CC8400D91708 /* ev_extra.m in Sources */ = {isa = PBXBuildFile; fileRef = 152439E418038E5B00D91708 /* ev_extra.m */; }; + 15260A452272529F00AE1F72 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; }; + 15260A462272533D00AE1F72 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; }; + 15260A472272535F00AE1F72 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1559C4440D349A4E0098FD59 /* SystemConfiguration.framework */; }; 152691DB1129EEA6006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; }; 152691DC1129EEAD006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; }; 152691DE1129EEC2006BD2D5 /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; }; @@ -696,6 +699,9 @@ 159A752C107FEAA400A57EAB /* VPNPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 159A7517107FEAA400A57EAB /* VPNPrivate.c */; }; 159A752E107FEAA400A57EAB /* VPNConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 159A7519107FEAA400A57EAB /* VPNConfiguration.c */; }; 159C32B60F583724008A72EE /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; }; + 159C80B0219378710004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 15D427212166F6F50082AA78 /* SCNetworkConfigurationPrivate.c */; }; + 159C80B1219378760004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 15D427212166F6F50082AA78 /* SCNetworkConfigurationPrivate.c */; }; + 159C80B2219378790004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 15D427212166F6F50082AA78 /* SCNetworkConfigurationPrivate.c */; }; 159D540D07528DAE004F8947 /* ev_dlil.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53B107528B36004F8947 /* ev_dlil.c */; }; 159D540E07528DAE004F8947 /* ev_dlil.h in Headers */ = {isa = PBXBuildFile; fileRef = 159D53B207528B36004F8947 /* ev_dlil.h */; }; 159D540F07528DB0004F8947 /* ev_ipv4.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53B307528B36004F8947 /* ev_ipv4.c */; }; @@ -856,6 +862,9 @@ 15C330D1134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; }; 15C330D2134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; }; 15C330D3134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; }; + 15C7B7C7224D9A9A0040A8D0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15C7B7C6224D9A9A0040A8D0 /* CoreFoundation.framework */; }; + 15C7B7C9224D9AA70040A8D0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15C7B7C8224D9AA70040A8D0 /* Foundation.framework */; }; + 15C7B7CB224D9AAE0040A8D0 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15C7B7CA224D9AAE0040A8D0 /* SystemConfiguration.framework */; }; 15CB8F701EE4DCFC00726685 /* network_state_information_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */; }; 15CB8F711EE4DCFF00726685 /* network_state_information_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */; }; 15CB8F721EE4DD0400726685 /* network_state_information_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */; }; @@ -1009,7 +1018,6 @@ 15E56C5B21939B7B00088C51 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15E56C5A21939B7B00088C51 /* Foundation.framework */; }; 15E56C5C21939B8E00088C51 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15E56C5A21939B7B00088C51 /* Foundation.framework */; }; 15E91DB721893E83001155DC /* test-objC.m in Sources */ = {isa = PBXBuildFile; fileRef = 72D3E66B1AE6EAF600DB4C69 /* test-objC.m */; }; - 15E91DB921893E83001155DC /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; }; 15E91DD021893EE1001155DC /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72D3E6601AE6EA3A00DB4C69 /* main.swift */; }; 15EF899F21894452003B2C5C /* SCNetworkInterfaceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = F90E43542012AD3900EF27C4 /* SCNetworkInterfaceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; }; 15EF89A021894533003B2C5C /* SNHelperPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = B0C967F717441F0E00889853 /* SNHelperPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -1028,6 +1036,10 @@ 15F742EA1EC638D100DA2E7A /* liblog_SystemConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 151D060D1EC14C6700E02E48 /* liblog_SystemConfiguration.m */; }; 15F742EC1EC638D100DA2E7A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; }; 15F742ED1EC638D100DA2E7A /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72573D331D66800C004975AD /* SystemConfiguration.framework */; }; + 15FA163A23C6341100573B3C /* SCTestInterfaceNamer.m in Sources */ = {isa = PBXBuildFile; fileRef = 15FA163923C6341100573B3C /* SCTestInterfaceNamer.m */; }; + 15FA163D23C67A9800573B3C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FA163C23C67A9800573B3C /* IOKit.framework */; }; + 15FA163F23C67AAF00573B3C /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FA163E23C67AAF00573B3C /* Network.framework */; }; + 15FA164123C67AF100573B3C /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FA163E23C67AAF00573B3C /* Network.framework */; }; 15FB1F8A1E27EA8700B4F809 /* InterfaceNamerControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FB1F881E27E9A000B4F809 /* InterfaceNamerControlPrefs.c */; }; 15FB1F8B1E27EA8900B4F809 /* InterfaceNamerControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FB1F881E27E9A000B4F809 /* InterfaceNamerControlPrefs.c */; }; 15FBB54C17D6834C0035D752 /* libCrashReporterClient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 15FBB54B17D6834C0035D752 /* libCrashReporterClient.a */; }; @@ -1056,7 +1068,6 @@ 72573D3E1D669AA6004975AD /* SCTestPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D3D1D669AA6004975AD /* SCTestPreferences.m */; }; 72573D401D67B2BE004975AD /* SCTestUnitTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D3F1D67B2BE004975AD /* SCTestUnitTest.m */; }; 72573D421D6B798A004975AD /* SCTestConfigAgents.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D411D6B7989004975AD /* SCTestConfigAgents.m */; }; - 72573D441D6BA051004975AD /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015951BE16B6C009F4F60 /* Network.framework */; }; 725CB7551BF439C6000C05A8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; }; 725CB7561BF439D2000C05A8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 725CB7541BF439C6000C05A8 /* Foundation.framework */; }; 725CB7581BF514F2000C05A8 /* configAgentDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 725CB7571BF51476000C05A8 /* configAgentDefines.h */; }; @@ -1074,7 +1085,6 @@ 7271EA241D76600B0055B1AA /* SCTestConfigAgents.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D411D6B7989004975AD /* SCTestConfigAgents.m */; }; 7271EA251D76600B0055B1AA /* SCTestPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D3D1D669AA6004975AD /* SCTestPreferences.m */; }; 7271EA261D76600B0055B1AA /* SCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 72573D2D1D6673B6004975AD /* SCTest.m */; }; - 7271EA291D76600B0055B1AA /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015951BE16B6C009F4F60 /* Network.framework */; }; 7271EA2A1D76600B0055B1AA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72573D331D66800C004975AD /* SystemConfiguration.framework */; }; 7271EA2B1D76600B0055B1AA /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 728015961BE16B6C009F4F60 /* NetworkExtension.framework */; }; 7271EA2D1D76600B0055B1AA /* npt_configd.plist in npt_configd.plist */ = {isa = PBXBuildFile; fileRef = 72C12CAA1D6E9ED4000EE61C /* npt_configd.plist */; }; @@ -2002,12 +2012,12 @@ 151D060D1EC14C6700E02E48 /* liblog_SystemConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = liblog_SystemConfiguration.m; path = logging/liblog_SystemConfiguration.m; sourceTree = SOURCE_ROOT; }; 151F5D9A0CCE98E50093AC3B /* SCMonitor.plugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SCMonitor.plugin; sourceTree = BUILT_PRODUCTS_DIR; }; 151F63EC09328A3C0096DCC9 /* genSCPreferences */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = genSCPreferences; sourceTree = BUILT_PRODUCTS_DIR; }; - 1520A3DE0846B2DC0010B584 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = ""; }; + 1520A3DE0846B2DC0010B584 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 1521FC5C060F296A003B28F5 /* dnsinfo_create.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_create.c; path = dnsinfo/dnsinfo_create.c; sourceTree = SOURCE_ROOT; }; 1522FCE50FA7FD7000B24128 /* dnsinfo_flatfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dnsinfo_flatfile.c; path = dnsinfo/dnsinfo_flatfile.c; sourceTree = ""; }; 152439E318038E5B00D91708 /* ev_extra.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ev_extra.h; sourceTree = ""; }; 152439E418038E5B00D91708 /* ev_extra.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ev_extra.m; sourceTree = ""; }; - 152439E7180399D800D91708 /* CoreWLAN.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreWLAN.framework; path = /System/Library/Frameworks/CoreWLAN.framework; sourceTree = ""; }; + 152439E7180399D800D91708 /* CoreWLAN.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreWLAN.framework; path = System/Library/Frameworks/CoreWLAN.framework; sourceTree = SDKROOT; }; 152439EB180716ED00D91708 /* MobileWiFi.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileWiFi.framework; path = System/Library/PrivateFrameworks/MobileWiFi.framework; sourceTree = SDKROOT; }; 1524FE1920619BAF0010091E /* Info-Embedded.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "Info-Embedded.plist"; path = "Plugins/QoSMarking/Info-Embedded.plist"; sourceTree = ""; }; 1528922C1EDE41ED00FCFE71 /* network_state_information_logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_state_information_logging.h; path = nwi/network_state_information_logging.h; sourceTree = ""; }; @@ -2029,7 +2039,7 @@ 15436251218AA22800283462 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = SCMonitor/en.lproj/Localizable.strings; sourceTree = ""; }; 15436253218AA26100283462 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 15436255218AA27400283462 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/NetworkInterface.strings; sourceTree = ""; }; - 1543636A0752D03C00A8EC6C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; + 1543636A0752D03C00A8EC6C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 1547001D08455B98006787CE /* SCHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SCHelper; sourceTree = BUILT_PRODUCTS_DIR; }; 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SystemConfiguration.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 154CF3F307E1EA4D00D8302E /* SCPreferencesGetSpecificPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCPreferencesGetSpecificPrivate.h; sourceTree = ""; }; @@ -2137,8 +2147,13 @@ 15B73F0C05FD1B670096477F /* dnsinfo_private.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_private.h; path = dnsinfo/dnsinfo_private.h; sourceTree = ""; }; 15B73F0D05FD1B670096477F /* dnsinfo_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_server.c; path = dnsinfo/dnsinfo_server.c; sourceTree = ""; }; 15B73F0E05FD1B670096477F /* dnsinfo_server.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_server.h; path = dnsinfo/dnsinfo_server.h; sourceTree = ""; }; + 15B9C0AF2232202200C8FF86 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 15B9C0B42232224A00C8FF86 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 15BAA32207F0699A00D9EC95 /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = /usr/lib/libbsm.dylib; sourceTree = ""; }; 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkReachabilityInternal.h; sourceTree = ""; }; + 15C7B7C6224D9A9A0040A8D0 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; + 15C7B7C8224D9AA70040A8D0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 15C7B7CA224D9AAE0040A8D0 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 15CB691305C0722B0099E85F /* SystemConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SystemConfiguration.h; sourceTree = ""; }; 15CB691505C0722B0099E85F /* SCPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCPrivate.h; sourceTree = ""; }; 15CB691705C0722B0099E85F /* SCDPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCDPlugin.h; sourceTree = ""; }; @@ -2254,13 +2269,14 @@ 15CB6A6005C0722B0099E85F /* tests.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tests.c; sourceTree = ""; }; 15CB6A6205C0722B0099E85F /* prefs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = prefs.c; sourceTree = ""; }; 15CB6A6A05C0722B0099E85F /* scutil.8 */ = {isa = PBXFileReference; explicitFileType = text.man; path = scutil.8; sourceTree = ""; }; - 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; + 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 15CFC229068B222F00123568 /* get-mobility-info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = "get-mobility-info"; sourceTree = SOURCE_ROOT; }; 15D3082716F3E4DA00014F82 /* libSimulatorSupport_sim.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSimulatorSupport_sim.a; sourceTree = BUILT_PRODUCTS_DIR; }; 15D3082D16F3E4E100014F82 /* SimulatorSupport.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SimulatorSupport.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 15D3083616F3EB7200014F82 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/SimulatorSupport/Info.plist; sourceTree = ""; }; 15D3083816F3EB8600014F82 /* simulator_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = simulator_support.c; path = Plugins/SimulatorSupport/simulator_support.c; sourceTree = ""; }; 15D3083A16F4E6D900014F82 /* com.apple.configd_sim.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.configd_sim.plist; sourceTree = ""; }; + 15D427212166F6F50082AA78 /* SCNetworkConfigurationPrivate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SCNetworkConfigurationPrivate.c; sourceTree = ""; }; 15D8B2291450D8450090CECF /* SCD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCD.h; sourceTree = ""; }; 15D92B9A1FFC5FA500DF2632 /* libnetwork.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libnetwork.tbd; path = usr/lib/libnetwork.tbd; sourceTree = SDKROOT; }; 15D92B9D1FFC61F400DF2632 /* libnetwork.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libnetwork.tbd; path = usr/lib/libnetwork.tbd; sourceTree = SDKROOT; }; @@ -2279,7 +2295,7 @@ 15DC346E0711D49400A3311C /* net_set.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = net_set.h; sourceTree = ""; }; 15E1B05916EBAE3C00E5F06F /* libIPMonitor_sim.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIPMonitor_sim.a; sourceTree = BUILT_PRODUCTS_DIR; }; 15E1B06116EBAE7800E5F06F /* IPMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - 15E56C5A21939B7B00088C51 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 15E56C5A21939B7B00088C51 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 15E91DBE21893E83001155DC /* SCTest-ObjC-Embedded */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "SCTest-ObjC-Embedded"; sourceTree = BUILT_PRODUCTS_DIR; }; 15E91DD621893EE1001155DC /* SCTest-Swift-Embedded */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "SCTest-Swift-Embedded"; sourceTree = BUILT_PRODUCTS_DIR; }; 15EF89B121894636003B2C5C /* SCTest-ObjC-EmbeddedSimulator */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "SCTest-ObjC-EmbeddedSimulator"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2288,6 +2304,9 @@ 15F742F11EC638D100DA2E7A /* liblog_SystemConfiguration.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = liblog_SystemConfiguration.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 15FA0F73203A379600C7702F /* EventFactory.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = EventFactory.framework; sourceTree = ""; }; 15FA0F74203A390E00C7702F /* EventFactory.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventFactory.framework; path = System/Library/PrivateFrameworks/EventFactory.framework; sourceTree = SDKROOT; }; + 15FA163923C6341100573B3C /* SCTestInterfaceNamer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCTestInterfaceNamer.m; sourceTree = ""; }; + 15FA163C23C67A9800573B3C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + 15FA163E23C67AAF00573B3C /* Network.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Network.framework; path = System/Library/Frameworks/Network.framework; sourceTree = SDKROOT; }; 15FB1F881E27E9A000B4F809 /* InterfaceNamerControlPrefs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = InterfaceNamerControlPrefs.c; sourceTree = ""; }; 15FB1F891E27E9A000B4F809 /* InterfaceNamerControlPrefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterfaceNamerControlPrefs.h; sourceTree = ""; }; 15FBB54B17D6834C0035D752 /* libCrashReporterClient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libCrashReporterClient.a; path = /usr/local/lib/libCrashReporterClient.a; sourceTree = ""; }; @@ -2464,6 +2483,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 15703B2A22320A940018D2EE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 15C7B7C7224D9A9A0040A8D0 /* CoreFoundation.framework in Frameworks */, + 15C7B7C9224D9AA70040A8D0 /* Foundation.framework in Frameworks */, + 15C7B7CB224D9AAE0040A8D0 /* SystemConfiguration.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 1572C5230CFB55B400E2776E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2614,7 +2643,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 15E91DB921893E83001155DC /* SystemConfiguration.framework in Frameworks */, + 15260A452272529F00AE1F72 /* SystemConfiguration.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2623,6 +2652,7 @@ buildActionMask = 2147483647; files = ( 15E56C5B21939B7B00088C51 /* Foundation.framework in Frameworks */, + 15260A462272533D00AE1F72 /* SystemConfiguration.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2665,9 +2695,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 72573D441D6BA051004975AD /* Network.framework in Frameworks */, - 72573D351D6680AA004975AD /* SystemConfiguration.framework in Frameworks */, + 15FA163D23C67A9800573B3C /* IOKit.framework in Frameworks */, + 15FA163F23C67AAF00573B3C /* Network.framework in Frameworks */, 728E0E971D70348D00E0613A /* NetworkExtension.framework in Frameworks */, + 72573D351D6680AA004975AD /* SystemConfiguration.framework in Frameworks */, 15D92B9F1FFC640200DF2632 /* libnetwork.tbd in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2676,9 +2707,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7271EA291D76600B0055B1AA /* Network.framework in Frameworks */, - 7271EA2A1D76600B0055B1AA /* SystemConfiguration.framework in Frameworks */, + 15FA164123C67AF100573B3C /* Network.framework in Frameworks */, 7271EA2B1D76600B0055B1AA /* NetworkExtension.framework in Frameworks */, + 7271EA2A1D76600B0055B1AA /* SystemConfiguration.framework in Frameworks */, 15D92BA11FFC641500DF2632 /* libnetwork.tbd in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2688,6 +2719,7 @@ buildActionMask = 2147483647; files = ( 15E56C5921939B6400088C51 /* Foundation.framework in Frameworks */, + 15260A472272535F00AE1F72 /* SystemConfiguration.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3175,8 +3207,8 @@ isa = PBXGroup; children = ( 15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */, - 155A1E6B081079CC00F70D98 /* SCNetworkConfigurationPrivate.h */, 15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */, + 155A1E6B081079CC00F70D98 /* SCNetworkConfigurationPrivate.h */, ); name = Headers; sourceTree = ""; @@ -3185,6 +3217,7 @@ isa = PBXGroup; children = ( 15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */, + 15D427212166F6F50082AA78 /* SCNetworkConfigurationPrivate.c */, 15AD7A3B0670A85900BFE03C /* SCNetworkInterface.c */, 15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */, 15AD7A3D0670A85900BFE03C /* SCNetworkService.c */, @@ -3617,6 +3650,7 @@ 72573D3D1D669AA6004975AD /* SCTestPreferences.m */, 72573D411D6B7989004975AD /* SCTestConfigAgents.m */, 728E0E951D70229A00E0613A /* SCTestReachability.m */, + 15FA163923C6341100573B3C /* SCTestInterfaceNamer.m */, 72573D3F1D67B2BE004975AD /* SCTestUnitTest.m */, 72573D431D6B9E72004975AD /* sctest-entitlements.plist */, 72C12CAA1D6E9ED4000EE61C /* npt_configd.plist */, @@ -3670,6 +3704,13 @@ 90507AAE1CE2F55B0067D16B /* Frameworks */ = { isa = PBXGroup; children = ( + 15FA163E23C67AAF00573B3C /* Network.framework */, + 15FA163C23C67A9800573B3C /* IOKit.framework */, + 15C7B7CA224D9AAE0040A8D0 /* SystemConfiguration.framework */, + 15C7B7C8224D9AA70040A8D0 /* Foundation.framework */, + 15C7B7C6224D9A9A0040A8D0 /* CoreFoundation.framework */, + 15B9C0B42232224A00C8FF86 /* Foundation.framework */, + 15B9C0AF2232202200C8FF86 /* SystemConfiguration.framework */, 15E56C5A21939B7B00088C51 /* Foundation.framework */, F9D7305020E41DD500521181 /* WirelessDiagnostics.framework */, F9D7304E20E41D9C00521181 /* ProtocolBuffer.framework */, @@ -6404,6 +6445,7 @@ B0C9689D174426D100889853 /* SNHelper.c in Sources */, 1572C4FC0CFB55B400E2776E /* SCPUnlock.c in Sources */, 1572C4FD0CFB55B400E2776E /* SCPList.c in Sources */, + 159C80B1219378760004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */, 1572C4FE0CFB55B400E2776E /* SCPGet.c in Sources */, 1572C4FF0CFB55B400E2776E /* SCPAdd.c in Sources */, 1572C5000CFB55B400E2776E /* SCPSet.c in Sources */, @@ -6782,6 +6824,7 @@ 15A5A2390D5B94190087BDA0 /* SCPOpen.c in Sources */, 15A5A23A0D5B94190087BDA0 /* SCPLock.c in Sources */, 15A5A23B0D5B94190087BDA0 /* SCPUnlock.c in Sources */, + 159C80B2219378790004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */, 15A5A23C0D5B94190087BDA0 /* SCPList.c in Sources */, 15A5A23D0D5B94190087BDA0 /* SCPGet.c in Sources */, 15A5A23E0D5B94190087BDA0 /* SCPAdd.c in Sources */, @@ -6868,6 +6911,7 @@ 15DAD67C07591A1A0084A6ED /* SCDNotifierAdd.c in Sources */, 15DAD67D07591A1A0084A6ED /* SCDNotifierRemove.c in Sources */, F9B7AE641862119300C78D18 /* IPMonitorControl.c in Sources */, + 159C80B0219378710004C3A6 /* SCNetworkConfigurationPrivate.c in Sources */, 15DAD67E07591A1A0084A6ED /* SCDNotifierGetChanges.c in Sources */, 15DAD67F07591A1A0084A6ED /* SCDNotifierWait.c in Sources */, 15DAD68007591A1A0084A6ED /* SCDNotifierInformViaCallback.c in Sources */, @@ -6999,6 +7043,7 @@ 728E0E961D70229A00E0613A /* SCTestReachability.m in Sources */, 72573D291D667372004975AD /* main.m in Sources */, 72573D421D6B798A004975AD /* SCTestConfigAgents.m in Sources */, + 15FA163A23C6341100573B3C /* SCTestInterfaceNamer.m in Sources */, 72573D3E1D669AA6004975AD /* SCTestPreferences.m in Sources */, 72573D2E1D6673B6004975AD /* SCTest.m in Sources */, ); diff --git a/sctest/SCTestInterfaceNamer.m b/sctest/SCTestInterfaceNamer.m new file mode 100644 index 0000000..bbf42ff --- /dev/null +++ b/sctest/SCTestInterfaceNamer.m @@ -0,0 +1,556 @@ +/* + * Copyright (c) 2020 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "SCTest.h" +#import "SCTestUtils.h" + +#include +#include +#include +#include +#include +#include +#include + +#define INTERFACES_KEY @"State:/Network/Interface" +#define PLUGIN_INTERFACE_NAMER_KEY @"Plugin:InterfaceNamer" + +#define WAIT_TIME (30 * NSEC_PER_SEC) + + +@interface SCTestInterfaceNamer : SCTest +@property NSArray *interfaces_all; +@property NSArray *interfaces_preconfigured; +@property dispatch_queue_t queue; +@property dispatch_semaphore_t sem_interfaces_all; +@property dispatch_semaphore_t sem_interfaces_preconfigured; +@property SCDynamicStoreRef store; +@end + +@implementation SCTestInterfaceNamer + ++ (NSString *)command +{ + return @"InterfaceNamer"; +} + ++ (NSString *)commandDescription +{ + return @"Tests the InterfaceNamer.bundle code paths"; +} + +static void +storeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) +{ + @autoreleasepool { + NSDictionary *dict; + NSArray *interfaces; + SCTestInterfaceNamer *test = (__bridge SCTestInterfaceNamer *)info; + + if ([(__bridge NSArray *)changedKeys containsObject:INTERFACES_KEY]) { + // copy list of interfaces + dict = (__bridge_transfer NSDictionary *)SCDynamicStoreCopyValue(store, (CFStringRef)INTERFACES_KEY); + interfaces = [dict objectForKey:(__bridge NSString *)kSCPropNetInterfaces]; + if (!_SC_CFEqual((__bridge CFArrayRef)interfaces, (__bridge CFArrayRef)test.interfaces_all)) { + test.interfaces_all = interfaces; + dispatch_semaphore_signal(test.sem_interfaces_all); + } + } + + if ([(__bridge NSArray *)changedKeys containsObject:PLUGIN_INTERFACE_NAMER_KEY]) { + // copy list of [pre-configured] interfaces + dict = (__bridge_transfer NSDictionary *)SCDynamicStoreCopyValue(store, (CFStringRef)PLUGIN_INTERFACE_NAMER_KEY); + interfaces = [dict objectForKey:@"_PreConfigured_"]; + if (!_SC_CFEqual((__bridge CFArrayRef)interfaces, (__bridge CFArrayRef)test.interfaces_preconfigured)) { + test.interfaces_preconfigured = interfaces; + dispatch_semaphore_signal(test.sem_interfaces_preconfigured); + } + } + } + + return; +} + +- (instancetype)initWithOptions:(NSDictionary *)options +{ + self = [super initWithOptions:options]; +// if (self) { +// } + return self; +} + +- (void)dealloc +{ + [self watchForChanges:FALSE]; +} + +- (void)start +{ + [self cleanupAndExitWithErrorCode:0]; +} + +- (void)cleanupAndExitWithErrorCode:(int)error +{ + [super cleanupAndExitWithErrorCode:error]; +} + +- (BOOL)setup +{ + return YES; +} + +- (BOOL)unitTest +{ + if(![self setup]) { + return NO; + } + + BOOL allUnitTestsPassed = YES; + allUnitTestsPassed &= [self unitTestInsertRemoveOneInterface]; + + if(![self tearDown]) { + return NO; + } + + return allUnitTestsPassed; +} + +- (BOOL)tearDown +{ + return YES; +} + +- (void)watchForChanges:(BOOL)enable +{ + if (enable) { + SCDynamicStoreContext context = {0, NULL, CFRetain, CFRelease, NULL}; + Boolean ok; + + self.queue = dispatch_queue_create("SCTestInterfaceNamer callback queue", NULL); + + self.sem_interfaces_all = dispatch_semaphore_create(0); + + self.sem_interfaces_preconfigured = dispatch_semaphore_create(0); + + context.info = (__bridge void * _Nullable)self; + self.store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("SCTest"), storeCallback, &context); + + ok = SCDynamicStoreSetNotificationKeys(self.store, + (__bridge CFArrayRef)@[INTERFACES_KEY, + PLUGIN_INTERFACE_NAMER_KEY], + NULL); + assert(ok); + + ok = SCDynamicStoreSetDispatchQueue(self.store, self.queue); + assert(ok); + } else { + if (self.store != NULL) { + (void)SCDynamicStoreSetDispatchQueue(self.store, NULL); + CFRelease(self.store); + self.store = NULL; + } + + self.queue = NULL; + self.sem_interfaces_all = NULL; + self.sem_interfaces_preconfigured = NULL; + } +} + +- (BOOL)isPreconfiguredInterface:(NSString *)bsdName +{ + return [self.interfaces_preconfigured containsObject:bsdName];; +} + +#pragma mark - +#pragma mark IOEthernetController support + +static CFStringRef +copy_interface_name(IOEthernetControllerRef controller) +{ + CFStringRef bsdName; + io_object_t interface; + + interface = IOEthernetControllerGetIONetworkInterfaceObject(controller); + if (interface == MACH_PORT_NULL) { + SCTestLog("*** could not get interface for controller"); + return NULL; + } + + bsdName = IORegistryEntryCreateCFProperty(interface, CFSTR(kIOBSDNameKey), NULL, kNilOptions); + if (bsdName == NULL) { + SCTestLog("*** IOEthernetController with no BSD interface name"); + return NULL; + } + + return bsdName; +} + +static CFDataRef +copy_interface_mac(IOEthernetControllerRef controller) +{ + CFDataRef macAddress; + io_object_t interface; + + interface = IOEthernetControllerGetIONetworkInterfaceObject(controller); + if (interface == MACH_PORT_NULL) { + SCTestLog("*** could not get interface for controller"); + return NULL; + } + + macAddress = IORegistryEntrySearchCFProperty(interface, + kIOServicePlane, + CFSTR(kIOMACAddress), + NULL, + kIORegistryIterateRecursively | kIORegistryIterateParents); + if (macAddress == NULL) { + SCTestLog("*** IOEthernetController with no BSD interface name"); + return NULL; + } + + return macAddress; +} + +static IOEthernetControllerRef +create_hidden_interface(u_char ea_unique) +{ + IOEthernetControllerRef controller; + CFDataRef data; + struct ether_addr ea = { .octet = { 0x02, 'F', 'A', 'K', 'E', ea_unique } }; + CFMutableDictionaryRef merge; + CFNumberRef num; + CFMutableDictionaryRef props; + const int usb_vid_apple = kIOUSBAppleVendorID; + + props = CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + data = CFDataCreate(NULL, ea.octet, ETHER_ADDR_LEN); + CFDictionarySetValue(props, kIOEthernetHardwareAddress, data); + CFRelease(data); + + merge = CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(merge, CFSTR(kIOPropertyProductNameKey), CFSTR("Hidden Ethernet")); + CFDictionarySetValue(merge, kIOUserEthernetInterfaceRole, CFSTR("hidden-ethernet")); + CFDictionarySetValue(merge, kSCNetworkInterfaceHiddenConfigurationKey, kCFBooleanTrue); + num = CFNumberCreate(NULL, kCFNumberIntType, &usb_vid_apple); + CFDictionarySetValue(merge, CFSTR(kUSBVendorID), num); + CFRelease(num); + CFDictionarySetValue(props, kIOUserEthernetInterfaceMergeProperties, merge); + CFRelease(merge); + + controller = IOEthernetControllerCreate(NULL, props); + CFRelease(props); + if (controller == NULL) { + SCTestLog("*** could not create ethernet controller for \"%s\"", ether_ntoa(&ea)); + return NULL; + } + + return controller; +} + +- (BOOL)interfaceAdd:(u_char)ea_unique controller:(IOEthernetControllerRef *)newController +{ + BOOL ok = FALSE; + + do { + NSString *bsdName; + NSData *macAddress; + long status; + + // add an interface + *newController = create_hidden_interface(ea_unique); + if (*newController == NULL) { + SCTestLog("*** could not create controller"); + break; + } + + // wait for the [BSD] interface to show up + status = dispatch_semaphore_wait(self.sem_interfaces_all, dispatch_time(DISPATCH_TIME_NOW, WAIT_TIME)); + if (status != 0) { + // if timeout + SCTestLog("*** no KernelEventMonitor change posted, interface not? created"); + break; + } + + bsdName = (__bridge_transfer NSString *)copy_interface_name(*newController); + if (bsdName == NULL) { + break; + } + + macAddress = (__bridge_transfer NSData *)copy_interface_mac(*newController); + if (macAddress == NULL) { + break; + } + + SCTestLog(" Interface \"%@\" added, mac=%s", + bsdName, + ether_ntoa((struct ether_addr *)macAddress.bytes)); + + // check if pre-configured + status = dispatch_semaphore_wait(self.sem_interfaces_preconfigured, dispatch_time(DISPATCH_TIME_NOW, WAIT_TIME)); + if (status != 0) { + // if timeout + SCTestLog("*** no InterfaceNamer change posted, not? preconfigured"); + break; + } + + if (![self isPreconfiguredInterface:bsdName]) { + SCTestLog("*** Interface \"%@\" is not pre-configured", bsdName); + break; + } + + SCTestLog(" Interface \"%@\" is pre-configured", bsdName); + + ok = TRUE; + } while (0); + + if (!ok) { + if (*newController != NULL) { + CFRelease(*newController); + *newController = NULL; + } + } + + return ok; +} + +- (BOOL)interfaceRemove:(IOEthernetControllerRef)controller +{ + BOOL ok = FALSE; + + do { + NSString *bsdName = (__bridge_transfer NSString *)copy_interface_name(controller); + long status; + + // remove the interface + CFRelease(controller); + + // wait for the [BSD] interface to go away + status = dispatch_semaphore_wait(self.sem_interfaces_all, dispatch_time(DISPATCH_TIME_NOW, WAIT_TIME)); + if (status != 0) { + // if timeout + SCTestLog("*** no KernelEventMonitor change posted, interface not? removed"); + break; + } + + SCTestLog(" Interface \"%@\" removed", bsdName); + + // check if [still] pre-configured + status = dispatch_semaphore_wait(self.sem_interfaces_preconfigured, dispatch_time(DISPATCH_TIME_NOW, WAIT_TIME)); + if (status != 0) { + // if timeout + SCTestLog("*** no InterfaceNamer change posted, still? preconfigured"); + break; + } + + if ([self isPreconfiguredInterface:bsdName]) { + SCTestLog("*** interface \"%@\" is still pre-configured", bsdName); + break; + } + + ok = TRUE; + } while (0); + + return ok; +} + +#pragma mark - +#pragma mark unitTestInsertRemoveOneInterface + +#define N_INTERFACES 5 + +- (BOOL)unitTestInsertRemoveOneInterface +{ + NSString *bsdName1 = nil; + BOOL ok; + SCTestInterfaceNamer *test; + + test = [[SCTestInterfaceNamer alloc] initWithOptions:self.options]; + [test watchForChanges:TRUE]; + + for (size_t i = 0; i < N_INTERFACES; i++) { + NSString *bsdName; + IOEthernetControllerRef controller; + + SCTestLog("Interface #%zd", i + 1); + + // add an interface + ok = [test interfaceAdd:i controller:&controller]; + if (!ok) { + break; + } + + // check the assigned interface name + bsdName = (__bridge_transfer NSString *)copy_interface_name(controller); + if (i == 0) { + bsdName1 = bsdName; + } else if ([bsdName isNotEqualTo:bsdName1]) { + SCTestLog("*** interface name not re-assigned, expected \"%@\", assigned \"%@\"", bsdName1, bsdName); + break; + } + + // remove the interface + ok = [test interfaceRemove:controller]; + if (!ok) { + break; + } + }; + + if (ok) { + SCTestLog("Successfully completed unitTestInsertRemoveOneInterface unit test"); + } + + return ok; +} + +#pragma mark - +#pragma mark unitTestInsertRemoveMultipleInterfaces + +#define N_INTERFACES_SLOT_X (N_INTERFACES / 2) + +- (BOOL)unitTestInsertRemoveMultipleInterfaces +{ + NSString *bsdName; + IOEthernetControllerRef controller; + struct { + NSString *bsdName; + IOEthernetControllerRef controller; + } interfaces[N_INTERFACES] = { { } }; + BOOL ok; + SCTestInterfaceNamer *test; + + test = [[SCTestInterfaceNamer alloc] initWithOptions:self.options]; + [test watchForChanges:TRUE]; + + SCTestLog("Adding %d interfaces", N_INTERFACES); + + for (size_t i = 0; i < N_INTERFACES; i++) { + // add an interface + ok = [test interfaceAdd:i controller:&controller]; + if (!ok) { + break; + } + + interfaces[i].controller = controller; + interfaces[i].bsdName = (__bridge_transfer NSString *)copy_interface_name(controller); + } + + if (ok) { + SCTestLog("Removing interfaces"); + + for (size_t i = 0; i < N_INTERFACES; i++) { + // remove the interface + ok = [test interfaceRemove:interfaces[i].controller]; + interfaces[i].controller = NULL; + if (!ok) { + break; + } + } + } + + if (ok) { + SCTestLog("Re-adding %d interfaces", N_INTERFACES); + + for (size_t i = 0; i < N_INTERFACES; i++) { + // add an interface + ok = [test interfaceAdd:i controller:&controller]; + if (!ok) { + break; + } + + interfaces[i].controller = controller; + + bsdName = (__bridge_transfer NSString *)copy_interface_name(controller); + ok = [bsdName isEqualTo:interfaces[i].bsdName]; + if (!ok) { + SCTestLog("*** interface %zd not assigned the same name, expected \"%@\", assigned \"%@\"", + i, + interfaces[i].bsdName, + bsdName); + break; + } + + interfaces[i].bsdName = bsdName; + } + } + + if (ok) { + SCTestLog("Removing one interface"); + + ok = [test interfaceRemove:interfaces[N_INTERFACES_SLOT_X].controller]; + interfaces[N_INTERFACES_SLOT_X].controller = NULL; + } + + if (ok) { + SCTestLog("Adding a new interface"); + + do { + // add a new interface (should re-use the first available name) + ok = [test interfaceAdd:N_INTERFACES controller:&controller]; + if (!ok) { + break; + } + + interfaces[N_INTERFACES_SLOT_X].controller = controller; + + bsdName = (__bridge_transfer NSString *)copy_interface_name(controller); + ok = [bsdName isEqualTo:interfaces[N_INTERFACES_SLOT_X].bsdName]; + if (!ok) { + SCTestLog("*** interface %d not assigned an old name, expected \"%@\", assigned \"%@\"", + N_INTERFACES, + interfaces[N_INTERFACES_SLOT_X].bsdName, + bsdName); + break; + } + + interfaces[N_INTERFACES_SLOT_X].bsdName = bsdName; + } while (0); + } + + if (ok) { + SCTestLog("Removing interfaces (again)"); + + for (size_t i = 0; i < N_INTERFACES; i++) { + // remove the interface + ok = [test interfaceRemove:interfaces[i].controller]; + interfaces[i].controller = NULL; + if (!ok) { + break; + } + } + } + + // cleanup + for (size_t i = 0; i < N_INTERFACES; i++) { + if (interfaces[i].controller != NULL) { + CFRelease(interfaces[i].controller); + } + } + + return ok; +} + +@end diff --git a/sctest/SCTestOptions.h b/sctest/SCTestOptions.h index 46be006..cc8c2f3 100644 --- a/sctest/SCTestOptions.h +++ b/sctest/SCTestOptions.h @@ -67,6 +67,7 @@ extern const NSString * const kSCTestUnitTestTestMethodList; {"list_tests", 0, NULL, 0}, \ {"test_method", 1, NULL, 0}, \ {"test_method_list", 0, NULL, 0}, \ + {NULL, 0, NULL, 0}, #define kSCTestOptionHelp \ "\n============== global options =============\n"\ diff --git a/sctest/SCTestUtils.h b/sctest/SCTestUtils.h index 5b07145..02622a8 100644 --- a/sctest/SCTestUtils.h +++ b/sctest/SCTestUtils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017 Apple Inc. All rights reserved. + * Copyright (c) 2016, 2017, 2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -28,7 +28,8 @@ #import #import -#define SCTestLog(fmt, ...) SCPrint(TRUE, stdout, CFSTR(fmt "\n"), ##__VA_ARGS__) +#define SCTestLog(fmt, ...) SCLog(TRUE, LOG_NOTICE, CFSTR(fmt), ##__VA_ARGS__) + #define ERR_EXIT exit(1) typedef struct { diff --git a/sctest/genSCTestOptions.c b/sctest/genSCTestOptions.c index 4374622..b06d135 100644 --- a/sctest/genSCTestOptions.c +++ b/sctest/genSCTestOptions.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017 Apple Inc. All rights reserved. + * Copyright (c) 2016, 2017, 2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -103,6 +103,7 @@ printOptionEntries() printf("\t\t{\"%s\", %d, NULL, 0}, \\", testOptions[i].optionString, testOptions[i].hasArg); printf("\n"); } + printf("\t\t{NULL, 0, NULL, 0},\n"); } void diff --git a/sctest/main.m b/sctest/main.m index e868110..ec71efc 100644 --- a/sctest/main.m +++ b/sctest/main.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Apple Inc. All rights reserved. + * Copyright (c) 2016, 2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -50,6 +50,8 @@ int main(int argc, const char * argv[]) { Class testClass; SCTest *testClassObject; + _sc_log = 0; // print (stdout) + if (argc == 1) { usage(); } @@ -86,6 +88,8 @@ int main(int argc, const char * argv[]) { } } + _sc_log = 3; // log AND print (stdout w/o timestamp) + testClassObject = [(SCTest *)[testClass alloc] initWithOptions:options]; if (testClassObject.options[kSCTestGlobalOptionCPU] != nil) { cpuStart(testClassObject.globalCPU); diff --git a/scutil.tproj/commands.c b/scutil.tproj/commands.c index aeab336..79a8358 100644 --- a/scutil.tproj/commands.c +++ b/scutil.tproj/commands.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2011, 2013, 2014, 2017, 2018 Apple Inc. All rights reserved. + * Copyright (c) 2000-2011, 2013, 2014, 2017-2019 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -192,10 +192,6 @@ const cmdInfo commands_net[] = { " enable protocol [ ]\n" " enable service [ | ]" }, - { "migrate", 2, 5, do_net_migrate, 11, 0, - " migrate perform []\n" - " migrate validate "}, - { "remove", 1, 2, do_net_remove, 6, 0, " remove protocol [ ]\n" " remove service [ | ]\n" @@ -223,9 +219,19 @@ const cmdInfo commands_net[] = { " show sets\n\n" " show set [ | ]" }, - { "update", 0, 1, do_net_update, 10, 0, + { "migrate", 2, 5, do_net_migrate, 10, 0, + " migrate perform []\n" + " migrate validate "}, + + { "clean", 0, 0, do_net_clean, 11, 0, + " clean : clean the network configuration" }, + + { "update", 0, 0, do_net_update, 11, 0, " update : update the network configuration" }, + { "upgrade", 0, 1, do_net_upgrade, 11, 0, + " upgrade [ ] : upgrade the network configuration" }, + { "snapshot", 0, 0, do_net_snapshot, 99, 2, " snapshot" } diff --git a/scutil.tproj/net.c b/scutil.tproj/net.c index d793a7c..3cee939 100644 --- a/scutil.tproj/net.c +++ b/scutil.tproj/net.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2007, 2009-2011, 2014, 2016, 2017 Apple Inc. All rights reserved. + * Copyright (c) 2004-2007, 2009-2011, 2014, 2016, 2017, 2019, 2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -38,6 +38,9 @@ #include "net_service.h" #include "net_set.h" +#include "SCNetworkConfigurationInternal.h" +#include "SCPreferencesInternal.h" + #include @@ -541,7 +544,6 @@ void do_net_open(int argc, char **argv) { Boolean ok; - CFStringRef prefsID = NULL; if (prefs != NULL) { if (_prefs_commitRequired(argc, argv, "close")) { @@ -552,12 +554,7 @@ do_net_open(int argc, char **argv) _prefs_close(); } - if (argc > 0) { - prefsID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); - } - - ok = _prefs_open(CFSTR("scutil --net"), prefsID); - if (prefsID != NULL) CFRelease(prefsID); + ok = _prefs_open(CFSTR("scutil --net"), (argc > 0) ? argv[0] : NULL); if (!ok) { SCPrint(TRUE, stdout, @@ -1010,6 +1007,47 @@ do_net_show(int argc, char **argv) } +__private_extern__ +void +do_net_clean(int argc, char **argv) +{ +#pragma unused(argc) +#pragma unused(argv) + Boolean updated; + + if (prefs == NULL) { + SCPrint(TRUE, stdout, CFSTR("network configuration not open\n")); + return; + } + + if (ni_prefs == NULL) { + ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG); + if (ni_prefs == NULL) { + SC_log(LOG_NOTICE, "SCPreferencesCreate( ) failed: %s", SCErrorString(SCError())); + } + } + + updated = __SCNetworkConfigurationClean(prefs, ni_prefs); + + if (updated) { + SCPrint(TRUE, stdout, + CFSTR("network configuration updated, use \"commit\" to save\n")); + if ((prefsPath == NULL) || (strcmp(prefsPath, PREFS_DEFAULT_CONFIG_PLIST) == 0)) { + SCPrint(TRUE, stdout, + CFSTR( "\n" + "NOTE: because you have modified the system's \"live\" network configuration,\n" + " a is also REQUIRED.\n" + "\n")); + } + _prefs_changed = TRUE; + } else { + SCPrint(TRUE, stdout, CFSTR("network configuration not updated\n")); + } + + return; +} + + __private_extern__ void do_net_update(int argc, char **argv) @@ -1071,6 +1109,7 @@ do_net_update(int argc, char **argv) SCNetworkSetGetSetID(set), setCreated ? "created, selected, and " : ""); } + _prefs_changed = TRUE; } CFRelease(set); @@ -1078,6 +1117,85 @@ do_net_update(int argc, char **argv) } +__private_extern__ +void +do_net_upgrade(int argc, char **argv) +{ + Boolean do_commit = FALSE; + Boolean upgraded; + + if (prefs == NULL) { + SCPrint(TRUE, stdout, CFSTR("network configuration not open\n")); + return; + } + + if (prefsPath != NULL) { + const char *prefs_plist; + + prefs_plist = strrchr(prefsPath, '/'); + if (prefs_plist != NULL) { + prefs_plist++; + } else { + prefs_plist = prefsPath; + } + + if (strcmp(prefs_plist, PREFS_DEFAULT_CONFIG_PLIST) != 0) { + SCPrint(TRUE, stdout, CFSTR("not updating a \"preferences.plist\" file\n")); + return; + } + } + + if (argc > 0) { + if (strcmp(argv[0], PREFS_DEFAULT_CONFIG_PLIST) == 0) { + upgraded = __SCNetworkConfigurationUpgrade(&prefs, NULL, do_commit); + } else if (strcmp(argv[0], INTERFACES_DEFAULT_CONFIG_PLIST) == 0) { + if (ni_prefs == NULL) { + ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG); + if (ni_prefs == NULL) { + SC_log(LOG_NOTICE, "SCPreferencesCreate( ) failed: %s", SCErrorString(SCError())); + } + } + + do_commit = TRUE; // using alternate, created on-the-fly preferences.plist + + upgraded = __SCNetworkConfigurationUpgrade(NULL, &ni_prefs, do_commit); + } else { + SCPrint(TRUE, stdout, CFSTR("invalid .plist (\"preferences.plist\", \"NetworkInterfaces.plist\"\n")); + return; + } + } else { + upgraded = __SCNetworkConfigurationUpgrade(&prefs, &ni_prefs, do_commit); + } + + if (upgraded) { + SCPrint(TRUE, stdout, + do_commit ? CFSTR("network configuration upgraded/saved\n") + : CFSTR("network configuration upgraded, use \"commit\" to save\n")); + if ((prefsPath == NULL) || (strcmp(prefsPath, PREFS_DEFAULT_CONFIG_PLIST) == 0)) { + SCPrint(TRUE, stdout, + do_commit ? CFSTR("\n" + "NOTE: because you have modified the system's \"live\" network configuration,\n" + " a is also REQUIRED.\n" + "\n") + + : CFSTR("\n" + "NOTE: because you are modifying the system's \"live\" network configuration,\n" + " a will also be REQUIRED.\n" + "\n") + ); + } + + if (!do_commit) { + _prefs_changed = TRUE; + } + } else { + SCPrint(TRUE, stdout, CFSTR("network configuration upgrade not needed\n")); + } + + return; +} + + #include "SCPreferencesInternal.h" #include #include diff --git a/scutil.tproj/net.h b/scutil.tproj/net.h index 3386d78..b8c78c8 100644 --- a/scutil.tproj/net.h +++ b/scutil.tproj/net.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, 2011, 2014, 2016 Apple Inc. All rights reserved. + * Copyright (c) 2004, 2006, 2011, 2014, 2016, 2019, 2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -118,6 +118,7 @@ void do_net_commit (int argc, char **argv); void do_net_apply (int argc, char **argv); void do_net_close (int argc, char **argv); +void do_net_clean (int argc, char **argv); void do_net_create (int argc, char **argv); void do_net_disable (int argc, char **argv); void do_net_enable (int argc, char **argv); @@ -127,6 +128,7 @@ void do_net_select (int argc, char **argv); void do_net_set (int argc, char **argv); void do_net_show (int argc, char **argv); void do_net_update (int argc, char **argv); +void do_net_upgrade (int argc, char **argv); void do_net_snapshot (int argc, char **argv); diff --git a/scutil.tproj/prefs.c b/scutil.tproj/prefs.c index a4df6a4..a0bf112 100644 --- a/scutil.tproj/prefs.c +++ b/scutil.tproj/prefs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008, 2011-2017 Apple Inc. All rights reserved. + * Copyright (c) 2003-2008, 2011-2017, 2019, 2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -144,10 +144,11 @@ __private_extern__ Boolean _prefs_changed = FALSE; __private_extern__ Boolean -_prefs_open(CFStringRef name, CFStringRef prefsID) +_prefs_open(CFStringRef name, const char *path) { char *env = NULL; CFMutableDictionaryRef options = NULL; + CFStringRef prefsID = NULL; Boolean useHelper = FALSE; Boolean useOptions = FALSE; @@ -191,6 +192,11 @@ _prefs_open(CFStringRef name, CFStringRef prefsID) CFRelease(str); } + if (path != NULL) { + prefsPath = strdup(path); + prefsID = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8); + } + if (!useHelper && !useOptions) { // if no helper/options needed prefs = SCPreferencesCreate(NULL, name, prefsID); @@ -202,7 +208,10 @@ _prefs_open(CFStringRef name, CFStringRef prefsID) CFRelease(options); } + if (prefsID != NULL) CFRelease(prefsID); if (prefs == NULL) { + if (prefsPath != NULL) free(prefsPath); + prefsPath = NULL; return FALSE; } @@ -230,8 +239,6 @@ _prefs_save() exit (1); } - _prefs_changed = FALSE; - if (!SCPreferencesApplyChanges(prefs)) { SCPrint(TRUE, stdout, @@ -240,6 +247,33 @@ _prefs_save() exit (1); } + _prefs_changed = FALSE; + + if (ni_prefs != NULL) { + if (!SCPreferencesCommitChanges(ni_prefs)) { + switch (SCError()) { + case kSCStatusAccessError : + SCPrint(TRUE, stderr, CFSTR("Permission denied.\n")); + break; + default : + SCPrint(TRUE, + stdout, + CFSTR("SCPreferencesCommitChanges( ) failed: %s\n"), + SCErrorString(SCError())); + break; + } + exit (1); + } + + if (!SCPreferencesApplyChanges(ni_prefs)) { + SCPrint(TRUE, + stdout, + CFSTR("SCPreferencesApplyChanges( ) failed: %s\n"), + SCErrorString(SCError())); + exit (1); + } + } + return; } @@ -248,12 +282,22 @@ __private_extern__ void _prefs_close() { + if (prefsPath != NULL) { + free(prefsPath); + prefsPath = NULL; + } + if (prefs != NULL) { CFRelease(prefs); prefs = NULL; _prefs_changed = FALSE; } + if (ni_prefs != NULL) { + CFRelease(ni_prefs); + ni_prefs = NULL; + } + if (authorization != NULL) { #if !TARGET_OS_IPHONE _prefs_AuthorizationFree(authorization); @@ -644,7 +688,6 @@ void do_prefs_open(int argc, char **argv) { Boolean ok; - CFStringRef prefsID = NULL; if (prefs != NULL) { if (_prefs_commitRequired(argc, argv, "close")) { @@ -654,12 +697,7 @@ do_prefs_open(int argc, char **argv) do_prefs_close(0, NULL); } - if (argc > 0) { - prefsID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); - } - - ok = _prefs_open(CFSTR("scutil --prefs"), prefsID); - if (prefsID != NULL) CFRelease(prefsID); + ok = _prefs_open(CFSTR("scutil --prefs"), (argc > 0) ? argv[0] : NULL); if (!ok) { SCPrint(TRUE, stdout, @@ -768,6 +806,10 @@ do_prefs_synchronize(int argc, char **argv) #pragma unused(argc) #pragma unused(argv) SCPreferencesSynchronize(prefs); + if (ni_prefs != NULL) { + SCPreferencesSynchronize(ni_prefs); + } + return; } diff --git a/scutil.tproj/prefs.h b/scutil.tproj/prefs.h index b4f397a..af4d98a 100644 --- a/scutil.tproj/prefs.h +++ b/scutil.tproj/prefs.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2003, 2005-2007, 2012, 2013, 2015-2017 Apple Inc. All rights reserved. + * Copyright (c) 2003, 2005-2007, 2012, 2013, 2015-2017, 2019, 2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -44,7 +44,7 @@ __BEGIN_DECLS AuthorizationRef _prefs_AuthorizationCreate (void); void _prefs_AuthorizationFree (AuthorizationRef authorization); -Boolean _prefs_open (CFStringRef name, CFStringRef prefsID); +Boolean _prefs_open (CFStringRef name, const char *path); void _prefs_save (void); void _prefs_close (void); Boolean _prefs_commitRequired (int argc, char **argv, const char *command); diff --git a/scutil.tproj/scutil.c b/scutil.tproj/scutil.c index a897d81..0d27a4a 100644 --- a/scutil.tproj/scutil.c +++ b/scutil.tproj/scutil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2018 Apple Inc. All rights reserved. + * Copyright (c) 2000-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -75,9 +75,11 @@ __private_extern__ AuthorizationRef authorization = NULL; __private_extern__ InputRef currentInput = NULL; __private_extern__ Boolean doDispatch = FALSE; __private_extern__ int nesting = 0; +__private_extern__ SCPreferencesRef ni_prefs = NULL; __private_extern__ CFRunLoopRef notifyRl = NULL; __private_extern__ CFRunLoopSourceRef notifyRls = NULL; __private_extern__ SCPreferencesRef prefs = NULL; +__private_extern__ char *prefsPath = NULL; __private_extern__ SCDynamicStoreRef store = NULL; __private_extern__ CFPropertyListRef value = NULL; __private_extern__ CFMutableArrayRef watchedKeys = NULL; diff --git a/scutil.tproj/scutil.h b/scutil.tproj/scutil.h index b72f280..c44303f 100644 --- a/scutil.tproj/scutil.h +++ b/scutil.tproj/scutil.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005, 2009, 2012, 2016, 2017 Apple Inc. All rights reserved. + * Copyright (c) 2000-2005, 2009, 2012, 2016, 2017, 2019, 2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -37,7 +37,9 @@ #include #include -#define SC_LOG_HANDLE _SC_LOG_DEFAULT +#define SC_LOG_HANDLE _SC_LOG_DEFAULT +#define USE_SC_LOG_OR_PRINT 1 + #include #include #include @@ -54,9 +56,11 @@ extern AuthorizationRef authorization; extern InputRef currentInput; extern Boolean doDispatch; extern int nesting; +extern SCPreferencesRef ni_prefs; extern CFRunLoopRef notifyRl; extern CFRunLoopSourceRef notifyRls; extern SCPreferencesRef prefs; +extern char *prefsPath; extern SCDynamicStoreRef store; extern CFPropertyListRef value; extern CFMutableArrayRef watchedKeys; -- 2.45.2