SCNetworkSetRef SCNetworkSetCopy(SCPreferencesRef prefs, CFStringRef setID) { CFDictionaryRef entity; CFStringRef path; SCNetworkSetPrivateRef setPrivate; if (!isA_CFString(setID)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } path = SCPreferencesPathKeyCreateSet(NULL, setID); entity = SCPreferencesPathGetValue(prefs, path); CFRelease(path); if (!isA_CFDictionary(entity)) { _SCErrorSet(kSCStatusNoKey); return NULL; } setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, setID); assert(setPrivate != NULL); // mark set as "old" (already established) setPrivate->established = TRUE; return (SCNetworkSetRef)setPrivate; }
CFArrayRef /* of serviceID CFStringRef's */ SCNetworkSetGetServiceOrder(SCNetworkSetRef set) { CFDictionaryRef dict; CFStringRef path; CFArrayRef serviceOrder; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } path = SCPreferencesPathKeyCreateSetNetworkGlobalEntity(NULL, setPrivate->setID, kSCEntNetIPv4); if (path == NULL) { return NULL; } dict = SCPreferencesPathGetValue(setPrivate->prefs, path); CFRelease(path); if (!isA_CFDictionary(dict)) { return NULL; } serviceOrder = CFDictionaryGetValue(dict, kSCPropNetServiceOrder); serviceOrder = isA_CFArray(serviceOrder); return serviceOrder; }
__private_extern__ CFDictionaryRef __getPrefsConfiguration(SCPreferencesRef prefs, CFStringRef path) { CFDictionaryRef config; CFIndex n; config = SCPreferencesPathGetValue(prefs, path); n = isA_CFDictionary(config) ? CFDictionaryGetCount(config) : 0; switch (n) { case 0 : // ignore empty configuration entities config = NULL; break; case 1 : if (CFDictionaryContainsKey(config, kSCResvInactive)) { // ignore [effectively] empty configuration entities config = NULL; } break; default : break; } return config; }
static Boolean _SCBondInterfaceSetMode(SCBondInterfaceRef bond, CFNumberRef mode) { SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)bond; Boolean needs_release = FALSE; Boolean ok = TRUE; assert(bond != NULL); if (mode == NULL) { int mode_num = IF_BOND_MODE_LACP; mode = CFNumberCreate(NULL, kCFNumberIntType, &mode_num); needs_release = TRUE; } // set mode in the stored preferences if (interfacePrivate->prefs != NULL) { CFDictionaryRef dict; CFMutableDictionaryRef newDict; CFStringRef path; path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeBond, interfacePrivate->entity_device); dict = SCPreferencesPathGetValue(interfacePrivate->prefs, path); if (!isA_CFDictionary(dict)) { // if the prefs are confused CFRelease(path); _SCErrorSet(kSCStatusFailed); ok = FALSE; goto done; } newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesBondMode, mode); if (!CFEqual(dict, newDict)) { ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); } CFRelease(newDict); CFRelease(path); } if (ok) { CFRetain(mode); if (interfacePrivate->bond.mode != NULL) { CFRelease(interfacePrivate->bond.mode); } interfacePrivate->bond.mode = mode; } done : if (needs_release) CFRelease(mode); return ok; }
__private_extern__ Boolean __setPrefsConfiguration(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef config, Boolean keepInactive) { CFDictionaryRef curConfig; CFMutableDictionaryRef newConfig = NULL; Boolean ok; if ((config != NULL) && !isA_CFDictionary(config)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } curConfig = SCPreferencesPathGetValue(prefs, path); if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } if (keepInactive) { if (config == NULL) { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) { // if currently disabled CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); } else { // if currently enabled CFDictionaryRemoveValue(newConfig, kSCResvInactive); } } // set new configuration if (_SC_CFEqual(curConfig, newConfig)) { // if no change if (newConfig != NULL) CFRelease(newConfig); ok = TRUE; } else if (newConfig != NULL) { // if new configuration (or we are preserving a disabled state) ok = SCPreferencesPathSetValue(prefs, path, newConfig); CFRelease(newConfig); } else { ok = SCPreferencesPathRemoveValue(prefs, path); if (!ok && (SCError() == kSCStatusNoKey)) { ok = TRUE; } } return ok; }
CFArrayRef /* of SCNetworkSetRef's */ SCNetworkSetCopyAll(SCPreferencesRef prefs) { CFMutableArrayRef array; CFIndex n; CFStringRef path; CFDictionaryRef sets; path = SCPreferencesPathKeyCreateSets(NULL); sets = SCPreferencesPathGetValue(prefs, path); CFRelease(path); if ((sets != NULL) && !isA_CFDictionary(sets)) { return NULL; } array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); n = (sets != NULL) ? CFDictionaryGetCount(sets) : 0; if (n > 0) { CFIndex i; const void * keys_q[N_QUICK]; const void ** keys = keys_q; const void * vals_q[N_QUICK]; const void ** vals = vals_q; if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) { keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0); vals = CFAllocatorAllocate(NULL, n * sizeof(CFPropertyListRef), 0); } CFDictionaryGetKeysAndValues(sets, keys, vals); for (i = 0; i < n; i++) { SCNetworkSetPrivateRef setPrivate; if (!isA_CFDictionary(vals[i])) { SC_log(LOG_INFO, "error w/set \"%@\"", keys[i]); continue; } setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, keys[i]); assert(setPrivate != NULL); // mark set as "old" (already established) setPrivate->established = TRUE; CFArrayAppendValue(array, (SCNetworkSetRef)setPrivate); CFRelease(setPrivate); } if (keys != keys_q) { CFAllocatorDeallocate(NULL, keys); CFAllocatorDeallocate(NULL, vals); } } return array; }
Boolean SCNetworkSetSetServiceOrder(SCNetworkSetRef set, CFArrayRef newOrder) { CFDictionaryRef dict; CFMutableDictionaryRef newDict; Boolean ok; CFStringRef path; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (isA_CFArray(newOrder)) { CFIndex i; CFIndex n = CFArrayGetCount(newOrder); for (i = 0; i < n; i++) { CFStringRef serviceID; serviceID = CFArrayGetValueAtIndex(newOrder, i); if (!isA_CFString(serviceID)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } } } else { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } path = SCPreferencesPathKeyCreateSetNetworkGlobalEntity(NULL, setPrivate->setID, kSCEntNetIPv4); if (path == NULL) { return FALSE; } dict = SCPreferencesPathGetValue(setPrivate->prefs, path); if (dict != NULL) { newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); } else { newDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newDict, kSCPropNetServiceOrder, newOrder); ok = SCPreferencesPathSetValue(setPrivate->prefs, path, newDict); CFRelease(newDict); CFRelease(path); return ok; }
__private_extern__ Boolean __getPrefsEnabled(SCPreferencesRef prefs, CFStringRef path) { CFDictionaryRef config; config = SCPreferencesPathGetValue(prefs, path); if (isA_CFDictionary(config) && CFDictionaryContainsKey(config, kSCResvInactive)) { return FALSE; } return TRUE; }
__private_extern__ Boolean __setPrefsEnabled(SCPreferencesRef prefs, CFStringRef path, Boolean enabled) { CFDictionaryRef curConfig; CFMutableDictionaryRef newConfig = NULL; Boolean ok = FALSE; // preserve current configuration curConfig = SCPreferencesPathGetValue(prefs, path); if (curConfig != NULL) { if (!isA_CFDictionary(curConfig)) { _SCErrorSet(kSCStatusFailed); return FALSE; } newConfig = CFDictionaryCreateMutableCopy(NULL, 0, curConfig); if (enabled) { // enable CFDictionaryRemoveValue(newConfig, kSCResvInactive); } else { // disable CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); } } else { if (!enabled) { // disable newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); } } // set new configuration if (_SC_CFEqual(curConfig, newConfig)) { // 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 { ok = SCPreferencesPathRemoveValue(prefs, path); if (!ok && (SCError() == kSCStatusNoKey)) { ok = TRUE; } } return ok; }
/* * For rdar://problem/4685223 * * To keep MoreSCF happy we need to ensure that the first "Set" and * "NetworkService" have a [less than] unique identifier that can * be parsed as a numeric string. * * Note: this backwards compatibility code must be enabled using the * following command: * * sudo defaults write \ * /Library/Preferences/SystemConfiguration/preferences \ * MoreSCF \ * -bool true */ __private_extern__ CFStringRef __SCPreferencesPathCreateUniqueChild_WithMoreSCFCompatibility(SCPreferencesRef prefs, CFStringRef prefix) { static int hack = -1; CFStringRef path = NULL; if (hack < 0) { CFBooleanRef enable; enable = SCPreferencesGetValue(prefs, CFSTR("MoreSCF")); hack = (isA_CFBoolean(enable) && CFBooleanGetValue(enable)) ? 1 : 0; } if (hack > 0) { CFDictionaryRef dict; Boolean ok; path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), prefix, CFSTR("0")); dict = SCPreferencesPathGetValue(prefs, path); if (dict != NULL) { // if path "0" exists CFRelease(path); return NULL; } // unique child with path "0" does not exist, create dict = CFDictionaryCreate(NULL, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ok = SCPreferencesPathSetValue(prefs, path, dict); CFRelease(dict); if (!ok) { // if create failed CFRelease(path); return NULL; } } return path; }
CFArrayRef SCVLANInterfaceCopyAll(SCPreferencesRef prefs) { addContext context; CFDictionaryRef dict; CFStringRef path; context.vlans = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); context.prefs = prefs; path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeVLAN); dict = SCPreferencesPathGetValue(prefs, path); CFRelease(path); if (isA_CFDictionary(dict)) { my_CFDictionaryApplyFunction(dict, add_configured_interface, &context); } return context.vlans; }
CFStringRef SCNetworkSetGetName(SCNetworkSetRef set) { CFBundleRef bundle; CFDictionaryRef entity; CFStringRef path; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } if (setPrivate->name != NULL) { return setPrivate->name; } path = SCPreferencesPathKeyCreateSet(NULL, setPrivate->setID); entity = SCPreferencesPathGetValue(setPrivate->prefs, path); CFRelease(path); if (isA_CFDictionary(entity)) { CFStringRef name; name = CFDictionaryGetValue(entity, kSCPropUserDefinedName); if (isA_CFString(name)) { setPrivate->name = CFRetain(name); } } bundle = _SC_CFBundleGet(); if (bundle != NULL) { if (setPrivate->name != NULL) { CFStringRef non_localized; non_localized = _SC_CFBundleCopyNonLocalizedString(bundle, CFSTR("DEFAULT_SET_NAME"), CFSTR("Automatic"), NULL); if (non_localized != NULL) { if (CFEqual(setPrivate->name, non_localized)) { CFStringRef localized; // if "Automatic", return localized name localized = CFBundleCopyLocalizedString(bundle, CFSTR("DEFAULT_SET_NAME"), CFSTR("Automatic"), NULL); if (localized != NULL) { CFRelease(setPrivate->name); setPrivate->name = localized; } } CFRelease(non_localized); } } } return setPrivate->name; }
SCBondInterfaceRef SCBondInterfaceCreate(SCPreferencesRef prefs) { CFAllocatorRef allocator; SCBondInterfaceRef bond = NULL; CFIndex i; if (prefs == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } allocator = CFGetAllocator(prefs); // create a new bond using an unused interface name for (i = 0; bond == NULL; i++) { CFDictionaryRef dict; CFStringRef bond_if; SCNetworkInterfacePrivateRef interfacePrivate; CFMutableDictionaryRef newDict; CFArrayRef newInterfaces; Boolean ok; CFStringRef path; bond_if = CFStringCreateWithFormat(allocator, NULL, CFSTR("bond%ld"), i); path = CFStringCreateWithFormat(allocator, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeBond, bond_if); dict = SCPreferencesPathGetValue(prefs, path); if (dict != NULL) { // if bond interface name not available CFRelease(path); CFRelease(bond_if); continue; } // add the bond to the stored preferences newDict = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); newInterfaces = CFArrayCreate(allocator, NULL, 0, &kCFTypeArrayCallBacks); CFDictionaryAddValue(newDict, kSCPropVirtualNetworkInterfacesBondInterfaces, newInterfaces); CFRelease(newInterfaces); ok = SCPreferencesPathSetValue(prefs, path, newDict); CFRelease(newDict); CFRelease(path); if (!ok) { // if the bond could not be saved CFRelease(bond_if); break; } // create the SCBondInterfaceRef bond = (SCBondInterfaceRef)_SCBondInterfaceCreatePrivate(allocator, bond_if); CFRelease(bond_if); // estabish link to the stored configuration interfacePrivate = (SCNetworkInterfacePrivateRef)bond; interfacePrivate->prefs = CFRetain(prefs); } return bond; }
Boolean SCBondInterfaceSetLocalizedDisplayName(SCBondInterfaceRef bond, CFStringRef newName) { SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)bond; Boolean ok = TRUE; if (!isA_SCBondInterface(bond)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if ((newName != NULL) && !isA_CFString(newName)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } // set name in the stored preferences if (interfacePrivate->prefs != NULL) { CFDictionaryRef dict; CFMutableDictionaryRef newDict; CFStringRef path; path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeBond, interfacePrivate->entity_device); dict = SCPreferencesPathGetValue(interfacePrivate->prefs, path); if (!isA_CFDictionary(dict)) { // if the prefs are confused CFRelease(path); _SCErrorSet(kSCStatusFailed); return FALSE; } newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); if (newName != NULL) { CFDictionarySetValue(newDict, kSCPropUserDefinedName, newName); } else { CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName); } if (!CFEqual(dict, newDict)) { ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); } CFRelease(newDict); CFRelease(path); } // set name in the SCBondInterfaceRef if (ok) { if (interfacePrivate->localized_name != NULL) { CFRelease(interfacePrivate->localized_name); interfacePrivate->localized_name = NULL; } if (newName != NULL) { interfacePrivate->localized_name = CFStringCreateCopy(NULL, newName); } } return ok; }
CFArrayRef /* of SCNetworkServiceRef's */ SCNetworkSetCopyServices(SCNetworkSetRef set) { CFMutableArrayRef array; CFDictionaryRef dict; CFIndex n; CFStringRef path; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } path = SCPreferencesPathKeyCreateSetNetworkService(NULL, setPrivate->setID, NULL); dict = SCPreferencesPathGetValue(setPrivate->prefs, path); CFRelease(path); if ((dict != NULL) && !isA_CFDictionary(dict)) { return NULL; } array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); n = (dict != NULL) ? CFDictionaryGetCount(dict) : 0; if (n > 0) { CFIndex i; const void * keys_q[N_QUICK]; const void ** keys = keys_q; if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) { keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0); } CFDictionaryGetKeysAndValues(dict, keys, NULL); for (i = 0; i < n; i++) { CFArrayRef components; CFStringRef link; path = SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL, setPrivate->setID, (CFStringRef)keys[i], NULL); link = SCPreferencesPathGetLink(setPrivate->prefs, path); CFRelease(path); if (link == NULL) { SC_log(LOG_INFO, "service \"%@\" for set \"%@\" is not a link", keys[i], setPrivate->setID); continue; // if the service is not a link } components = CFStringCreateArrayBySeparatingStrings(NULL, link, CFSTR("/")); if (CFArrayGetCount(components) == 3) { CFStringRef serviceID; serviceID = CFArrayGetValueAtIndex(components, 2); path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator serviceID, // service NULL); // entity if (CFEqual(path, link)) { SCNetworkServicePrivateRef servicePrivate; servicePrivate = __SCNetworkServiceCreatePrivate(NULL, setPrivate->prefs, serviceID, NULL); CFArrayAppendValue(array, (SCNetworkServiceRef)servicePrivate); CFRelease(servicePrivate); } CFRelease(path); } CFRelease(components); } if (keys != keys_q) { CFAllocatorDeallocate(NULL, keys); } } return array; }
Boolean _SCNetworkSetSetSetID(SCNetworkSetRef set, CFStringRef newSetID) { SCNetworkSetRef currentSet = NULL; SCNetworkSetPrivateRef currentSetPrivate = NULL; CFDictionaryRef entity; CFStringRef newPath; Boolean ok = FALSE; CFStringRef oldPath = NULL; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; Boolean updateCurrentSet = FALSE; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (!isA_CFString(newSetID)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } // If newSetID is equal to current setID, our work is done if (CFEqual(newSetID, setPrivate->setID)) { return TRUE; } newPath = SCPreferencesPathKeyCreateSet(NULL, newSetID); entity = SCPreferencesPathGetValue(setPrivate->prefs, newPath); if (isA_CFDictionary(entity)) { // if the new set already exists _SCErrorSet(kSCStatusKeyExists); goto done; } oldPath = SCPreferencesPathKeyCreateSet(NULL, setPrivate->setID); entity = SCPreferencesPathGetValue(setPrivate->prefs, oldPath); if (!isA_CFDictionary(entity)) { // if the set has already been removed _SCErrorSet(kSCStatusNoKey); goto done; } ok = SCPreferencesPathSetValue(setPrivate->prefs, newPath, entity); if (!ok) { goto done; } ok = SCPreferencesPathRemoveValue(setPrivate->prefs, oldPath); if (!ok) { goto done; } // update current set (if needed) currentSet = SCNetworkSetCopyCurrent(setPrivate->prefs); if (currentSet != NULL) { currentSetPrivate = (SCNetworkSetPrivateRef)currentSet; if (CFEqual(currentSetPrivate->setID, setPrivate->setID)) { updateCurrentSet = TRUE; } CFRelease(currentSet); } CFRetain(newSetID); CFRelease(setPrivate->setID); setPrivate->setID = newSetID; if (updateCurrentSet) { SCNetworkSetSetCurrent(set); } done: if (oldPath != NULL) { CFRelease(oldPath); } if (newPath != NULL) { CFRelease(newPath); } return ok; }
static void flatten(SCPreferencesRef prefs, CFStringRef key, CFDictionaryRef base) { CFDictionaryRef subset; CFStringRef link; CFMutableDictionaryRef myDict; CFStringRef myKey; CFIndex i; CFIndex nKeys; const void **keys; const void **vals; if (!CFDictionaryGetValueIfPresent(base, kSCResvLink, (const void **)&link)) { /* if this dictionary is not linked */ subset = base; } else { /* if __LINK__ key is present */ subset = SCPreferencesPathGetValue(prefs, link); if (!subset) { /* if error with link */ SCLog(TRUE, LOG_ERR, CFSTR("SCPreferencesPathGetValue(,%@,) failed: %s"), link, SCErrorString(SCError())); return; } } if (CFDictionaryContainsKey(subset, kSCResvInactive)) { /* if __INACTIVE__ key is present */ return; } myKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), kSCDynamicStoreDomainSetup, key); myDict = (CFMutableDictionaryRef)CFDictionaryGetValue(newPrefs, myKey); if (myDict) { myDict = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)myDict); } else { myDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } nKeys = CFDictionaryGetCount(subset); if (nKeys > 0) { keys = CFAllocatorAllocate(NULL, nKeys * sizeof(CFStringRef) , 0); vals = CFAllocatorAllocate(NULL, nKeys * sizeof(CFPropertyListRef), 0); CFDictionaryGetKeysAndValues(subset, keys, vals); for (i = 0; i < nKeys; i++) { if (CFGetTypeID((CFTypeRef)vals[i]) != CFDictionaryGetTypeID()) { /* add this key/value to the current dictionary */ CFDictionarySetValue(myDict, keys[i], vals[i]); } else { CFStringRef subKey; /* flatten [sub]dictionaries */ subKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%s%@"), key, CFEqual(key, CFSTR("/")) ? "" : "/", keys[i]); flatten(prefs, subKey, vals[i]); CFRelease(subKey); } } CFAllocatorDeallocate(NULL, keys); CFAllocatorDeallocate(NULL, vals); } if (CFDictionaryGetCount(myDict) > 0) { /* add this dictionary to the new preferences */ CFDictionarySetValue(newPrefs, myKey, myDict); } CFRelease(myDict); CFRelease(myKey); return; }
Boolean SCNetworkSetSetName(SCNetworkSetRef set, CFStringRef name) { CFBundleRef bundle = NULL; CFDictionaryRef entity; CFStringRef localized = NULL; CFStringRef non_localized = NULL; Boolean ok = FALSE; CFStringRef path; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if ((name != NULL) && !isA_CFString(name)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } // if known, compare against localized name if (name != NULL) { bundle = _SC_CFBundleGet(); if (bundle != NULL) { non_localized = _SC_CFBundleCopyNonLocalizedString(bundle, CFSTR("DEFAULT_SET_NAME"), CFSTR("Automatic"), NULL); if (non_localized != NULL) { if (CFEqual(name, non_localized)) { localized = CFBundleCopyLocalizedString(bundle, CFSTR("DEFAULT_SET_NAME"), CFSTR("Automatic"), NULL); if (localized != NULL) { name = localized; } } } } } #define PREVENT_DUPLICATE_SET_NAMES #ifdef PREVENT_DUPLICATE_SET_NAMES if (name != NULL) { CFArrayRef sets; // ensure that each set is uniquely named sets = SCNetworkSetCopyAll(setPrivate->prefs); if (sets != NULL) { CFIndex i; CFIndex n; n = CFArrayGetCount(sets); for (i = 0; i < n; i++) { CFStringRef otherID; CFStringRef otherName; SCNetworkSetRef set = CFArrayGetValueAtIndex(sets, i); otherID = SCNetworkSetGetSetID(set); if (CFEqual(setPrivate->setID, otherID)) { continue; // skip current set } otherName = SCNetworkSetGetName(set); if ((otherName != NULL) && CFEqual(name, otherName)) { // if "name" not unique CFRelease(sets); _SCErrorSet(kSCStatusKeyExists); goto done; } } CFRelease(sets); } } #endif /* PREVENT_DUPLICATE_SET_NAMES */ // if known, store non-localized name if ((name != NULL) && (bundle != NULL) && (non_localized != NULL)) { if (localized == NULL) { localized = CFBundleCopyLocalizedString(bundle, CFSTR("DEFAULT_SET_NAME"), CFSTR("Automatic"), NULL); } if (localized != NULL) { if (CFEqual(name, localized)) { name = non_localized; } } } // update the "name" path = SCPreferencesPathKeyCreateSet(NULL, setPrivate->setID); entity = SCPreferencesPathGetValue(setPrivate->prefs, path); if (isA_CFDictionary(entity) || ((entity == NULL) && (name != NULL))) { CFMutableDictionaryRef newEntity; if (entity != NULL) { newEntity = CFDictionaryCreateMutableCopy(NULL, 0, entity); } else { newEntity = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } if (name != NULL) { CFDictionarySetValue(newEntity, kSCPropUserDefinedName, name); } else { CFDictionaryRemoveValue(newEntity, kSCPropUserDefinedName); } ok = SCPreferencesPathSetValue(setPrivate->prefs, path, newEntity); CFRelease(newEntity); } CFRelease(path); done : if (localized != NULL) CFRelease(localized); if (non_localized != NULL) CFRelease(non_localized); return ok; }
static void updateSCDynamicStore(SCPreferencesRef prefs) { CFStringRef current = NULL; CFDateRef date = NULL; CFMutableDictionaryRef dict = NULL; CFDictionaryRef global = NULL; CFIndex i; CFArrayRef keys; CFIndex n; CFStringRef pattern; CFMutableArrayRef patterns; CFDictionaryRef set = NULL; /* * initialize old preferences, new preferences, an array * of keys which have not changed, and an array of keys * to be removed (cleaned up). */ patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); pattern = CFStringCreateWithFormat(NULL, NULL, CFSTR("^%@.*"), kSCDynamicStoreDomainSetup); CFArrayAppendValue(patterns, pattern); dict = (CFMutableDictionaryRef)SCDynamicStoreCopyMultiple(store, NULL, patterns); CFRelease(patterns); CFRelease(pattern); if (dict) { currentPrefs = CFDictionaryCreateMutableCopy(NULL, 0, dict); CFRelease(dict); } else { currentPrefs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } unchangedPrefsKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); i = CFDictionaryGetCount(currentPrefs); if (i > 0) { const void **currentKeys; CFArrayRef array; currentKeys = CFAllocatorAllocate(NULL, i * sizeof(CFStringRef), 0); CFDictionaryGetKeysAndValues(currentPrefs, currentKeys, NULL); array = CFArrayCreate(NULL, currentKeys, i, &kCFTypeArrayCallBacks); removedPrefsKeys = CFArrayCreateMutableCopy(NULL, 0, array); CFRelease(array); CFAllocatorDeallocate(NULL, currentKeys); } else { removedPrefsKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } /* * The "newPrefs" dictionary will contain the new / updated * configuration which will be written to the configuration cache. */ newPrefs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); /* * create status dictionary associated with current configuration * information including: * - current set "name" to cache * - time stamp indicating when the cache preferences were * last updated. */ dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); date = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent()); /* * load preferences */ keys = SCPreferencesCopyKeyList(prefs); if ((keys == NULL) || (CFArrayGetCount(keys) == 0)) { SCLog(TRUE, LOG_NOTICE, CFSTR("updateConfiguration(): no preferences.")); goto done; } /* * get "global" system preferences */ global = SCPreferencesGetValue(prefs, kSCPrefSystem); if (!global) { /* if no global preferences are defined */ goto getSet; } if (!isA_CFDictionary(global)) { SCLog(TRUE, LOG_ERR, CFSTR("updateConfiguration(): %@ is not a dictionary."), kSCPrefSystem); goto done; } /* flatten property list */ flatten(prefs, CFSTR("/"), global); getSet : /* * get current set name */ current = SCPreferencesGetValue(prefs, kSCPrefCurrentSet); if (!current) { /* if current set not defined */ goto done; } if (!isA_CFString(current)) { SCLog(TRUE, LOG_ERR, CFSTR("updateConfiguration(): %@ is not a string."), kSCPrefCurrentSet); goto done; } /* * get current set */ set = SCPreferencesPathGetValue(prefs, current); if (!set) { /* if error with path */ SCLog(TRUE, LOG_ERR, CFSTR("%@ value (%@) not valid"), kSCPrefCurrentSet, current); goto done; } if (!isA_CFDictionary(set)) { SCLog(TRUE, LOG_ERR, CFSTR("updateConfiguration(): %@ is not a dictionary."), current); goto done; } /* flatten property list */ flatten(prefs, CFSTR("/"), set); CFDictionarySetValue(dict, kSCDynamicStorePropSetupCurrentSet, current); done : /* add last updated time stamp */ CFDictionarySetValue(dict, kSCDynamicStorePropSetupLastUpdated, date); /* add Setup: key */ CFDictionarySetValue(newPrefs, kSCDynamicStoreDomainSetup, dict); /* compare current and new preferences */ CFDictionaryApplyFunction(newPrefs, updateCache, NULL); /* remove those keys which have not changed from the update */ n = CFArrayGetCount(unchangedPrefsKeys); for (i = 0; i < n; i++) { CFStringRef key; key = CFArrayGetValueAtIndex(unchangedPrefsKeys, i); CFDictionaryRemoveValue(newPrefs, key); } /* Update the dynamic store */ #ifndef MAIN if (!SCDynamicStoreSetMultiple(store, newPrefs, removedPrefsKeys, NULL)) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreSetMultiple() failed: %s"), SCErrorString(SCError())); } #else // !MAIN SCLog(TRUE, LOG_NOTICE, CFSTR("SCDynamicStore\nset: %@\nremove: %@\n"), newPrefs, removedPrefsKeys); #endif // !MAIN CFRelease(currentPrefs); CFRelease(newPrefs); CFRelease(unchangedPrefsKeys); CFRelease(removedPrefsKeys); if (dict) CFRelease(dict); if (date) CFRelease(date); if (keys) CFRelease(keys); return; }
Boolean SCVLANInterfaceSetOptions(SCVLANInterfaceRef vlan, CFDictionaryRef newOptions) { SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)vlan; Boolean ok = TRUE; if (!isA_SCVLANInterface(vlan)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if ((newOptions != NULL) && !isA_CFDictionary(newOptions)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } // set options in the stored preferences if (interfacePrivate->prefs != NULL) { CFDictionaryRef dict; CFMutableDictionaryRef newDict; CFStringRef path; path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeVLAN, interfacePrivate->entity_device); dict = SCPreferencesPathGetValue(interfacePrivate->prefs, path); if (!isA_CFDictionary(dict)) { // if the prefs are confused CFRelease(path); _SCErrorSet(kSCStatusFailed); return FALSE; } newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); if (newOptions != NULL) { CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesVLANOptions, newOptions); } else { CFDictionaryRemoveValue(newDict, kSCPropVirtualNetworkInterfacesVLANOptions); } if (!CFEqual(dict, newDict)) { ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); } CFRelease(newDict); CFRelease(path); } // set options in the SCVLANInterfaceRef if (ok) { if (interfacePrivate->vlan.options != NULL) { CFRelease(interfacePrivate->vlan.options); interfacePrivate->vlan.options = NULL; } if (newOptions != NULL) { interfacePrivate->vlan.options = CFDictionaryCreateCopy(NULL, newOptions); } } return ok; }
Boolean SCVLANInterfaceSetPhysicalInterfaceAndTag(SCVLANInterfaceRef vlan, SCNetworkInterfaceRef physical, CFNumberRef tag) { SCNetworkInterfacePrivateRef interfacePrivate; Boolean ok = TRUE; if (!isA_SCVLANInterface(vlan)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (!isA_SCNetworkInterface(physical)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } interfacePrivate = (SCNetworkInterfacePrivateRef)physical; if (!interfacePrivate->supportsVLAN) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (isA_CFNumber(tag)) { int tag_val; CFNumberGetValue(tag, kCFNumberIntType, &tag_val); if ((tag_val < 1) || (tag_val > 4094)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } } else { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } interfacePrivate = (SCNetworkInterfacePrivateRef)vlan; if (interfacePrivate->prefs != NULL) { SCVLANInterfaceRef config_vlan; CFDictionaryRef dict; CFMutableDictionaryRef newDict; CFStringRef path; // make sure that physical interface and tag are not used config_vlan = findVLANInterfaceAndTag(interfacePrivate->prefs, physical, tag); if (config_vlan != NULL) { if (!CFEqual(vlan, config_vlan)) { CFRelease(config_vlan); _SCErrorSet(kSCStatusKeyExists); return FALSE; } CFRelease(config_vlan); } // set interface/tag in the stored preferences path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeVLAN, interfacePrivate->entity_device); dict = SCPreferencesPathGetValue(interfacePrivate->prefs, path); if (!isA_CFDictionary(dict)) { // if the prefs are confused CFRelease(path); _SCErrorSet(kSCStatusFailed); return FALSE; } newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesVLANInterface, SCNetworkInterfaceGetBSDName(physical)); CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesVLANTag, tag); if (!CFEqual(dict, newDict)) { ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); } CFRelease(newDict); CFRelease(path); } if (ok) { SCNetworkInterfacePrivateRef newInterface; CFTypeRef save; // set physical interface newInterface = __SCNetworkInterfaceCreateCopy(NULL, physical, interfacePrivate->prefs, interfacePrivate->serviceID); save = interfacePrivate->vlan.interface; interfacePrivate->vlan.interface = (SCNetworkInterfaceRef)newInterface; if (save != NULL) CFRelease(save); // set tag save = interfacePrivate->vlan.tag; interfacePrivate->vlan.tag = CFRetain(tag); if (save != NULL) CFRelease(save); } return ok; }
SCVLANInterfaceRef SCVLANInterfaceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef physical, CFNumberRef tag) { CFAllocatorRef allocator; CFIndex i; SCNetworkInterfacePrivateRef interfacePrivate; SCVLANInterfaceRef vlan; if (prefs == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } if (!isA_SCNetworkInterface(physical)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } interfacePrivate = (SCNetworkInterfacePrivateRef)physical; if (!interfacePrivate->supportsVLAN) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } if (isA_CFNumber(tag)) { int tag_val; CFNumberGetValue(tag, kCFNumberIntType, &tag_val); if ((tag_val < 1) || (tag_val > 4094)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } } else { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } // make sure that physical interface and tag are not used vlan = findVLANInterfaceAndTag(prefs, physical, tag); if (vlan != NULL) { CFRelease(vlan); _SCErrorSet(kSCStatusKeyExists); return NULL; } allocator = CFGetAllocator(prefs); // create a new VLAN using an unused interface name for (i = 0; vlan == NULL; i++) { CFDictionaryRef dict; CFStringRef vlan_if; Boolean ok; CFStringRef path; vlan_if = CFStringCreateWithFormat(allocator, NULL, CFSTR("vlan%ld"), i); path = CFStringCreateWithFormat(allocator, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeVLAN, vlan_if); dict = SCPreferencesPathGetValue(prefs, path); if (dict != NULL) { // if VLAN interface name not available CFRelease(path); CFRelease(vlan_if); continue; } // add the VLAN to the stored preferences dict = CFDictionaryCreate(allocator, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ok = SCPreferencesPathSetValue(prefs, path, dict); CFRelease(dict); CFRelease(path); if (!ok) { // if the VLAN could not be saved CFRelease(vlan_if); _SCErrorSet(kSCStatusFailed); break; } // create the SCVLANInterfaceRef vlan = (SCVLANInterfaceRef)_SCVLANInterfaceCreatePrivate(allocator, vlan_if); CFRelease(vlan_if); // estabish link to the stored configuration interfacePrivate = (SCNetworkInterfacePrivateRef)vlan; interfacePrivate->prefs = CFRetain(prefs); // set physical interface and tag SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan, physical, tag); } return vlan; }
static Boolean _SCBondInterfaceSetMemberInterfaces(SCBondInterfaceRef bond, CFArrayRef members) { CFIndex i; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)bond; CFIndex n; CFMutableArrayRef newMembers; Boolean ok = TRUE; n = (members != NULL) ? CFArrayGetCount(members) : 0; // set member interfaces in the stored preferences if (interfacePrivate->prefs != NULL) { CFDictionaryRef dict; CFMutableDictionaryRef newDict; CFStringRef path; path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeBond, interfacePrivate->entity_device); dict = SCPreferencesPathGetValue(interfacePrivate->prefs, path); if (!isA_CFDictionary(dict)) { // if the prefs are confused CFRelease(path); _SCErrorSet(kSCStatusFailed); return FALSE; } newMembers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (i = 0; i < n; i++) { SCNetworkInterfaceRef interface; CFStringRef memberName; interface = CFArrayGetValueAtIndex(members, i); memberName = SCNetworkInterfaceGetBSDName(interface); CFArrayAppendValue(newMembers, memberName); } newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesBondInterfaces, newMembers); CFRelease(newMembers); if (!CFEqual(dict, newDict)) { ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); } CFRelease(newDict); CFRelease(path); } if (ok) { newMembers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (i = 0; i < n; i++) { SCNetworkInterfaceRef member; SCNetworkInterfacePrivateRef newMember; member = CFArrayGetValueAtIndex(members, i); newMember = __SCNetworkInterfaceCreateCopy(NULL, member, interfacePrivate->prefs, interfacePrivate->serviceID); CFArrayAppendValue(newMembers, newMember); CFRelease(newMember); } CFRelease(interfacePrivate->bond.interfaces); interfacePrivate->bond.interfaces = newMembers; } return ok; }
int set_global_proxy(int enable, const char* host, int port) { printf("set global proxy %d %s %d\n", enable, host, port); SCPreferencesRef pref = SCPreferencesCreate(kCFAllocatorSystemDefault, CFSTR("setproxy"), 0); if(!pref){ printf("Failed to open preference.\n"); return 1; } CFDictionaryRef set = SCPreferencesPathGetValue(pref, CFSTR("/NetworkServices/")); if(!set){ printf("Failed to get network services.\n"); } CFMutableDictionaryRef mset = CFDictionaryCreateMutableCopy(0, 0, set); SCDynamicStoreRef theDynamicStore = SCDynamicStoreCreate(nil, CFSTR("setproxy"), nil, nil); CFDictionaryRef returnedPList; returnedPList = (CFDictionaryRef)SCDynamicStoreCopyValue(theDynamicStore, CFSTR("State:/Network/Global/IPv4")); CFStringRef primaryService = NULL; if(returnedPList){ primaryService = (CFStringRef)CFDictionaryGetValue(returnedPList, CFSTR("PrimaryService")); } size_t size = CFDictionaryGetCount(set); CFTypeRef *keysTypeRef = (CFTypeRef *) malloc( size * sizeof(CFTypeRef) ); CFTypeRef *valuesTypeRef = (CFTypeRef *) malloc( size * sizeof(CFTypeRef) ); CFDictionaryGetKeysAndValues(set, (const void **) keysTypeRef, (const void**)valuesTypeRef); const void **keys = (const void **) keysTypeRef; printf("Number of interfaces = %ld\n", size); int i; for(i=0; i<size && keysTypeRef[i]; i++){ Boolean success; CFStringRef service = (CFStringRef)keysTypeRef[i]; printf("Setting interface %d\n", i); if(enable == 1 && primaryService && CFStringCompare(service, primaryService, kCFCompareCaseInsensitive) != 0){ continue; } CFTypeRef value = valuesTypeRef[i]; if(!value){ continue; } CFDictionaryRef face = (CFDictionaryRef)value; CFMutableDictionaryRef mface = CFDictionaryCreateMutableCopy(0, 0, face); CFMutableDictionaryRef mproxy = NULL; CFDictionaryRef proxy = (CFDictionaryRef)CFDictionaryGetValue(mface, CFSTR("Proxies")); if(NULL == proxy){ if(enable == 0){ CFRelease(mface); continue; } printf("proxy = %p, try to create it\n", proxy); mproxy = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); }else{ mproxy = CFDictionaryCreateMutableCopy(0, 0, proxy); if(mproxy == NULL) return 4; } if(enable){ CFStringRef cfHost = CFStringCreateWithCString(0, host, kCFStringEncodingASCII); CFDictionarySetValue(mproxy, CFSTR("HTTPEnable"), CFNumberCreate(0, kCFNumberIntType, &enable)); CFDictionarySetValue(mproxy, CFSTR("HTTPProxy"), cfHost); CFDictionarySetValue(mproxy, CFSTR("HTTPPort"), CFNumberCreate(0, kCFNumberIntType, &port)); CFDictionarySetValue(mproxy, CFSTR("HTTPSEnable"), CFNumberCreate(0, kCFNumberIntType, &enable)); CFDictionarySetValue(mproxy, CFSTR("HTTPSProxy"), cfHost); CFDictionarySetValue(mproxy, CFSTR("HTTPSPort"), CFNumberCreate(0, kCFNumberIntType, &port)); CFRelease(cfHost); }else{ CFDictionaryRemoveValue(mproxy, CFSTR("HTTPEnable")); CFDictionaryRemoveValue(mproxy, CFSTR("HTTPProxy")); CFDictionaryRemoveValue(mproxy, CFSTR("HTTPPort")); CFDictionaryRemoveValue(mproxy, CFSTR("HTTPSEnable")); CFDictionaryRemoveValue(mproxy, CFSTR("HTTPSProxy")); CFDictionaryRemoveValue(mproxy, CFSTR("HTTPSPort")); } CFDictionarySetValue(mface, CFSTR("Proxies"), mproxy); CFDictionarySetValue(mset, service, mface); SCPreferencesPathSetValue(pref, CFSTR("/NetworkServices/"), mset); success = SCPreferencesCommitChanges(pref); printf("success: %d\n", success); success = SCPreferencesApplyChanges(pref); printf("success: %d\n", success); CFRelease(mface); CFRelease(mproxy); } CFRelease(mset); CFRelease(pref); free(keysTypeRef); free(valuesTypeRef); }