Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #12
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
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;
}
Beispiel #17
0
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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
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;
}
Beispiel #24
0
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);
}