2 * Copyright (c) 2006, 2007 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <CoreFoundation/CoreFoundation.h>
25 #include <CoreFoundation/CFRuntime.h>
26 #include <SystemConfiguration/SystemConfiguration.h>
27 #include <SystemConfiguration/SCPrivate.h> // for SCLog
28 #include "SCNetworkConfigurationInternal.h"
31 #include <ppp/PPPControllerPriv.h>
35 #pragma mark SCUserPreferences
40 // base CFType information
44 CFStringRef serviceID
;
46 // user preferences [unique] id
49 } SCUserPreferencesPrivate
, *SCUserPreferencesPrivateRef
;
52 static CFStringRef
__SCUserPreferencesCopyDescription (CFTypeRef cf
);
53 static void __SCUserPreferencesDeallocate (CFTypeRef cf
);
54 static Boolean
__SCUserPreferencesEqual (CFTypeRef cf1
, CFTypeRef cf2
);
55 static CFHashCode
__SCUserPreferencesHash (CFTypeRef cf
);
58 static CFTypeID __kSCUserPreferencesTypeID
= _kCFRuntimeNotATypeID
;
61 static const CFRuntimeClass __SCUserPreferencesClass
= {
63 "SCUserPreferences", // className
66 __SCUserPreferencesDeallocate
, // dealloc
67 __SCUserPreferencesEqual
, // equal
68 __SCUserPreferencesHash
, // hash
69 NULL
, // copyFormattingDesc
70 __SCUserPreferencesCopyDescription
// copyDebugDesc
74 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
78 __SCUserPreferencesCopyDescription(CFTypeRef cf
)
80 CFAllocatorRef allocator
= CFGetAllocator(cf
);
81 CFMutableStringRef result
;
82 SCUserPreferencesPrivateRef prefsPrivate
= (SCUserPreferencesPrivateRef
)cf
;
84 result
= CFStringCreateMutable(allocator
, 0);
85 CFStringAppendFormat(result
, NULL
, CFSTR("<SCUserPreferences %p [%p]> {"), cf
, allocator
);
86 CFStringAppendFormat(result
, NULL
, CFSTR("service = %@"), prefsPrivate
->serviceID
);
87 CFStringAppendFormat(result
, NULL
, CFSTR(", id = %@"), prefsPrivate
->prefsID
);
88 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
95 __SCUserPreferencesDeallocate(CFTypeRef cf
)
97 SCUserPreferencesPrivateRef prefsPrivate
= (SCUserPreferencesPrivateRef
)cf
;
99 /* release resources */
101 CFRelease(prefsPrivate
->prefsID
);
102 CFRelease(prefsPrivate
->serviceID
);
109 __SCUserPreferencesEqual(CFTypeRef cf1
, CFTypeRef cf2
)
111 SCUserPreferencesPrivateRef s1
= (SCUserPreferencesPrivateRef
)cf1
;
112 SCUserPreferencesPrivateRef s2
= (SCUserPreferencesPrivateRef
)cf2
;
117 if (!CFEqual(s1
->prefsID
, s2
->prefsID
))
118 return FALSE
; // if not the same [unique] prefs identifier
125 __SCUserPreferencesHash(CFTypeRef cf
)
127 SCUserPreferencesPrivateRef prefsPrivate
= (SCUserPreferencesPrivateRef
)cf
;
129 return CFHash(prefsPrivate
->prefsID
);
134 __SCUserPreferencesInitialize(void)
136 __kSCUserPreferencesTypeID
= _CFRuntimeRegisterClass(&__SCUserPreferencesClass
);
141 static SCUserPreferencesPrivateRef
142 __SCUserPreferencesCreatePrivate(CFAllocatorRef allocator
,
143 CFStringRef serviceID
,
146 SCUserPreferencesPrivateRef prefsPrivate
;
149 /* initialize runtime */
150 pthread_once(&initialized
, __SCUserPreferencesInitialize
);
152 /* allocate target */
153 size
= sizeof(SCUserPreferencesPrivate
) - sizeof(CFRuntimeBase
);
154 prefsPrivate
= (SCUserPreferencesPrivateRef
)_CFRuntimeCreateInstance(allocator
,
155 __kSCUserPreferencesTypeID
,
158 if (prefsPrivate
== NULL
) {
162 prefsPrivate
->serviceID
= CFStringCreateCopy(NULL
, serviceID
);
163 prefsPrivate
->prefsID
= CFStringCreateCopy(NULL
, prefsID
);
169 static __inline__ CFTypeRef
170 isA_SCUserPreferences(CFTypeRef obj
)
172 return (isA_CFType(obj
, SCUserPreferencesGetTypeID()));
177 #pragma mark SCUserPreferences SPIs
180 #define USER_PREFERENCES_NOTIFICATION "com.apple.networkConnect"
181 #define USER_PREFERENCES_APPLICATION_ID CFSTR("com.apple.networkConnect")
182 #define USER_PREFERENCES_ID CFSTR("UniqueIdentifier")
183 #define USER_PREFERENCES_DEFAULT CFSTR("ConnectByDefault")
187 copyCFPreferencesForServiceID(CFStringRef serviceID
)
191 // fetch "Managed" or "ByHost" user preferences
192 (void) CFPreferencesAppSynchronize(USER_PREFERENCES_APPLICATION_ID
);
193 prefs
= CFPreferencesCopyAppValue(serviceID
,
194 USER_PREFERENCES_APPLICATION_ID
);
196 if ((prefs
!= NULL
) && !isA_CFArray(prefs
)) {
206 setCFPreferencesForServiceID(CFStringRef serviceID
, CFArrayRef newPreferences
)
210 if (CFPreferencesAppValueIsForced(serviceID
, USER_PREFERENCES_APPLICATION_ID
)) {
214 CFPreferencesSetValue(serviceID
,
216 USER_PREFERENCES_APPLICATION_ID
,
217 kCFPreferencesCurrentUser
,
218 kCFPreferencesCurrentHost
);
219 ok
= CFPreferencesSynchronize(USER_PREFERENCES_APPLICATION_ID
,
220 kCFPreferencesCurrentUser
,
221 kCFPreferencesCurrentHost
);
223 (void) notify_post(USER_PREFERENCES_NOTIFICATION
);
230 addPreference(CFMutableArrayRef
*newPrefs
, CFDictionaryRef newDict
)
232 if (*newPrefs
== NULL
) {
233 *newPrefs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
235 CFArrayAppendValue(*newPrefs
, newDict
);
241 typedef CFDictionaryRef (*processPreferencesCallout
) (CFStringRef serviceID
,
242 CFDictionaryRef current
,
249 processPreferences(CFStringRef serviceID
,
250 processPreferencesCallout callout
,
255 Boolean changed
= FALSE
;
258 CFDictionaryRef newDict
= NULL
;
259 CFMutableArrayRef newPrefs
= NULL
;
263 prefs
= copyCFPreferencesForServiceID(serviceID
);
264 n
= (prefs
!= NULL
) ? CFArrayGetCount(prefs
) : 0;
265 for (i
= 0; i
< n
; i
++) {
266 CFDictionaryRef dict
;
268 dict
= CFArrayGetValueAtIndex(prefs
, i
);
269 if (isA_CFDictionary(dict
)) {
270 newDict
= (*callout
)(serviceID
, dict
, context1
, context2
, context3
);
271 if (newDict
== NULL
) {
272 // if entry to be removed
277 // if not a CFDictionary, leave as-is
278 newDict
= CFRetain(dict
);
281 if (!CFEqual(dict
, newDict
)) {
285 addPreference(&newPrefs
, newDict
);
288 if (prefs
!= NULL
) CFRelease(prefs
);
290 newDict
= (*callout
)(serviceID
, NULL
, context1
, context2
, context3
);
291 if (newDict
!= NULL
) {
294 addPreference(&newPrefs
, newDict
);
299 ok
= setCFPreferencesForServiceID(serviceID
, newPrefs
);
301 if (newPrefs
!= NULL
) CFRelease(newPrefs
);
307 static __inline__ Boolean
308 isMatchingPrefsID(CFDictionaryRef dict
, CFStringRef matchID
)
312 prefsID
= CFDictionaryGetValue(dict
, USER_PREFERENCES_ID
);
313 if (isA_CFString(prefsID
)) {
314 if (CFEqual(prefsID
, matchID
)) {
324 SCUserPreferencesGetTypeID(void)
326 pthread_once(&initialized
, __SCUserPreferencesInitialize
); /* initialize runtime */
327 return __kSCUserPreferencesTypeID
;
332 SCUserPreferencesGetUniqueID(SCUserPreferencesRef userPreferences
)
334 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
336 if (!isA_SCUserPreferences(userPreferences
)) {
337 _SCErrorSet(kSCStatusInvalidArgument
);
341 return userPrivate
->prefsID
;
346 SCUserPreferencesIsForced(SCUserPreferencesRef userPreferences
)
348 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
350 if (!isA_SCUserPreferences(userPreferences
)) {
351 _SCErrorSet(kSCStatusInvalidArgument
);
355 return CFPreferencesAppValueIsForced(userPrivate
->serviceID
, USER_PREFERENCES_APPLICATION_ID
);
359 static CFDictionaryRef
360 removeCallout(CFStringRef serviceID
,
361 CFDictionaryRef current
,
366 CFStringRef matchID
= (CFStringRef
)context1
;
368 if (current
== NULL
) {
369 // we have nothing to "add"
373 if (isMatchingPrefsID(current
, matchID
)) {
374 // if we match, don't add (i.e. remove)
378 return CFRetain(current
);
383 SCUserPreferencesRemove(SCUserPreferencesRef userPreferences
)
385 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
387 if (!isA_SCUserPreferences(userPreferences
)) {
388 _SCErrorSet(kSCStatusInvalidArgument
);
392 return processPreferences(userPrivate
->serviceID
,
394 (void *)userPrivate
->prefsID
,
400 static CFDictionaryRef
401 setCurrentCallout(CFStringRef serviceID
,
402 CFDictionaryRef current
,
407 CFStringRef matchID
= (CFStringRef
)context1
;
408 CFMutableDictionaryRef newDict
;
410 if (current
== NULL
) {
411 // we have nothing to "add"
415 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
417 // remove "default" flag
418 CFDictionaryRemoveValue(newDict
, USER_PREFERENCES_DEFAULT
);
420 if (isMatchingPrefsID(current
, matchID
)) {
421 // if we match, set "default" flag
422 CFDictionarySetValue(newDict
, USER_PREFERENCES_DEFAULT
, kCFBooleanTrue
);
430 SCUserPreferencesSetCurrent(SCUserPreferencesRef userPreferences
)
432 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
434 if (!isA_SCUserPreferences(userPreferences
)) {
435 _SCErrorSet(kSCStatusInvalidArgument
);
439 return processPreferences(userPrivate
->serviceID
,
441 (void *)userPrivate
->prefsID
,
447 static CFDictionaryRef
448 copyNameCallout(CFStringRef serviceID
,
449 CFDictionaryRef current
,
454 CFStringRef matchID
= (CFStringRef
)context1
;
455 CFStringRef
*name
= (CFStringRef
*)context3
;
457 if (current
== NULL
) {
458 // we have nothing to "add"
462 if (isMatchingPrefsID(current
, matchID
)) {
463 *name
= CFDictionaryGetValue(current
, kSCPropUserDefinedName
);
465 // for backwards compatibility, we also check for the name in the PPP entity
469 ppp
= CFDictionaryGetValue(current
, kSCEntNetPPP
);
470 if (isA_CFDictionary(ppp
)) {
471 *name
= CFDictionaryGetValue(ppp
, kSCPropUserDefinedName
);
475 *name
= isA_CFString(*name
);
481 return CFRetain(current
);
486 SCUserPreferencesCopyName(SCUserPreferencesRef userPreferences
)
488 CFStringRef name
= NULL
;
490 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
492 if (!isA_SCUserPreferences(userPreferences
)) {
493 _SCErrorSet(kSCStatusInvalidArgument
);
497 // find SCUserPreferences and copy name
498 ok
= processPreferences(userPrivate
->serviceID
,
500 (void *)userPrivate
->prefsID
,
514 static CFDictionaryRef
515 setNameCallout(CFStringRef serviceID
,
516 CFDictionaryRef current
,
521 CFStringRef matchID
= (CFStringRef
)context1
;
522 CFMutableDictionaryRef newDict
;
523 CFStringRef newName
= (CFStringRef
)context2
;
525 if (current
== NULL
) {
526 // we have nothing to "add"
530 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
532 if (isMatchingPrefsID(current
, matchID
)) {
533 CFDictionaryRef pppEntity
;
536 if (newName
!= NULL
) {
537 CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, newName
);
539 CFDictionaryRemoveValue(newDict
, kSCPropUserDefinedName
);
542 // for backwards compatibility, we also set the name in the PPP entity
543 pppEntity
= CFDictionaryGetValue(newDict
, kSCEntNetPPP
);
544 if (isA_CFDictionary(pppEntity
)) {
545 CFMutableDictionaryRef newPPPEntity
;
547 newPPPEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, pppEntity
);
548 if (newName
!= NULL
) {
549 CFDictionarySetValue(newPPPEntity
, kSCPropUserDefinedName
, newName
);
551 CFDictionaryRemoveValue(newPPPEntity
, kSCPropUserDefinedName
);
553 CFDictionarySetValue(newDict
, kSCEntNetPPP
, newPPPEntity
);
554 CFRelease(newPPPEntity
);
563 SCUserPreferencesSetName(SCUserPreferencesRef userPreferences
, CFStringRef newName
)
566 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
568 if (!isA_SCUserPreferences(userPreferences
)) {
569 _SCErrorSet(kSCStatusInvalidArgument
);
573 if ((newName
!= NULL
) && !isA_CFString(newName
)) {
574 _SCErrorSet(kSCStatusInvalidArgument
);
578 // find SCUserPreferences and set name
579 ok
= processPreferences(userPrivate
->serviceID
,
581 (void *)userPrivate
->prefsID
,
589 static CFDictionaryRef
590 copyInterfaceConfigurationCallout(CFStringRef serviceID
,
591 CFDictionaryRef current
,
596 CFDictionaryRef
*dict
= (CFDictionaryRef
*)context3
;
597 CFStringRef interfaceType
= (CFStringRef
)context2
;
598 CFStringRef matchID
= (CFStringRef
)context1
;
600 if (current
== NULL
) {
601 // we have nothing to "add"
605 if (isMatchingPrefsID(current
, matchID
)) {
606 *dict
= CFDictionaryGetValue(current
, interfaceType
);
607 *dict
= isA_CFDictionary(*dict
);
613 return CFRetain(current
);
618 SCUserPreferencesCopyInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
619 SCNetworkInterfaceRef interface
)
621 CFStringRef defaultType
;
622 CFDictionaryRef entity
= NULL
;
624 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
626 if (!isA_SCUserPreferences(userPreferences
)) {
627 _SCErrorSet(kSCStatusInvalidArgument
);
631 if (!isA_SCNetworkInterface(interface
)) {
632 _SCErrorSet(kSCStatusInvalidArgument
);
637 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
638 if (defaultType
== NULL
) {
639 _SCErrorSet(kSCStatusInvalidArgument
);
643 // find SCUserPreferences and copy interface entity
644 ok
= processPreferences(userPrivate
->serviceID
,
645 copyInterfaceConfigurationCallout
,
646 (void *)userPrivate
->prefsID
,
650 if (entity
!= NULL
) {
660 static CFDictionaryRef
661 setInterfaceConfigurationCallout(CFStringRef serviceID
,
662 CFDictionaryRef current
,
667 CFStringRef interfaceType
= (CFStringRef
)context2
;
668 CFStringRef matchID
= (CFStringRef
)context1
;
669 CFMutableDictionaryRef newDict
;
670 CFDictionaryRef newOptions
= (CFDictionaryRef
)context3
;
672 if (current
== NULL
) {
673 // we have nothing to "add"
677 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
679 if (isMatchingPrefsID(current
, matchID
)) {
680 if (newOptions
!= NULL
) {
681 CFDictionarySetValue(newDict
, interfaceType
, newOptions
);
683 // for backwards compatibility, we want to ensure that
684 // the name is set in both the top level and in the PPP
686 if (CFEqual(interfaceType
, kSCEntNetPPP
)) {
689 name
= CFDictionaryGetValue(newOptions
, kSCPropUserDefinedName
);
691 // if name was passed in newOptions, push up
692 CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, name
);
694 name
= CFDictionaryGetValue(newDict
, kSCPropUserDefinedName
);
696 CFMutableDictionaryRef newPPPEntity
;
698 // if name in parent, push into entity
699 newPPPEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, newOptions
);
700 CFDictionarySetValue(newPPPEntity
, kSCPropUserDefinedName
, name
);
701 CFDictionarySetValue(newDict
, interfaceType
, newPPPEntity
);
702 CFRelease(newPPPEntity
);
707 CFDictionaryRemoveValue(newDict
, interfaceType
);
716 SCUserPreferencesSetInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
717 SCNetworkInterfaceRef interface
,
718 CFDictionaryRef newOptions
)
720 CFStringRef defaultType
;
722 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
724 if (!isA_SCUserPreferences(userPreferences
)) {
725 _SCErrorSet(kSCStatusInvalidArgument
);
729 if (!isA_SCNetworkInterface(interface
)) {
730 _SCErrorSet(kSCStatusInvalidArgument
);
735 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
736 if (defaultType
== NULL
) {
737 _SCErrorSet(kSCStatusInvalidArgument
);
741 // set new interface entity for SCUserPreferences
742 ok
= processPreferences(userPrivate
->serviceID
,
743 setInterfaceConfigurationCallout
,
744 (void *)userPrivate
->prefsID
,
753 SCUserPreferencesCopyExtendedInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
754 SCNetworkInterfaceRef interface
,
755 CFStringRef extendedType
)
757 CFDictionaryRef entity
= NULL
;
759 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
761 if (!isA_SCUserPreferences(userPreferences
)) {
762 _SCErrorSet(kSCStatusInvalidArgument
);
766 if (!isA_SCNetworkInterface(interface
)) {
767 _SCErrorSet(kSCStatusInvalidArgument
);
771 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, FALSE
)) {
772 _SCErrorSet(kSCStatusInvalidArgument
);
776 // find SCUserPreferences and copy interface entity
777 ok
= processPreferences(userPrivate
->serviceID
,
778 copyInterfaceConfigurationCallout
,
779 (void *)userPrivate
->prefsID
,
780 (void *)extendedType
,
783 if (entity
!= NULL
) {
794 SCUserPreferencesSetExtendedInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
795 SCNetworkInterfaceRef interface
,
796 CFStringRef extendedType
,
797 CFDictionaryRef newOptions
)
800 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
802 if (!isA_SCUserPreferences(userPreferences
)) {
803 _SCErrorSet(kSCStatusInvalidArgument
);
807 if (!isA_SCNetworkInterface(interface
)) {
808 _SCErrorSet(kSCStatusInvalidArgument
);
812 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, FALSE
)) {
813 _SCErrorSet(kSCStatusInvalidArgument
);
817 // set new interface entity for SCUserPreferences
818 ok
= processPreferences(userPrivate
->serviceID
,
819 setInterfaceConfigurationCallout
,
820 (void *)userPrivate
->prefsID
,
821 (void *)extendedType
,
829 #pragma mark SCNetworkConnection + SCUserPreferences SPIs
832 static CFDictionaryRef
833 copyAllCallout(CFStringRef serviceID
,
834 CFDictionaryRef current
,
839 CFMutableArrayRef
*prefs
= (CFMutableArrayRef
*)context3
;
841 SCUserPreferencesPrivateRef userPrivate
;
843 if (current
== NULL
) {
844 // we have nothing to "add"
848 prefsID
= CFDictionaryGetValue(current
, USER_PREFERENCES_ID
);
849 if (!isA_CFString(prefsID
)) {
854 userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, prefsID
);
855 if (userPrivate
!= NULL
) {
856 if (*prefs
== NULL
) {
857 *prefs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
859 CFArrayAppendValue(*prefs
, (SCUserPreferencesRef
)userPrivate
);
860 CFRelease(userPrivate
);
865 return CFRetain(current
);
869 CFArrayRef
/* of SCUserPreferencesRef's */
870 SCNetworkConnectionCopyAllUserPreferences(SCNetworkConnectionRef connection
)
873 CFMutableArrayRef prefs
= NULL
;
874 CFStringRef serviceID
;
877 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
879 // collect SCUserPreferences
880 ok
= processPreferences(serviceID
,
892 CFRelease(serviceID
);
897 static CFDictionaryRef
898 copyCurrentCallout(CFStringRef serviceID
,
899 CFDictionaryRef current
,
904 CFBooleanRef isDefault
;
906 SCUserPreferencesPrivateRef
*userPrivate
= (SCUserPreferencesPrivateRef
*)context3
;
908 if (current
== NULL
) {
909 // we have nothing to "add"
913 prefsID
= CFDictionaryGetValue(current
, USER_PREFERENCES_ID
);
914 if (!isA_CFString(prefsID
)) {
919 isDefault
= CFDictionaryGetValue(current
, USER_PREFERENCES_DEFAULT
);
920 if (!isA_CFBoolean(isDefault
) || !CFBooleanGetValue(isDefault
)) {
921 // if not the default configuration
925 *userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, prefsID
);
929 return CFRetain(current
);
934 SCNetworkConnectionCopyCurrentUserPreferences(SCNetworkConnectionRef connection
)
936 SCUserPreferencesRef current
= NULL
;
938 CFStringRef serviceID
;
941 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
943 // collect SCUserPreferences
944 ok
= processPreferences(serviceID
,
950 if (current
!= NULL
) {
956 CFRelease(serviceID
);
961 static CFDictionaryRef
962 createCallout(CFStringRef serviceID
,
963 CFDictionaryRef current
,
968 CFMutableDictionaryRef newDict
;
969 CFStringRef newPrefsID
= (CFStringRef
)context1
;
971 if (current
!= NULL
) {
972 // don't change existing entries
973 return CFRetain(current
);
976 newDict
= CFDictionaryCreateMutable(NULL
,
978 &kCFTypeDictionaryKeyCallBacks
,
979 &kCFTypeDictionaryValueCallBacks
);
980 CFDictionarySetValue(newDict
, USER_PREFERENCES_ID
, newPrefsID
);
986 SCNetworkConnectionCreateUserPreferences(SCNetworkConnectionRef connection
)
988 CFStringRef newPrefsID
;
989 CFStringRef serviceID
;
990 SCUserPreferencesPrivateRef userPrivate
;
994 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
996 // allocate a new user preferences ID
997 uuid
= CFUUIDCreate(NULL
);
998 newPrefsID
= CFUUIDCreateString(NULL
, uuid
);
1001 userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, newPrefsID
);
1002 if (userPrivate
!= NULL
) {
1003 (void) processPreferences(serviceID
,
1010 CFRelease(newPrefsID
);
1011 CFRelease(serviceID
);
1012 return (SCUserPreferencesRef
)userPrivate
;
1018 SCNetworkConnectionSelectService(CFDictionaryRef selectionOptions
,
1019 SCNetworkServiceRef
*service
,
1020 SCUserPreferencesRef
*userPreferences
)
1028 update_PPP_entity(SCUserPreferencesRef userPreferences
, CFDictionaryRef
*userOptions
)
1030 CFStringRef encryption
;
1031 CFDictionaryRef entity
;
1032 CFStringRef keychainID
;
1034 entity
= CFDictionaryGetValue(*userOptions
, kSCEntNetPPP
);
1035 if (!isA_CFDictionary(entity
)) {
1039 encryption
= CFDictionaryGetValue(entity
, kSCPropNetPPPAuthPasswordEncryption
);
1040 if (encryption
== NULL
) {
1041 // provide default encryption method
1042 encryption
= kSCValNetPPPAuthPasswordEncryptionKeychain
;
1045 if (!isA_CFString(encryption
) ||
1046 !CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1050 keychainID
= CFDictionaryGetValue(entity
, kSCPropNetPPPAuthPassword
);
1051 if (isA_CFString(keychainID
)) {
1052 // if password is keychain ID
1053 } else if (isA_CFData(keychainID
) &&
1054 ((CFDataGetLength((CFDataRef
)keychainID
) % sizeof(UniChar
)) == 0)) {
1055 // if inline password
1058 keychainID
= SCUserPreferencesGetUniqueID(userPreferences
);
1061 if (_SCSecKeychainPasswordItemExists(NULL
, keychainID
)) {
1062 CFMutableDictionaryRef new_entity
;
1063 CFMutableDictionaryRef new_options
;
1065 // access PPP password from system keychain
1066 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1068 CFDictionarySetValue(new_entity
,
1069 kSCPropNetPPPAuthPassword
,
1071 CFDictionarySetValue(new_entity
,
1072 kSCPropNetPPPAuthPasswordEncryption
,
1073 kSCValNetPPPAuthPasswordEncryptionKeychain
);
1075 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1076 CFDictionarySetValue(new_options
, kSCEntNetPPP
, new_entity
);
1077 CFRelease(new_entity
);
1079 CFRelease(*userOptions
);
1080 *userOptions
= new_options
;
1088 update_IPSec_entity(SCUserPreferencesRef userPreferences
, CFDictionaryRef
*userOptions
)
1090 CFStringRef encryption
;
1091 CFDictionaryRef entity
;
1092 SecKeychainRef keychain
= NULL
;
1093 CFStringRef keychainID
;
1095 CFDataRef sharedSecret
;
1097 entity
= CFDictionaryGetValue(*userOptions
, kSCEntNetIPSec
);
1098 if (!isA_CFDictionary(entity
)) {
1102 method
= CFDictionaryGetValue(entity
, kSCPropNetIPSecAuthenticationMethod
);
1103 if (!isA_CFString(method
) ||
1104 !CFEqual(method
, kSCValNetIPSecAuthenticationMethodSharedSecret
)) {
1108 encryption
= CFDictionaryGetValue(entity
, kSCPropNetIPSecSharedSecretEncryption
);
1109 if (encryption
== NULL
) {
1110 // provide default encryption method
1111 encryption
= kSCValNetIPSecSharedSecretEncryptionKeychain
;
1114 if (!isA_CFString(encryption
) ||
1115 !CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1119 keychainID
= CFDictionaryGetValue(entity
, kSCPropNetIPSecSharedSecret
);
1120 if (isA_CFString(keychainID
)) {
1121 // if shared secret is keychain ID
1122 CFRetain(keychainID
);
1123 } else if (isA_CFData(keychainID
) &&
1124 ((CFDataGetLength((CFDataRef
)keychainID
) % sizeof(UniChar
)) == 0)) {
1125 // if inline shared secret
1128 CFStringRef unique_id
;
1130 unique_id
= SCUserPreferencesGetUniqueID(userPreferences
);
1131 keychainID
= (CFStringRef
)CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1132 CFStringAppend((CFMutableStringRef
)keychainID
, CFSTR(".SS"));
1135 sharedSecret
= _SCSecKeychainPasswordItemCopy(NULL
, keychainID
);
1136 if (sharedSecret
!= NULL
) {
1137 CFMutableDictionaryRef new_entity
;
1138 CFMutableDictionaryRef new_options
;
1139 CFStringRef password
;
1141 // pass SharedSecret from user keychain
1142 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1144 password
= CFStringCreateWithBytes(NULL
,
1145 CFDataGetBytePtr(sharedSecret
),
1146 CFDataGetLength(sharedSecret
),
1147 kCFStringEncodingUTF8
,
1149 CFRelease(sharedSecret
);
1150 CFDictionarySetValue(new_entity
,
1151 kSCPropNetIPSecSharedSecret
,
1153 CFRelease(password
);
1154 CFDictionaryRemoveValue(new_entity
,
1155 kSCPropNetIPSecSharedSecretEncryption
);
1157 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1158 CFDictionarySetValue(new_options
, kSCEntNetIPSec
, new_entity
);
1159 CFRelease(new_entity
);
1161 CFRelease(*userOptions
);
1162 *userOptions
= new_options
;
1166 keychain
= _SCSecKeychainCopySystemKeychain();
1167 if (keychain
== NULL
) {
1171 if (_SCSecKeychainPasswordItemExists(keychain
, keychainID
)) {
1172 CFMutableDictionaryRef new_entity
;
1173 CFMutableDictionaryRef new_options
;
1175 // access SharedSecret from system keychain
1176 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1178 CFDictionarySetValue(new_entity
,
1179 kSCPropNetIPSecSharedSecret
,
1181 CFDictionarySetValue(new_entity
,
1182 kSCPropNetIPSecSharedSecretEncryption
,
1183 kSCValNetIPSecSharedSecretEncryptionKeychain
);
1185 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1186 CFDictionarySetValue(new_options
, kSCEntNetIPSec
, new_entity
);
1187 CFRelease(new_entity
);
1189 CFRelease(*userOptions
);
1190 *userOptions
= new_options
;
1195 if (keychain
!= NULL
) CFRelease(keychain
);
1196 CFRelease(keychainID
);
1201 static CFDictionaryRef
1202 copyOptionsCallout(CFStringRef serviceID
,
1203 CFDictionaryRef current
,
1208 CFStringRef matchID
= (CFStringRef
)context1
;
1209 CFMutableDictionaryRef
*userOptions
= (CFMutableDictionaryRef
*)context3
;
1211 if (current
== NULL
) {
1212 // we have nothing to "add"
1216 if (isMatchingPrefsID(current
, matchID
)) {
1217 // if we match, return options dictionary
1218 if (*userOptions
!= NULL
) CFRelease(*userOptions
);
1219 *userOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
1220 CFDictionaryRemoveValue(*userOptions
, USER_PREFERENCES_ID
);
1221 CFDictionaryRemoveValue(*userOptions
, USER_PREFERENCES_DEFAULT
);
1224 return CFRetain(current
);
1229 SCNetworkConnectionStartWithUserPreferences(SCNetworkConnectionRef connection
,
1230 SCUserPreferencesRef userPreferences
,
1234 CFDictionaryRef userOptions
= NULL
;
1235 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
1237 if (!isA_SCUserPreferences(userPreferences
)) {
1238 _SCErrorSet(kSCStatusInvalidArgument
);
1242 (void) processPreferences(userPrivate
->serviceID
,
1244 (void *)userPrivate
->prefsID
,
1249 * For some legacy preferences, some of the user options
1250 * were missing yet handled by the APIs. Make sure that
1251 * everything still works!
1253 if (userOptions
!= NULL
) {
1254 update_PPP_entity (userPreferences
, &userOptions
);
1255 update_IPSec_entity(userPreferences
, &userOptions
);
1258 ok
= SCNetworkConnectionStart(connection
, userOptions
, linger
);
1260 if (userOptions
!= NULL
) {
1261 CFRelease(userOptions
);
1269 #pragma mark SCUserPreferences + SCNetworkInterface Password SPIs
1273 getUserPasswordID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1275 CFStringRef unique_id
= NULL
;
1277 if (config
!= NULL
) {
1278 CFStringRef encryption
;
1280 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
1281 if (isA_CFString(encryption
) &&
1282 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1283 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
1286 if (unique_id
== NULL
) {
1287 unique_id
= SCUserPreferencesGetUniqueID(userPreferences
);
1295 copyUserSharedSecretID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1297 CFMutableStringRef sharedSecret
= NULL
;
1299 if (config
!= NULL
) {
1300 CFStringRef encryption
;
1302 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
1303 if (isA_CFString(encryption
) &&
1304 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1305 sharedSecret
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
1306 if (sharedSecret
!= NULL
) {
1307 CFRetain(sharedSecret
);
1312 if (sharedSecret
== NULL
) {
1313 CFStringRef unique_id
;
1315 unique_id
= getUserPasswordID(config
, userPreferences
);
1316 sharedSecret
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1317 CFStringAppend(sharedSecret
, CFSTR(".SS"));
1320 return sharedSecret
;
1325 checkUserPreferencesPassword(SCUserPreferencesRef userPreferences
,
1326 SCNetworkInterfaceRef interface
,
1327 SCNetworkInterfacePasswordType passwordType
)
1329 if (!isA_SCUserPreferences(userPreferences
)) {
1330 _SCErrorSet(kSCStatusInvalidArgument
);
1334 if (!isA_SCNetworkInterface(interface
)) {
1335 _SCErrorSet(kSCStatusInvalidArgument
);
1339 switch (passwordType
) {
1340 case kSCNetworkInterfacePasswordTypePPP
: {
1341 CFStringRef interfaceType
;
1343 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1344 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1345 _SCErrorSet(kSCStatusInvalidArgument
);
1351 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1352 CFStringRef interfaceType
;
1354 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1355 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1356 _SCErrorSet(kSCStatusInvalidArgument
);
1360 interface
= SCNetworkInterfaceGetInterface(interface
);
1361 if (interface
== NULL
) {
1362 _SCErrorSet(kSCStatusInvalidArgument
);
1366 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1367 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
1368 _SCErrorSet(kSCStatusInvalidArgument
);
1374 case kSCNetworkInterfacePasswordTypeEAPOL
: {
1375 _SCErrorSet(kSCStatusInvalidArgument
);
1388 SCUserPreferencesCheckInterfacePassword(SCUserPreferencesRef userPreferences
,
1389 SCNetworkInterfaceRef interface
,
1390 SCNetworkInterfacePasswordType passwordType
)
1392 Boolean exists
= FALSE
;
1394 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1398 switch (passwordType
) {
1399 case kSCNetworkInterfacePasswordTypePPP
: {
1400 CFDictionaryRef config
;
1401 CFStringRef unique_id
;
1403 // get configuration
1404 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1406 // get userPreferences ID
1407 unique_id
= getUserPasswordID(config
, userPreferences
);
1410 exists
= __extract_password(NULL
,
1412 kSCPropNetPPPAuthPassword
,
1413 kSCPropNetPPPAuthPasswordEncryption
,
1414 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1418 if (config
!= NULL
) CFRelease(config
);
1422 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1423 CFDictionaryRef config
;
1424 CFStringRef shared_id
;
1426 // get configuration
1427 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1431 // get sharedSecret ID
1432 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1435 exists
= __extract_password(NULL
,
1437 kSCPropNetIPSecSharedSecret
,
1438 kSCPropNetIPSecSharedSecretEncryption
,
1439 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1443 if (config
!= NULL
) CFRelease(config
);
1444 CFRelease(shared_id
);
1449 _SCErrorSet(kSCStatusInvalidArgument
);
1458 SCUserPreferencesCopyInterfacePassword(SCUserPreferencesRef userPreferences
,
1459 SCNetworkInterfaceRef interface
,
1460 SCNetworkInterfacePasswordType passwordType
)
1462 CFDataRef password
= NULL
;
1464 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1468 switch (passwordType
) {
1469 case kSCNetworkInterfacePasswordTypePPP
: {
1470 CFDictionaryRef config
;
1471 CFStringRef unique_id
;
1473 // get configuration
1474 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1476 // get userPreferences ID
1477 unique_id
= getUserPasswordID(config
, userPreferences
);
1480 (void) __extract_password(NULL
,
1482 kSCPropNetPPPAuthPassword
,
1483 kSCPropNetPPPAuthPasswordEncryption
,
1484 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1488 if (config
!= NULL
) CFRelease(config
);
1492 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1493 CFDictionaryRef config
;
1494 CFStringRef shared_id
;
1496 // get configuration
1497 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1501 // get sharedSecret ID
1502 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1505 (void) __extract_password(NULL
,
1507 kSCPropNetIPSecSharedSecret
,
1508 kSCPropNetIPSecSharedSecretEncryption
,
1509 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1513 if (config
!= NULL
) CFRelease(config
);
1514 CFRelease(shared_id
);
1519 _SCErrorSet(kSCStatusInvalidArgument
);
1528 SCUserPreferencesRemoveInterfacePassword(SCUserPreferencesRef userPreferences
,
1529 SCNetworkInterfaceRef interface
,
1530 SCNetworkInterfacePasswordType passwordType
)
1534 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1538 switch (passwordType
) {
1539 case kSCNetworkInterfacePasswordTypePPP
: {
1540 CFDictionaryRef config
;
1541 CFStringRef unique_id
;
1543 // get configuration
1544 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1546 // get userPreferences ID
1547 unique_id
= getUserPasswordID(config
, userPreferences
);
1550 ok
= _SCSecKeychainPasswordItemRemove(NULL
, unique_id
);
1552 CFDictionaryRef config
;
1553 CFMutableDictionaryRef newConfig
;
1555 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1556 if (config
!= NULL
) {
1557 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
1558 CFDictionaryRemoveValue(newConfig
, kSCPropNetPPPAuthPassword
);
1559 CFDictionaryRemoveValue(newConfig
, kSCPropNetPPPAuthPasswordEncryption
);
1560 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1561 CFRelease(newConfig
);
1567 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1568 CFDictionaryRef config
;
1569 CFStringRef shared_id
;
1571 // get configuration
1572 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1576 // get sharedSecret ID
1577 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1580 ok
= _SCSecKeychainPasswordItemRemove(NULL
, shared_id
);
1582 CFMutableDictionaryRef newConfig
;
1584 if (config
!= NULL
) {
1585 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
1586 CFDictionaryRemoveValue(newConfig
, kSCPropNetIPSecSharedSecret
);
1587 CFDictionaryRemoveValue(newConfig
, kSCPropNetIPSecSharedSecretEncryption
);
1588 ok
= SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences
,
1592 CFRelease(newConfig
);
1596 if (config
!= NULL
) CFRelease(config
);
1597 CFRelease(shared_id
);
1602 _SCErrorSet(kSCStatusInvalidArgument
);
1611 SCUserPreferencesSetInterfacePassword(SCUserPreferencesRef userPreferences
,
1612 SCNetworkInterfaceRef interface
,
1613 SCNetworkInterfacePasswordType passwordType
,
1615 CFDictionaryRef options
)
1617 CFStringRef account
= NULL
;
1619 CFDictionaryRef config
;
1620 CFStringRef description
= NULL
;
1621 CFStringRef label
= NULL
;
1624 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1628 bundle
= _SC_CFBundleGet();
1630 switch (passwordType
) {
1631 case kSCNetworkInterfacePasswordTypePPP
: {
1632 CFStringRef unique_id
;
1634 // get configuration
1635 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1637 // get userPreferences ID
1638 unique_id
= getUserPasswordID(config
, userPreferences
);
1640 // User prefs auth name --> keychain "Account"
1641 if (config
!= NULL
) {
1642 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
1645 // User prefs "name" --> keychain "Name"
1646 label
= SCUserPreferencesCopyName(userPreferences
);
1648 // "PPP Password" --> keychain "Kind"
1649 if (bundle
!= NULL
) {
1650 description
= CFBundleCopyLocalizedString(bundle
,
1651 CFSTR("KEYCHAIN_PPP_PASSWORD"),
1652 CFSTR("PPP Password"),
1657 ok
= _SCSecKeychainPasswordItemSet(NULL
,
1659 (label
!= NULL
) ? label
: CFSTR("PPP"),
1660 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
1665 CFMutableDictionaryRef newConfig
;
1667 if (config
!= NULL
) {
1668 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
1670 newConfig
= CFDictionaryCreateMutable(NULL
,
1672 &kCFTypeDictionaryKeyCallBacks
,
1673 &kCFTypeDictionaryValueCallBacks
);
1675 CFDictionarySetValue(newConfig
,
1676 kSCPropNetPPPAuthPassword
,
1678 CFDictionarySetValue(newConfig
,
1679 kSCPropNetPPPAuthPasswordEncryption
,
1680 kSCValNetPPPAuthPasswordEncryptionKeychain
);
1681 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1682 CFRelease(newConfig
);
1685 if (config
!= NULL
) CFRelease(config
);
1686 if (description
!= NULL
) CFRelease(description
);
1687 if (label
!= NULL
) CFRelease(label
);
1691 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1692 CFStringRef shared_id
;
1694 // get configuration
1695 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1699 // get sharedSecret ID
1700 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1702 // User prefs "name" --> keychain "Name"
1703 label
= SCUserPreferencesCopyName(userPreferences
);
1705 // "IPSec Shared Secret" --> keychain "Kind"
1706 if (bundle
!= NULL
) {
1707 description
= CFBundleCopyLocalizedString(bundle
,
1708 CFSTR("KEYCHAIN_IPSEC_SHARED_SECRET"),
1709 CFSTR("IPSec Shared Secret"),
1714 ok
= _SCSecKeychainPasswordItemSet(NULL
,
1716 (label
!= NULL
) ? label
: CFSTR("PPP"),
1717 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
1722 CFMutableDictionaryRef newConfig
= NULL
;
1724 if (config
!= NULL
) {
1725 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
1727 newConfig
= CFDictionaryCreateMutable(NULL
,
1729 &kCFTypeDictionaryKeyCallBacks
,
1730 &kCFTypeDictionaryValueCallBacks
);
1732 CFDictionarySetValue(newConfig
,
1733 kSCPropNetIPSecSharedSecret
,
1735 CFDictionarySetValue(newConfig
,
1736 kSCPropNetIPSecSharedSecretEncryption
,
1737 kSCValNetIPSecSharedSecretEncryptionKeychain
);
1738 ok
= SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences
,
1742 CFRelease(newConfig
);
1745 if (config
!= NULL
) CFRelease(config
);
1746 if (description
!= NULL
) CFRelease(description
);
1747 if (label
!= NULL
) CFRelease(label
);
1748 CFRelease(shared_id
);
1753 _SCErrorSet(kSCStatusInvalidArgument
);