+ // get sharedSecret ID
+ shared_id = copySharedSecretID(config, serviceID);
+
+ // extract
+ (void) __extract_password(prefs,
+ config,
+ kSCPropNetIPSecSharedSecret,
+ kSCPropNetIPSecSharedSecretEncryption,
+ kSCValNetIPSecSharedSecretEncryptionKeychain,
+ shared_id,
+ &password);
+
+ CFRelease(shared_id);
+ break;
+ }
+
+ case kSCNetworkInterfacePasswordTypeEAPOL : {
+ CFDictionaryRef config;
+ CFStringRef unique_id = NULL;
+
+ // get configuration
+ config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
+
+ // get 802.1X identifier
+ if (config != NULL) {
+ unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
+ }
+ if (!isA_CFString(unique_id)) {
+ _SCErrorSet(kSCStatusFailed);
+ return NULL;
+ }
+
+ // copy password
+ password = _SCPreferencesSystemKeychainPasswordItemCopy(prefs, unique_id);
+ break;
+ }
+
+ default :
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ return password;
+}
+
+
+Boolean
+SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface,
+ SCNetworkInterfacePasswordType passwordType)
+{
+ Boolean ok = FALSE;
+ SCPreferencesRef prefs = NULL;
+ CFStringRef serviceID = NULL;
+
+ if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) {
+ return FALSE;
+ }
+
+ switch (passwordType) {
+ case kSCNetworkInterfacePasswordTypePPP : {
+ CFDictionaryRef config;
+ CFStringRef unique_id;
+
+ // get configuration
+ config = SCNetworkInterfaceGetConfiguration(interface);
+
+ // get serviceID
+ unique_id = getPasswordID(config, serviceID);
+
+ // remove password
+ ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, unique_id);
+ if (ok) {
+ CFMutableDictionaryRef newConfig;
+
+ if (config != NULL) {
+ newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
+ CFDictionaryRemoveValue(newConfig, kSCPropNetPPPAuthPassword);
+ CFDictionaryRemoveValue(newConfig, kSCPropNetPPPAuthPasswordEncryption);
+ ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
+ CFRelease(newConfig);
+ }
+ }
+ break;
+ }
+
+ case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
+ CFDictionaryRef config;
+ CFStringRef shared_id;
+
+ // get configuration
+ config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+
+ // get sharedSecret ID
+ shared_id = copySharedSecretID(config, serviceID);
+
+ // remove password
+ ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, shared_id);
+ if (ok) {
+ CFMutableDictionaryRef newConfig;
+
+ if (config != NULL) {
+ newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
+ CFDictionaryRemoveValue(newConfig, kSCPropNetIPSecSharedSecret);
+ CFDictionaryRemoveValue(newConfig, kSCPropNetIPSecSharedSecretEncryption);
+ ok = SCNetworkInterfaceSetExtendedConfiguration(interface,
+ kSCEntNetIPSec,
+ newConfig);
+ CFRelease(newConfig);
+ }
+ }
+
+ CFRelease(shared_id);
+ break;
+ }
+
+ case kSCNetworkInterfacePasswordTypeEAPOL : {
+ CFDictionaryRef config;
+ CFStringRef unique_id = NULL;
+
+ // get configuration
+ config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
+
+ // get 802.1X identifier
+ if (config != NULL) {
+ unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
+ }
+ if (!isA_CFString(unique_id)) {
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
+
+ // remove password
+ ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, unique_id);
+ break;
+ }
+
+ default :
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+
+ return ok;
+}
+
+
+Boolean
+SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface,
+ SCNetworkInterfacePasswordType passwordType,
+ CFDataRef password,
+ CFDictionaryRef options)
+{
+ CFStringRef account = NULL;
+ CFDictionaryRef config;
+ CFStringRef description = NULL;
+ CFStringRef label = NULL;
+ Boolean ok = FALSE;
+ SCPreferencesRef prefs = NULL;
+ CFStringRef serviceID = NULL;
+
+ if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) {
+ return FALSE;
+ }
+
+ switch (passwordType) {
+ case kSCNetworkInterfacePasswordTypePPP : {
+ SCNetworkServiceRef service = NULL;
+ CFStringRef unique_id;
+
+ // get configuration
+ config = SCNetworkInterfaceGetConfiguration(interface);
+
+ // get serviceID
+ unique_id = getPasswordID(config, serviceID);
+
+ // get "Account", "Name", "Kind"
+ if (config != NULL) {
+ // auth name --> keychain "Account"
+ account = CFDictionaryGetValue(config, kSCPropNetPPPAuthName);
+
+ // PPP [user defined] "name" --> keychain "Name"
+ label = CFDictionaryGetValue(config, kSCPropUserDefinedName);
+ }
+
+ if (label == NULL) {
+ // service name --> keychain "Name"
+ service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL,
+ prefs,
+ serviceID,
+ interface);
+
+ label = SCNetworkServiceGetName(service);
+ if (label == NULL) {
+ // interface name --> keychain "Name"
+ label = SCNetworkInterfaceGetLocalizedDisplayName(interface);
+ }
+ }
+
+ if (bundle != NULL) {
+ // "PPP Password" --> keychain "Kind"
+ description = CFBundleCopyLocalizedString(bundle,
+ CFSTR("KEYCHAIN_PPP_PASSWORD"),
+ CFSTR("PPP Password"),
+ NULL);
+ }
+
+ // store password
+ ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
+ unique_id,
+ (label != NULL) ? label : CFSTR("PPP"),
+ (description != NULL) ? description : CFSTR("PPP Password"),
+ account,
+ password,
+ options);
+ if (ok) {
+ CFMutableDictionaryRef newConfig;
+
+ if (config != NULL) {
+ newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
+ } else {
+ newConfig = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ }
+ CFDictionarySetValue(newConfig,
+ kSCPropNetPPPAuthPassword,
+ unique_id);
+ CFDictionarySetValue(newConfig,
+ kSCPropNetPPPAuthPasswordEncryption,
+ kSCValNetPPPAuthPasswordEncryptionKeychain);
+ ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
+ CFRelease(newConfig);
+ }
+
+ if (description != NULL) CFRelease(description);
+ if (service != NULL) CFRelease(service);
+ break;
+ }
+
+ case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
+ SCNetworkServiceRef service = NULL;
+ CFStringRef shared_id;
+
+ // get configuration
+ config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+
+ // get sharedSecret ID
+ shared_id = copySharedSecretID(config, serviceID);
+
+ // get "Name", "Kind"
+ if (config != NULL) {
+ // PPP [user defined] "name" --> keychain "Name"
+ label = CFDictionaryGetValue(config, kSCPropUserDefinedName);
+ }
+
+ if (label == NULL) {
+ // service name --> keychain "Name"
+ service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL,
+ prefs,
+ serviceID,
+ interface);
+
+ label = SCNetworkServiceGetName(service);
+ if (label == NULL) {
+ // interface name --> keychain "Name"
+ label = SCNetworkInterfaceGetLocalizedDisplayName(interface);
+ }
+ }
+
+ if (bundle != NULL) {
+ // "IPSec Shared Secret" --> keychain "Kind"
+ description = CFBundleCopyLocalizedString(bundle,
+ CFSTR("KEYCHAIN_IPSEC_SHARED_SECRET"),
+ CFSTR("IPSec Shared Secret"),
+ NULL);
+ }
+
+ // set password
+ ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
+ shared_id,
+ (label != NULL) ? label : CFSTR("PPP"),
+ (description != NULL) ? description : CFSTR("IPSec Shared Secret"),
+ NULL,
+ password,
+ options);
+ if (ok) {
+ CFMutableDictionaryRef newConfig = NULL;
+
+ if (config != NULL) {
+ newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
+ } else {
+ newConfig = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ }
+ CFDictionarySetValue(newConfig,
+ kSCPropNetIPSecSharedSecret,
+ shared_id);
+ CFDictionarySetValue(newConfig,
+ kSCPropNetIPSecSharedSecretEncryption,
+ kSCValNetIPSecSharedSecretEncryptionKeychain);
+ ok = SCNetworkInterfaceSetExtendedConfiguration(interface,
+ kSCEntNetIPSec,
+ newConfig);
+ CFRelease(newConfig);
+ }
+
+ if (description != NULL) CFRelease(description);
+ if (service != NULL) CFRelease(service);
+ CFRelease(shared_id);
+ break;
+ }
+
+ case kSCNetworkInterfacePasswordTypeEAPOL : {
+ CFStringRef unique_id = NULL;
+
+ // get configuration
+ config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
+
+ // get 802.1X identifier
+ if (config != NULL) {
+ unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
+ }
+ if (isA_CFString(unique_id)) {
+ CFRetain(unique_id);
+ } else {
+ CFUUIDRef uuid;
+
+ uuid = CFUUIDCreate(NULL);
+ unique_id = CFUUIDCreateString(NULL, uuid);
+ CFRelease(uuid);
+ }
+
+ // get "Name", "Kind"
+ if (bundle != NULL) {
+ // "802.1X Password" --> keychain "Name"
+ label = CFBundleCopyLocalizedString(bundle,
+ CFSTR("KEYCHAIN_EAPOL_PASSWORD"),
+ CFSTR("802.1X Password"),
+ NULL);
+ // "Internet Connect" --> keychain "Kind"
+ description = CFBundleCopyLocalizedString(bundle,
+ CFSTR("KEYCHAIN_INTERNET_CONNECT"),
+ CFSTR("Internet Connect"),
+ NULL);
+ }
+
+ // set password
+ ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
+ unique_id,
+ (label != NULL) ? label : CFSTR("802.1X Password"),
+ (description != NULL) ? description : CFSTR("Internet Connect"),
+ NULL,
+ password,
+ options);
+ if (ok) {
+ CFMutableDictionaryRef newConfig = NULL;
+
+ if (config != NULL) {
+ newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
+ } else {
+ newConfig = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ }
+ CFDictionarySetValue(newConfig,
+ kEAPClientPropUserPasswordKeychainItemID,
+ unique_id);
+ ok = SCNetworkInterfaceSetExtendedConfiguration(interface,
+ kSCEntNetEAPOL,
+ newConfig);
+ CFRelease(newConfig);
+ }
+
+ CFRelease(unique_id);
+ if (label != NULL) CFRelease(label);
+ if (description != NULL) CFRelease(description);
+ break;
+ }
+
+ default :
+ _SCErrorSet(kSCStatusInvalidArgument);
+ break;
+ }
+
+ return ok;
+}
+
+
+#pragma mark -
+#pragma mark SCNetworkInterface [InterfaceNamer] SPIs
+
+
+SCNetworkInterfaceRef
+_SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj)
+{
+ SCNetworkInterfaceRef interface;
+
+ /* initialize runtime */
+ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+
+ interface = createInterface(if_obj, processNetworkInterface);
+ return interface;
+}
+
+
+CFDataRef
+_SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->address;
+}
+
+
+CFNumberRef
+_SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->type;
+}
+
+
+CFNumberRef
+_SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->unit;
+}
+
+
+CFStringRef
+_SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->path;
+}
+
+
+Boolean
+_SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->builtin;
+}
+
+
+#pragma mark -
+#pragma mark SCNetworkInterface SPIs
+
+Boolean
+_SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->modemIsV92;
+}
+
+
+#pragma mark -
+#pragma mark SCNetworkInterface [internal] SPIs
+
+
+__private_extern__
+SCNetworkInterfacePrivateRef