/* * Function: copy_configured_interface_names * * Purpose: * Return the BSD interface name of all configured interfaces. If * 'entity' is non-NULL, also check that the interface has the specified * extended configuration. */ STATIC CFArrayRef /* of CFStringRef */ copy_configured_interface_names(SCPreferencesRef prefs, CFStringRef entity_name) { SCNetworkSetRef current_set = NULL; int count; int i; CFMutableArrayRef ret_names = NULL; CFRange ret_names_range = { 0 , 0 }; CFArrayRef services = NULL; if (prefs == NULL) { goto done; } current_set = SCNetworkSetCopyCurrent(prefs); if (current_set == NULL) { goto done; } services = SCNetworkSetCopyServices(current_set); if (services == NULL) { goto done; } count = CFArrayGetCount(services); for (i = 0; i < count; i++) { CFStringRef this_if_name; SCNetworkInterfaceRef this_if; SCNetworkServiceRef s; s = (SCNetworkServiceRef)CFArrayGetValueAtIndex(services, i); this_if = SCNetworkServiceGetInterface(s); if (this_if == NULL) { continue; } if (entity_name != NULL && (SCNetworkInterfaceGetExtendedConfiguration(this_if, entity_name) == NULL)) { /* interface doesn't have specified entity */ continue; } this_if_name = SCNetworkInterfaceGetBSDName(this_if); if (this_if_name == NULL) { continue; } if (ret_names == NULL || CFArrayContainsValue(ret_names, ret_names_range, this_if_name) == FALSE) { if (ret_names == NULL) { ret_names = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks); } CFArrayAppendValue(ret_names, this_if_name); ret_names_range.length++; } } done: my_CFRelease(¤t_set); my_CFRelease(&services); return (ret_names); }
/* * Function: copy_interface * Purpose: * Get a reference to an SCNetworkInterfaceRef for the specified * interface name. First try to get an interface configured in the * current set. If that fails, copy a service configured over the * specified interface, and add it to the current set. * * Return the interface, service, and set for the caller to release. */ STATIC SCNetworkInterfaceRef copy_interface(SCPreferencesRef prefs, CFStringRef if_name, SCNetworkSetRef * ret_set_p, SCNetworkServiceRef * ret_service_p) { SCNetworkSetRef current_set = NULL; SCNetworkServiceRef service = NULL; SCNetworkInterfaceRef net_if; SCNetworkInterfaceRef ret = NULL; /* if the interface is part of a service/set, we're done */ net_if = copy_configured_interface(prefs, if_name); if (net_if != NULL) { ret = net_if; CFRetain(ret); goto done; } /* interface isn't part of a service/set, make it so */ net_if = copy_present_interface(if_name); if (net_if == NULL) { goto done; } /* find the service in any set */ service = copy_service(prefs, net_if); if (service == NULL) { EAPLOG(LOG_ERR, "EAPOLClientConfiguration: can't get service"); goto done; } /* add the service to the current set */ current_set = SCNetworkSetCopyCurrent(prefs); if (current_set == NULL) { EAPLOG(LOG_ERR, "EAPOLClientConfiguration: can't get current set"); goto done; } if (SCNetworkSetAddService(current_set, service) == FALSE) { EAPLOG(LOG_ERR, "EAPOLClientConfiguration: failed to add dummy service"); goto done; } /* return this SCNetworkInterfaceRef since it's bound to the prefs */ ret = SCNetworkServiceGetInterface(service); CFRetain(ret); done: my_CFRelease(&net_if); if (ret == NULL) { my_CFRelease(&service); my_CFRelease(¤t_set); } *ret_service_p = service; *ret_set_p = current_set; return (ret); }
/* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ static void nc_select(int argc, char **argv) { SCNetworkSetRef current_set; int exit_code = 1; SCNetworkServiceRef service = NULL; Boolean status; do_prefs_init(); /* initialization */ do_prefs_open(0, NULL); /* open default prefs */ current_set = SCNetworkSetCopyCurrent(prefs); if (current_set == NULL) { SCPrint(TRUE, stderr, CFSTR("No current location\n"), SCErrorString(SCError())); goto done; } service = nc_copy_service_from_arguments(argc, argv, current_set); if (service == NULL) { SCPrint(TRUE, stderr, CFSTR("No service\n")); goto done; } #if !TARGET_OS_IPHONE status = SCNetworkServiceSetEnabled(service, TRUE); if (!status) { SCPrint(TRUE, stderr, CFSTR("Unable to enable service: %s\n"), SCErrorString(SCError())); goto done; } #else status = SCNetworkSetSetSelectedVPNService(current_set, service); if (!status) { SCPrint(TRUE, stderr, CFSTR("Unable to select service: %s\n"), SCErrorString(SCError())); goto done; } #endif _prefs_save(); exit_code = 0; done: my_CFRelease(&service); my_CFRelease(¤t_set); _prefs_close(); exit(exit_code); }
vector<InterfaceInfo> OSXPlatform::interfaces() { vector<InterfaceInfo> result; CFStringRef name = CFSTR("com.codebutler.firesheep.backend"); SCPreferencesRef prefs = SCPreferencesCreate(NULL, name, NULL); SCNetworkSetRef set = SCNetworkSetCopyCurrent(prefs); CFArrayRef services = SCNetworkSetCopyServices(set); int arraySize = CFArrayGetCount(services); for (int i = 0; i < arraySize; i++) { SCNetworkServiceRef service = (SCNetworkServiceRef) CFArrayGetValueAtIndex(services, i); if (SCNetworkServiceGetEnabled(service)) { SCNetworkInterfaceRef iface = SCNetworkServiceGetInterface(service); CFStringRef serviceName = SCNetworkServiceGetName(service); char cServiceName[(CFStringGetLength(serviceName) * 4) + 1]; CFStringGetCString(serviceName, cServiceName, sizeof(cServiceName), kCFStringEncodingUTF8); CFStringRef type = SCNetworkInterfaceGetInterfaceType(iface); if (CFStringCompare(type, CFSTR("Ethernet"), 0) == kCFCompareEqualTo || CFStringCompare(type, CFSTR("IEEE80211"), 0) == kCFCompareEqualTo) { char cType[(CFStringGetLength(type) * 4) + 1]; CFStringGetCString(type, cType, sizeof(cType), kCFStringEncodingUTF8); CFStringRef bsdName = SCNetworkInterfaceGetBSDName(iface); char cBsdName[(CFStringGetLength(bsdName) * 4) + 1]; CFStringGetCString(bsdName, cBsdName, sizeof(cBsdName), kCFStringEncodingUTF8); InterfaceInfo info((string(cBsdName)), (string(cServiceName)), (string(cType))); result.push_back(info); } } } CFRelease(services); CFRelease(set); CFRelease(prefs); return result; }
STATIC SCNetworkInterfaceRef copy_configured_interface(SCPreferencesRef prefs, CFStringRef if_name) { SCNetworkSetRef current_set = NULL; int count; int i; SCNetworkInterfaceRef ret_if = NULL; CFArrayRef services = NULL; current_set = SCNetworkSetCopyCurrent(prefs); if (current_set == NULL) { goto done; } services = SCNetworkSetCopyServices(current_set); if (services == NULL) { goto done; } count = CFArrayGetCount(services); for (i = 0; i < count; i++) { CFStringRef this_if_name; SCNetworkInterfaceRef this_if; SCNetworkServiceRef s; s = (SCNetworkServiceRef)CFArrayGetValueAtIndex(services, i); this_if = SCNetworkServiceGetInterface(s); if (this_if == NULL) { continue; } this_if_name = SCNetworkInterfaceGetBSDName(this_if); if (this_if_name == NULL) { continue; } if (CFEqual(this_if_name, if_name)) { ret_if = this_if; CFRetain(ret_if); break; } } done: my_CFRelease(¤t_set); my_CFRelease(&services); return (ret_if); }
static void updateConfiguration(SCPreferencesRef prefs, SCPreferencesNotification notificationType, void *info) { #if !TARGET_OS_IPHONE if ((notificationType & kSCPreferencesNotificationCommit) == kSCPreferencesNotificationCommit) { SCNetworkSetRef current; current = SCNetworkSetCopyCurrent(prefs); if (current != NULL) { /* network configuration available, disable template creation */ watchQuietDisable(); CFRelease(current); } } #endif /* !TARGET_OS_IPHONE */ if ((notificationType & kSCPreferencesNotificationApply) != kSCPreferencesNotificationApply) { return; } SCLog(_verbose, LOG_DEBUG, CFSTR("updating configuration")); /* update SCDynamicStore (Setup:) */ updateSCDynamicStore(prefs); /* finished with current prefs, wait for changes */ if (!rofs) { SCPreferencesSynchronize(prefs); } return; }
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; }
__private_extern__ void load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose) { Boolean initPrefs = TRUE; if (bundleVerbose) { _verbose = TRUE; } SCLog(_verbose, LOG_DEBUG, CFSTR("load() called")); SCLog(_verbose, LOG_DEBUG, CFSTR(" bundle ID = %@"), CFBundleGetIdentifier(bundle)); /* open a SCDynamicStore session to allow cache updates */ store = SCDynamicStoreCreate(NULL, CFSTR("PreferencesMonitor.bundle"), watchQuietCallback, NULL); if (store == NULL) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreate() failed: %s"), SCErrorString(SCError())); goto error; } /* 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 if (prefs != NULL) { Boolean need_update = FALSE; CFStringRef new_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)) { // if new hardware need_update = TRUE; } } if (need_update == FALSE) { SCNetworkSetRef current; current = SCNetworkSetCopyCurrent(prefs); if (current != NULL) { /* network configuration available, disable template creation */ initPrefs = FALSE; CFRelease(current); } } } else { SCLog(TRUE, LOG_ERR, CFSTR("SCPreferencesCreate() failed: %s"), SCErrorString(SCError())); goto error; } /* * register for change notifications. */ if (!SCPreferencesSetCallback(prefs, updateConfiguration, NULL)) { SCLog(TRUE, LOG_ERR, CFSTR("SCPreferencesSetCallBack() failed: %s"), SCErrorString(SCError())); goto error; } if (!SCPreferencesScheduleWithRunLoop(prefs, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) { SCLog(TRUE, LOG_ERR, CFSTR("SCPreferencesScheduleWithRunLoop() failed: %s"), SCErrorString(SCError())); goto error; } /* * if no preferences, initialize with a template (now or * when IOKit has quiesced). */ if (initPrefs) { watchQuietEnable(); watchQuietCallback(store, NULL, NULL); } return; error : watchQuietDisable(); if (store != NULL) CFRelease(store); if (prefs != NULL) CFRelease(prefs); return; }
static Boolean establishNewPreferences() { CFBundleRef bundle; SCNetworkSetRef current = NULL; CFStringRef new_model; Boolean ok = FALSE; int sc_status = kSCStatusFailed; SCNetworkSetRef set = NULL; CFStringRef setName = NULL; Boolean updated = FALSE; while (TRUE) { ok = SCPreferencesLock(prefs, TRUE); if (ok) { break; } sc_status = SCError(); if (sc_status == kSCStatusStale) { SCPreferencesSynchronize(prefs); } else { SCLog(TRUE, LOG_ERR, CFSTR("Could not acquire network configuration lock: %s"), SCErrorString(sc_status)); return FALSE; } } /* Ensure that the preferences has the new 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); } current = SCNetworkSetCopyCurrent(prefs); if (current != NULL) { set = current; } if (set == NULL) { set = SCNetworkSetCreate(prefs); if (set == NULL) { ok = FALSE; sc_status = SCError(); goto done; } bundle = _SC_CFBundleGet(); if (bundle != NULL) { setName = CFBundleCopyLocalizedString(bundle, CFSTR("DEFAULT_SET_NAME"), CFSTR("Automatic"), NULL); } ok = SCNetworkSetSetName(set, (setName != NULL) ? setName : CFSTR("Automatic")); if (!ok) { sc_status = SCError(); goto done; } ok = SCNetworkSetSetCurrent(set); if (!ok) { sc_status = SCError(); goto done; } } ok = SCNetworkSetEstablishDefaultConfiguration(set); if (!ok) { sc_status = SCError(); goto done; } done : if (ok) { ok = SCPreferencesCommitChanges(prefs); if (ok) { SCLog(TRUE, LOG_NOTICE, CFSTR("New network configuration saved")); updated = TRUE; } else { sc_status = SCError(); if (sc_status == EROFS) { /* a read-only fileysstem is OK */ ok = TRUE; /* ... but we don't want to synchronize */ rofs = TRUE; } } /* apply (committed or temporary/read-only) changes */ (void) SCPreferencesApplyChanges(prefs); } else if ((current == NULL) && (set != NULL)) { (void) SCNetworkSetRemove(set); } if (!ok) { SCLog(TRUE, LOG_ERR, CFSTR("Could not establish network configuration: %s"), SCErrorString(sc_status)); } (void)SCPreferencesUnlock(prefs); if (setName != NULL) CFRelease(setName); if (set != NULL) CFRelease(set); return updated; }