2 * Copyright (c) 2006-2010 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"
34 #pragma mark SCUserPreferences
39 // base CFType information
43 CFStringRef serviceID
;
45 // user preferences [unique] id
48 } SCUserPreferencesPrivate
, *SCUserPreferencesPrivateRef
;
51 static CFStringRef
__SCUserPreferencesCopyDescription (CFTypeRef cf
);
52 static void __SCUserPreferencesDeallocate (CFTypeRef cf
);
53 static Boolean
__SCUserPreferencesEqual (CFTypeRef cf1
, CFTypeRef cf2
);
54 static CFHashCode
__SCUserPreferencesHash (CFTypeRef cf
);
57 static CFTypeID __kSCUserPreferencesTypeID
= _kCFRuntimeNotATypeID
;
60 static const CFRuntimeClass __SCUserPreferencesClass
= {
62 "SCUserPreferences", // className
65 __SCUserPreferencesDeallocate
, // dealloc
66 __SCUserPreferencesEqual
, // equal
67 __SCUserPreferencesHash
, // hash
68 NULL
, // copyFormattingDesc
69 __SCUserPreferencesCopyDescription
// copyDebugDesc
73 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
77 __SCUserPreferencesCopyDescription(CFTypeRef cf
)
79 CFAllocatorRef allocator
= CFGetAllocator(cf
);
80 CFMutableStringRef result
;
81 SCUserPreferencesPrivateRef prefsPrivate
= (SCUserPreferencesPrivateRef
)cf
;
83 result
= CFStringCreateMutable(allocator
, 0);
84 CFStringAppendFormat(result
, NULL
, CFSTR("<SCUserPreferences %p [%p]> {"), cf
, allocator
);
85 CFStringAppendFormat(result
, NULL
, CFSTR("service = %@"), prefsPrivate
->serviceID
);
86 CFStringAppendFormat(result
, NULL
, CFSTR(", id = %@"), prefsPrivate
->prefsID
);
87 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
94 __SCUserPreferencesDeallocate(CFTypeRef cf
)
96 SCUserPreferencesPrivateRef prefsPrivate
= (SCUserPreferencesPrivateRef
)cf
;
98 /* release resources */
100 CFRelease(prefsPrivate
->prefsID
);
101 CFRelease(prefsPrivate
->serviceID
);
108 __SCUserPreferencesEqual(CFTypeRef cf1
, CFTypeRef cf2
)
110 SCUserPreferencesPrivateRef s1
= (SCUserPreferencesPrivateRef
)cf1
;
111 SCUserPreferencesPrivateRef s2
= (SCUserPreferencesPrivateRef
)cf2
;
116 if (!CFEqual(s1
->prefsID
, s2
->prefsID
))
117 return FALSE
; // if not the same [unique] prefs identifier
124 __SCUserPreferencesHash(CFTypeRef cf
)
126 SCUserPreferencesPrivateRef prefsPrivate
= (SCUserPreferencesPrivateRef
)cf
;
128 return CFHash(prefsPrivate
->prefsID
);
133 __SCUserPreferencesInitialize(void)
135 __kSCUserPreferencesTypeID
= _CFRuntimeRegisterClass(&__SCUserPreferencesClass
);
140 static SCUserPreferencesPrivateRef
141 __SCUserPreferencesCreatePrivate(CFAllocatorRef allocator
,
142 CFStringRef serviceID
,
145 SCUserPreferencesPrivateRef prefsPrivate
;
148 /* initialize runtime */
149 pthread_once(&initialized
, __SCUserPreferencesInitialize
);
151 /* allocate target */
152 size
= sizeof(SCUserPreferencesPrivate
) - sizeof(CFRuntimeBase
);
153 prefsPrivate
= (SCUserPreferencesPrivateRef
)_CFRuntimeCreateInstance(allocator
,
154 __kSCUserPreferencesTypeID
,
157 if (prefsPrivate
== NULL
) {
161 prefsPrivate
->serviceID
= CFStringCreateCopy(NULL
, serviceID
);
162 prefsPrivate
->prefsID
= CFStringCreateCopy(NULL
, prefsID
);
168 static __inline__ CFTypeRef
169 isA_SCUserPreferences(CFTypeRef obj
)
171 return (isA_CFType(obj
, SCUserPreferencesGetTypeID()));
176 #pragma mark SCUserPreferences SPIs
179 #define USER_PREFERENCES_NOTIFICATION "com.apple.networkConnect"
180 #define USER_PREFERENCES_APPLICATION_ID CFSTR("com.apple.networkConnect")
181 #define USER_PREFERENCES_ID CFSTR("UniqueIdentifier")
182 #define USER_PREFERENCES_DEFAULT CFSTR("ConnectByDefault")
185 #define LOG_CFPREFERENCES_CHANGES
186 #ifdef LOG_CFPREFERENCES_CHANGES
189 #include <sys/stat.h>
190 #include <sys/time.h>
192 logCFPreferencesChange(CFStringRef serviceID
, CFArrayRef newPreferences
)
196 CFArrayRef oldPreferences
;
200 struct timeval tv_now
;
202 bVal
= CFPreferencesCopyAppValue(CFSTR("LOG_SC_CHANGES"), USER_PREFERENCES_APPLICATION_ID
);
206 enabled
= isA_CFBoolean(bVal
) && CFBooleanGetValue(bVal
);
209 // if debugging not enabled
213 // if debugging not enabled
217 (void)gettimeofday(&tv_now
, NULL
);
218 (void)localtime_r(&tv_now
.tv_sec
, &tm_now
);
220 str
= CFStringCreateWithFormat(NULL
, NULL
,
221 CFSTR("/var/tmp/com.apple.networkConnect-%@-%4d%02d%02d.%02d%02d%02d.%03d"),
223 tm_now
.tm_year
+ 1900,
229 tv_now
.tv_usec
/ 1000);
230 _SC_cfstring_to_cstring(str
, dir
, sizeof(dir
), kCFStringEncodingUTF8
);
233 SCLog(TRUE
, LOG_ERR
, CFSTR("CFPreferences being updated, old/new in \"%s\""), dir
);
235 if (mkdir(dir
, 0755) == -1) {
236 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange mkdir() failed, error = %s"), SCErrorString(errno
));
240 trace
= _SC_copyBacktrace();
246 strlcpy(path
, dir
, sizeof(path
));
247 strlcat(path
, "/backtrace", sizeof(path
));
248 fd
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
250 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange fopen() failed, error = %s"), SCErrorString(errno
));
255 SCPrint(TRUE
, f
, CFSTR("%@"), trace
);
260 oldPreferences
= CFPreferencesCopyAppValue(serviceID
, USER_PREFERENCES_APPLICATION_ID
);
261 if (oldPreferences
!= NULL
) {
266 strlcpy(path
, dir
, sizeof(path
));
267 strlcat(path
, "/old", sizeof(path
));
268 fd
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
270 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange fopen() failed, error = %s"), SCErrorString(errno
));
271 CFRelease(oldPreferences
);
274 data
= CFPropertyListCreateData(NULL
, oldPreferences
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
);
276 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange CFPropertyListCreateData() failed"));
278 CFRelease(oldPreferences
);
281 (void) write(fd
, CFDataGetBytePtr(data
), CFDataGetLength(data
));
284 CFRelease(oldPreferences
);
287 if (newPreferences
!= NULL
) {
292 strlcpy(path
, dir
, sizeof(path
));
293 strlcat(path
, "/new", sizeof(path
));
294 fd
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
296 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange fopen() failed, error = %s"), SCErrorString(errno
));
299 data
= CFPropertyListCreateData(NULL
, newPreferences
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
);
301 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange CFPropertyListCreateData() failed"));
305 (void) write(fd
, CFDataGetBytePtr(data
), CFDataGetLength(data
));
312 #endif // LOG_CFPREFERENCES_CHANGES
316 copyCFPreferencesForServiceID(CFStringRef serviceID
)
320 // fetch "Managed" or "ByHost" user preferences
321 (void) CFPreferencesAppSynchronize(USER_PREFERENCES_APPLICATION_ID
);
322 prefs
= CFPreferencesCopyAppValue(serviceID
,
323 USER_PREFERENCES_APPLICATION_ID
);
325 if ((prefs
!= NULL
) && !isA_CFArray(prefs
)) {
335 setCFPreferencesForServiceID(CFStringRef serviceID
, CFArrayRef newPreferences
)
339 if (CFPreferencesAppValueIsForced(serviceID
, USER_PREFERENCES_APPLICATION_ID
)) {
343 #ifdef LOG_CFPREFERENCES_CHANGES
344 logCFPreferencesChange(serviceID
, newPreferences
);
345 #endif // LOG_CFPREFERENCES_CHANGES
347 CFPreferencesSetValue(serviceID
,
349 USER_PREFERENCES_APPLICATION_ID
,
350 kCFPreferencesCurrentUser
,
351 kCFPreferencesCurrentHost
);
352 ok
= CFPreferencesSynchronize(USER_PREFERENCES_APPLICATION_ID
,
353 kCFPreferencesCurrentUser
,
354 kCFPreferencesCurrentHost
);
356 (void) notify_post(USER_PREFERENCES_NOTIFICATION
);
363 addPreference(CFMutableArrayRef
*newPrefs
, CFDictionaryRef newDict
)
365 if (*newPrefs
== NULL
) {
366 *newPrefs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
368 CFArrayAppendValue(*newPrefs
, newDict
);
374 typedef CFDictionaryRef (*processPreferencesCallout
) (CFStringRef serviceID
,
375 CFDictionaryRef current
,
382 processPreferences(CFStringRef serviceID
,
383 processPreferencesCallout callout
,
388 Boolean changed
= FALSE
;
391 CFDictionaryRef newDict
= NULL
;
392 CFMutableArrayRef newPrefs
= NULL
;
396 prefs
= copyCFPreferencesForServiceID(serviceID
);
397 n
= (prefs
!= NULL
) ? CFArrayGetCount(prefs
) : 0;
398 for (i
= 0; i
< n
; i
++) {
399 CFDictionaryRef dict
;
401 dict
= CFArrayGetValueAtIndex(prefs
, i
);
402 if (isA_CFDictionary(dict
)) {
403 newDict
= (*callout
)(serviceID
, dict
, context1
, context2
, context3
);
404 if (newDict
== NULL
) {
405 // if entry to be removed
410 // if not a CFDictionary, leave as-is
411 newDict
= CFRetain(dict
);
414 if (!CFEqual(dict
, newDict
)) {
418 addPreference(&newPrefs
, newDict
);
421 if (prefs
!= NULL
) CFRelease(prefs
);
423 newDict
= (*callout
)(serviceID
, NULL
, context1
, context2
, context3
);
424 if (newDict
!= NULL
) {
427 addPreference(&newPrefs
, newDict
);
432 ok
= setCFPreferencesForServiceID(serviceID
, newPrefs
);
434 if (newPrefs
!= NULL
) CFRelease(newPrefs
);
440 static __inline__ Boolean
441 isMatchingPrefsID(CFDictionaryRef dict
, CFStringRef matchID
)
445 prefsID
= CFDictionaryGetValue(dict
, USER_PREFERENCES_ID
);
446 if (isA_CFString(prefsID
)) {
447 if (CFEqual(prefsID
, matchID
)) {
457 SCUserPreferencesGetTypeID(void)
459 pthread_once(&initialized
, __SCUserPreferencesInitialize
); /* initialize runtime */
460 return __kSCUserPreferencesTypeID
;
465 SCUserPreferencesGetUniqueID(SCUserPreferencesRef userPreferences
)
467 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
469 if (!isA_SCUserPreferences(userPreferences
)) {
470 _SCErrorSet(kSCStatusInvalidArgument
);
474 return userPrivate
->prefsID
;
479 SCUserPreferencesIsForced(SCUserPreferencesRef userPreferences
)
481 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
483 if (!isA_SCUserPreferences(userPreferences
)) {
484 _SCErrorSet(kSCStatusInvalidArgument
);
488 return CFPreferencesAppValueIsForced(userPrivate
->serviceID
, USER_PREFERENCES_APPLICATION_ID
);
492 static CFDictionaryRef
493 removeCallout(CFStringRef serviceID
,
494 CFDictionaryRef current
,
499 CFStringRef matchID
= (CFStringRef
)context1
;
501 if (current
== NULL
) {
502 // we have nothing to "add"
506 if (isMatchingPrefsID(current
, matchID
)) {
507 // if we match, don't add (i.e. remove)
511 return CFRetain(current
);
516 SCUserPreferencesRemove(SCUserPreferencesRef userPreferences
)
518 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
520 if (!isA_SCUserPreferences(userPreferences
)) {
521 _SCErrorSet(kSCStatusInvalidArgument
);
525 return processPreferences(userPrivate
->serviceID
,
527 (void *)userPrivate
->prefsID
,
533 static CFDictionaryRef
534 setCurrentCallout(CFStringRef serviceID
,
535 CFDictionaryRef current
,
540 CFStringRef matchID
= (CFStringRef
)context1
;
541 CFMutableDictionaryRef newDict
;
543 if (current
== NULL
) {
544 // we have nothing to "add"
548 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
550 // remove "default" flag
551 CFDictionaryRemoveValue(newDict
, USER_PREFERENCES_DEFAULT
);
553 if (isMatchingPrefsID(current
, matchID
)) {
554 // if we match, set "default" flag
555 CFDictionarySetValue(newDict
, USER_PREFERENCES_DEFAULT
, kCFBooleanTrue
);
563 SCUserPreferencesSetCurrent(SCUserPreferencesRef userPreferences
)
565 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
567 if (!isA_SCUserPreferences(userPreferences
)) {
568 _SCErrorSet(kSCStatusInvalidArgument
);
572 return processPreferences(userPrivate
->serviceID
,
574 (void *)userPrivate
->prefsID
,
580 static CFDictionaryRef
581 copyNameCallout(CFStringRef serviceID
,
582 CFDictionaryRef current
,
587 CFStringRef matchID
= (CFStringRef
)context1
;
588 CFStringRef
*name
= (CFStringRef
*)context3
;
590 if (current
== NULL
) {
591 // we have nothing to "add"
595 if (isMatchingPrefsID(current
, matchID
)) {
596 *name
= CFDictionaryGetValue(current
, kSCPropUserDefinedName
);
598 // for backwards compatibility, we also check for the name in the PPP entity
602 ppp
= CFDictionaryGetValue(current
, kSCEntNetPPP
);
603 if (isA_CFDictionary(ppp
)) {
604 *name
= CFDictionaryGetValue(ppp
, kSCPropUserDefinedName
);
608 *name
= isA_CFString(*name
);
614 return CFRetain(current
);
619 SCUserPreferencesCopyName(SCUserPreferencesRef userPreferences
)
621 CFStringRef name
= NULL
;
623 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
625 if (!isA_SCUserPreferences(userPreferences
)) {
626 _SCErrorSet(kSCStatusInvalidArgument
);
630 // find SCUserPreferences and copy name
631 ok
= processPreferences(userPrivate
->serviceID
,
633 (void *)userPrivate
->prefsID
,
647 static CFDictionaryRef
648 setNameCallout(CFStringRef serviceID
,
649 CFDictionaryRef current
,
654 CFStringRef matchID
= (CFStringRef
)context1
;
655 CFMutableDictionaryRef newDict
;
656 CFStringRef newName
= (CFStringRef
)context2
;
658 if (current
== NULL
) {
659 // we have nothing to "add"
663 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
665 if (isMatchingPrefsID(current
, matchID
)) {
666 CFDictionaryRef pppEntity
;
669 if (newName
!= NULL
) {
670 CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, newName
);
672 CFDictionaryRemoveValue(newDict
, kSCPropUserDefinedName
);
675 // for backwards compatibility, we also set the name in the PPP entity
676 pppEntity
= CFDictionaryGetValue(newDict
, kSCEntNetPPP
);
677 if (isA_CFDictionary(pppEntity
)) {
678 CFMutableDictionaryRef newPPPEntity
;
680 newPPPEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, pppEntity
);
681 if (newName
!= NULL
) {
682 CFDictionarySetValue(newPPPEntity
, kSCPropUserDefinedName
, newName
);
684 CFDictionaryRemoveValue(newPPPEntity
, kSCPropUserDefinedName
);
686 CFDictionarySetValue(newDict
, kSCEntNetPPP
, newPPPEntity
);
687 CFRelease(newPPPEntity
);
696 SCUserPreferencesSetName(SCUserPreferencesRef userPreferences
, CFStringRef newName
)
699 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
701 if (!isA_SCUserPreferences(userPreferences
)) {
702 _SCErrorSet(kSCStatusInvalidArgument
);
706 if ((newName
!= NULL
) && !isA_CFString(newName
)) {
707 _SCErrorSet(kSCStatusInvalidArgument
);
711 // find SCUserPreferences and set name
712 ok
= processPreferences(userPrivate
->serviceID
,
714 (void *)userPrivate
->prefsID
,
722 static CFDictionaryRef
723 copyInterfaceConfigurationCallout(CFStringRef serviceID
,
724 CFDictionaryRef current
,
729 CFDictionaryRef
*dict
= (CFDictionaryRef
*)context3
;
730 CFStringRef interfaceType
= (CFStringRef
)context2
;
731 CFStringRef matchID
= (CFStringRef
)context1
;
733 if (current
== NULL
) {
734 // we have nothing to "add"
738 if (isMatchingPrefsID(current
, matchID
)) {
739 *dict
= CFDictionaryGetValue(current
, interfaceType
);
740 *dict
= isA_CFDictionary(*dict
);
746 return CFRetain(current
);
751 SCUserPreferencesCopyInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
752 SCNetworkInterfaceRef interface
)
754 CFStringRef defaultType
;
755 CFDictionaryRef entity
= NULL
;
757 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
759 if (!isA_SCUserPreferences(userPreferences
)) {
760 _SCErrorSet(kSCStatusInvalidArgument
);
764 if (!isA_SCNetworkInterface(interface
)) {
765 _SCErrorSet(kSCStatusInvalidArgument
);
770 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
771 if (defaultType
== NULL
) {
772 _SCErrorSet(kSCStatusInvalidArgument
);
776 // find SCUserPreferences and copy interface entity
777 ok
= processPreferences(userPrivate
->serviceID
,
778 copyInterfaceConfigurationCallout
,
779 (void *)userPrivate
->prefsID
,
783 if (entity
!= NULL
) {
793 static CFDictionaryRef
794 setInterfaceConfigurationCallout(CFStringRef serviceID
,
795 CFDictionaryRef current
,
800 CFStringRef interfaceType
= (CFStringRef
)context2
;
801 CFStringRef matchID
= (CFStringRef
)context1
;
802 CFMutableDictionaryRef newDict
;
803 CFDictionaryRef newOptions
= (CFDictionaryRef
)context3
;
805 if (current
== NULL
) {
806 // we have nothing to "add"
810 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
812 if (isMatchingPrefsID(current
, matchID
)) {
813 if (newOptions
!= NULL
) {
814 CFDictionarySetValue(newDict
, interfaceType
, newOptions
);
816 // for backwards compatibility, we want to ensure that
817 // the name is set in both the top level and in the PPP
819 if (CFEqual(interfaceType
, kSCEntNetPPP
)) {
822 name
= CFDictionaryGetValue(newOptions
, kSCPropUserDefinedName
);
824 // if name was passed in newOptions, push up
825 CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, name
);
827 name
= CFDictionaryGetValue(newDict
, kSCPropUserDefinedName
);
829 CFMutableDictionaryRef newPPPEntity
;
831 // if name in parent, push into entity
832 newPPPEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, newOptions
);
833 CFDictionarySetValue(newPPPEntity
, kSCPropUserDefinedName
, name
);
834 CFDictionarySetValue(newDict
, interfaceType
, newPPPEntity
);
835 CFRelease(newPPPEntity
);
840 CFDictionaryRemoveValue(newDict
, interfaceType
);
849 SCUserPreferencesSetInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
850 SCNetworkInterfaceRef interface
,
851 CFDictionaryRef newOptions
)
853 CFStringRef defaultType
;
855 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
857 if (!isA_SCUserPreferences(userPreferences
)) {
858 _SCErrorSet(kSCStatusInvalidArgument
);
862 if (!isA_SCNetworkInterface(interface
)) {
863 _SCErrorSet(kSCStatusInvalidArgument
);
868 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
869 if (defaultType
== NULL
) {
870 _SCErrorSet(kSCStatusInvalidArgument
);
874 // set new interface entity for SCUserPreferences
875 ok
= processPreferences(userPrivate
->serviceID
,
876 setInterfaceConfigurationCallout
,
877 (void *)userPrivate
->prefsID
,
886 SCUserPreferencesCopyExtendedInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
887 SCNetworkInterfaceRef interface
,
888 CFStringRef extendedType
)
890 CFDictionaryRef entity
= NULL
;
892 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
894 if (!isA_SCUserPreferences(userPreferences
)) {
895 _SCErrorSet(kSCStatusInvalidArgument
);
899 if (!isA_SCNetworkInterface(interface
)) {
900 _SCErrorSet(kSCStatusInvalidArgument
);
904 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, FALSE
)) {
905 _SCErrorSet(kSCStatusInvalidArgument
);
909 // find SCUserPreferences and copy interface entity
910 ok
= processPreferences(userPrivate
->serviceID
,
911 copyInterfaceConfigurationCallout
,
912 (void *)userPrivate
->prefsID
,
913 (void *)extendedType
,
916 if (entity
!= NULL
) {
927 SCUserPreferencesSetExtendedInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
928 SCNetworkInterfaceRef interface
,
929 CFStringRef extendedType
,
930 CFDictionaryRef newOptions
)
933 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
935 if (!isA_SCUserPreferences(userPreferences
)) {
936 _SCErrorSet(kSCStatusInvalidArgument
);
940 if (!isA_SCNetworkInterface(interface
)) {
941 _SCErrorSet(kSCStatusInvalidArgument
);
945 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, FALSE
)) {
946 _SCErrorSet(kSCStatusInvalidArgument
);
950 // set new interface entity for SCUserPreferences
951 ok
= processPreferences(userPrivate
->serviceID
,
952 setInterfaceConfigurationCallout
,
953 (void *)userPrivate
->prefsID
,
954 (void *)extendedType
,
962 #pragma mark SCNetworkConnection + SCUserPreferences SPIs
965 static CFDictionaryRef
966 copyAllCallout(CFStringRef serviceID
,
967 CFDictionaryRef current
,
972 CFMutableArrayRef
*prefs
= (CFMutableArrayRef
*)context3
;
974 SCUserPreferencesPrivateRef userPrivate
;
976 if (current
== NULL
) {
977 // we have nothing to "add"
981 prefsID
= CFDictionaryGetValue(current
, USER_PREFERENCES_ID
);
982 if (!isA_CFString(prefsID
)) {
987 userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, prefsID
);
988 if (userPrivate
!= NULL
) {
989 if (*prefs
== NULL
) {
990 *prefs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
992 CFArrayAppendValue(*prefs
, (SCUserPreferencesRef
)userPrivate
);
993 CFRelease(userPrivate
);
998 return CFRetain(current
);
1002 CFArrayRef
/* of SCUserPreferencesRef's */
1003 SCNetworkConnectionCopyAllUserPreferences(SCNetworkConnectionRef connection
)
1006 CFMutableArrayRef prefs
= NULL
;
1007 CFStringRef serviceID
;
1010 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
1012 // collect SCUserPreferences
1013 ok
= processPreferences(serviceID
,
1019 if (prefs
!= NULL
) {
1025 CFRelease(serviceID
);
1030 static CFDictionaryRef
1031 copyCurrentCallout(CFStringRef serviceID
,
1032 CFDictionaryRef current
,
1037 CFBooleanRef isDefault
;
1038 CFStringRef prefsID
;
1039 SCUserPreferencesPrivateRef
*userPrivate
= (SCUserPreferencesPrivateRef
*)context3
;
1041 if (current
== NULL
) {
1042 // we have nothing to "add"
1046 prefsID
= CFDictionaryGetValue(current
, USER_PREFERENCES_ID
);
1047 if (!isA_CFString(prefsID
)) {
1052 isDefault
= CFDictionaryGetValue(current
, USER_PREFERENCES_DEFAULT
);
1053 if (!isA_CFBoolean(isDefault
) || !CFBooleanGetValue(isDefault
)) {
1054 // if not the default configuration
1058 *userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, prefsID
);
1062 return CFRetain(current
);
1066 SCUserPreferencesRef
1067 SCNetworkConnectionCopyCurrentUserPreferences(SCNetworkConnectionRef connection
)
1069 SCUserPreferencesRef current
= NULL
;
1071 CFStringRef serviceID
;
1074 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
1076 // collect SCUserPreferences
1077 ok
= processPreferences(serviceID
,
1083 if (current
!= NULL
) {
1089 CFRelease(serviceID
);
1094 static CFDictionaryRef
1095 createCallout(CFStringRef serviceID
,
1096 CFDictionaryRef current
,
1101 CFMutableDictionaryRef newDict
;
1102 CFStringRef newPrefsID
= (CFStringRef
)context1
;
1104 if (current
!= NULL
) {
1105 // don't change existing entries
1106 return CFRetain(current
);
1109 newDict
= CFDictionaryCreateMutable(NULL
,
1111 &kCFTypeDictionaryKeyCallBacks
,
1112 &kCFTypeDictionaryValueCallBacks
);
1113 CFDictionarySetValue(newDict
, USER_PREFERENCES_ID
, newPrefsID
);
1118 SCUserPreferencesRef
1119 SCNetworkConnectionCreateUserPreferences(SCNetworkConnectionRef connection
)
1121 CFStringRef newPrefsID
;
1122 CFStringRef serviceID
;
1123 SCUserPreferencesPrivateRef userPrivate
;
1127 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
1129 // allocate a new user preferences ID
1130 uuid
= CFUUIDCreate(NULL
);
1131 newPrefsID
= CFUUIDCreateString(NULL
, uuid
);
1134 userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, newPrefsID
);
1135 if (userPrivate
!= NULL
) {
1136 (void) processPreferences(serviceID
,
1143 CFRelease(newPrefsID
);
1144 CFRelease(serviceID
);
1145 return (SCUserPreferencesRef
)userPrivate
;
1150 update_PPP_entity(SCUserPreferencesRef userPreferences
, CFDictionaryRef
*userOptions
)
1152 CFStringRef encryption
;
1153 CFDictionaryRef entity
;
1154 CFStringRef keychainID
;
1156 entity
= CFDictionaryGetValue(*userOptions
, kSCEntNetPPP
);
1157 if (!isA_CFDictionary(entity
)) {
1161 encryption
= CFDictionaryGetValue(entity
, kSCPropNetPPPAuthPasswordEncryption
);
1162 if (encryption
== NULL
) {
1163 // provide default encryption method
1164 encryption
= kSCValNetPPPAuthPasswordEncryptionKeychain
;
1167 if (!isA_CFString(encryption
) ||
1168 !CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1172 keychainID
= CFDictionaryGetValue(entity
, kSCPropNetPPPAuthPassword
);
1173 if (isA_CFString(keychainID
)) {
1174 // if password is keychain ID
1175 } else if (isA_CFData(keychainID
) &&
1176 ((CFDataGetLength((CFDataRef
)keychainID
) % sizeof(UniChar
)) == 0)) {
1177 // if inline password
1180 keychainID
= SCUserPreferencesGetUniqueID(userPreferences
);
1183 if (_SCSecKeychainPasswordItemExists(NULL
, keychainID
)) {
1184 CFMutableDictionaryRef new_entity
;
1185 CFMutableDictionaryRef new_options
;
1187 // access PPP password from system keychain
1188 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1190 CFDictionarySetValue(new_entity
,
1191 kSCPropNetPPPAuthPassword
,
1193 CFDictionarySetValue(new_entity
,
1194 kSCPropNetPPPAuthPasswordEncryption
,
1195 kSCValNetPPPAuthPasswordEncryptionKeychain
);
1197 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1198 CFDictionarySetValue(new_options
, kSCEntNetPPP
, new_entity
);
1199 CFRelease(new_entity
);
1201 CFRelease(*userOptions
);
1202 *userOptions
= new_options
;
1210 update_IPSec_entity(SCUserPreferencesRef userPreferences
, CFDictionaryRef
*userOptions
)
1212 CFStringRef encryption
;
1213 CFDictionaryRef entity
;
1214 SecKeychainRef keychain
= NULL
;
1215 CFStringRef keychainID
;
1217 CFDataRef sharedSecret
;
1219 entity
= CFDictionaryGetValue(*userOptions
, kSCEntNetIPSec
);
1220 if (!isA_CFDictionary(entity
)) {
1224 method
= CFDictionaryGetValue(entity
, kSCPropNetIPSecAuthenticationMethod
);
1225 if (!isA_CFString(method
) ||
1226 !CFEqual(method
, kSCValNetIPSecAuthenticationMethodSharedSecret
)) {
1230 encryption
= CFDictionaryGetValue(entity
, kSCPropNetIPSecSharedSecretEncryption
);
1231 if (encryption
== NULL
) {
1232 // provide default encryption method
1233 encryption
= kSCValNetIPSecSharedSecretEncryptionKeychain
;
1236 if (!isA_CFString(encryption
) ||
1237 !CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1241 keychainID
= CFDictionaryGetValue(entity
, kSCPropNetIPSecSharedSecret
);
1242 if (isA_CFString(keychainID
)) {
1243 // if shared secret is keychain ID
1244 CFRetain(keychainID
);
1245 } else if (isA_CFData(keychainID
) &&
1246 ((CFDataGetLength((CFDataRef
)keychainID
) % sizeof(UniChar
)) == 0)) {
1247 // if inline shared secret
1250 CFStringRef unique_id
;
1252 unique_id
= SCUserPreferencesGetUniqueID(userPreferences
);
1253 keychainID
= (CFStringRef
)CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1254 CFStringAppend((CFMutableStringRef
)keychainID
, CFSTR(".SS"));
1257 sharedSecret
= _SCSecKeychainPasswordItemCopy(NULL
, keychainID
);
1258 if (sharedSecret
!= NULL
) {
1259 CFMutableDictionaryRef new_entity
;
1260 CFMutableDictionaryRef new_options
;
1261 CFStringRef password
;
1263 // pass SharedSecret from user keychain
1264 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1266 password
= CFStringCreateWithBytes(NULL
,
1267 CFDataGetBytePtr(sharedSecret
),
1268 CFDataGetLength(sharedSecret
),
1269 kCFStringEncodingUTF8
,
1271 CFRelease(sharedSecret
);
1272 CFDictionarySetValue(new_entity
,
1273 kSCPropNetIPSecSharedSecret
,
1275 CFRelease(password
);
1276 CFDictionaryRemoveValue(new_entity
,
1277 kSCPropNetIPSecSharedSecretEncryption
);
1279 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1280 CFDictionarySetValue(new_options
, kSCEntNetIPSec
, new_entity
);
1281 CFRelease(new_entity
);
1283 CFRelease(*userOptions
);
1284 *userOptions
= new_options
;
1288 keychain
= _SCSecKeychainCopySystemKeychain();
1289 if (keychain
== NULL
) {
1293 if (_SCSecKeychainPasswordItemExists(keychain
, keychainID
)) {
1294 CFMutableDictionaryRef new_entity
;
1295 CFMutableDictionaryRef new_options
;
1297 // access SharedSecret from system keychain
1298 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1300 CFDictionarySetValue(new_entity
,
1301 kSCPropNetIPSecSharedSecret
,
1303 CFDictionarySetValue(new_entity
,
1304 kSCPropNetIPSecSharedSecretEncryption
,
1305 kSCValNetIPSecSharedSecretEncryptionKeychain
);
1307 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1308 CFDictionarySetValue(new_options
, kSCEntNetIPSec
, new_entity
);
1309 CFRelease(new_entity
);
1311 CFRelease(*userOptions
);
1312 *userOptions
= new_options
;
1317 if (keychain
!= NULL
) CFRelease(keychain
);
1318 CFRelease(keychainID
);
1323 static CFDictionaryRef
1324 copyOptionsCallout(CFStringRef serviceID
,
1325 CFDictionaryRef current
,
1330 CFStringRef matchID
= (CFStringRef
)context1
;
1331 CFMutableDictionaryRef
*userOptions
= (CFMutableDictionaryRef
*)context3
;
1333 if (current
== NULL
) {
1334 // we have nothing to "add"
1338 if (isMatchingPrefsID(current
, matchID
)) {
1339 // if we match, return options dictionary
1340 if (*userOptions
!= NULL
) CFRelease(*userOptions
);
1341 *userOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
1342 CFDictionaryRemoveValue(*userOptions
, USER_PREFERENCES_ID
);
1343 CFDictionaryRemoveValue(*userOptions
, USER_PREFERENCES_DEFAULT
);
1346 return CFRetain(current
);
1351 SCNetworkConnectionStartWithUserPreferences(SCNetworkConnectionRef connection
,
1352 SCUserPreferencesRef userPreferences
,
1356 CFDictionaryRef userOptions
= NULL
;
1357 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
1359 if (!isA_SCUserPreferences(userPreferences
)) {
1360 _SCErrorSet(kSCStatusInvalidArgument
);
1364 (void) processPreferences(userPrivate
->serviceID
,
1366 (void *)userPrivate
->prefsID
,
1371 * For some legacy preferences, some of the user options
1372 * were missing yet handled by the APIs. Make sure that
1373 * everything still works!
1375 if (userOptions
!= NULL
) {
1376 update_PPP_entity (userPreferences
, &userOptions
);
1377 update_IPSec_entity(userPreferences
, &userOptions
);
1380 ok
= SCNetworkConnectionStart(connection
, userOptions
, linger
);
1382 if (userOptions
!= NULL
) {
1383 CFRelease(userOptions
);
1391 #pragma mark SCUserPreferences + SCNetworkInterface Password SPIs
1395 getUserPasswordID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1397 CFStringRef unique_id
= NULL
;
1399 if (config
!= NULL
) {
1400 CFStringRef encryption
;
1402 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
1403 if (isA_CFString(encryption
) &&
1404 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1405 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
1408 if (unique_id
== NULL
) {
1409 unique_id
= SCUserPreferencesGetUniqueID(userPreferences
);
1417 copyUserSharedSecretID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1419 CFMutableStringRef sharedSecret
= NULL
;
1421 if (config
!= NULL
) {
1422 CFStringRef encryption
;
1424 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
1425 if (isA_CFString(encryption
) &&
1426 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1427 sharedSecret
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
1428 if (sharedSecret
!= NULL
) {
1429 CFRetain(sharedSecret
);
1434 if (sharedSecret
== NULL
) {
1435 CFStringRef unique_id
;
1437 unique_id
= getUserPasswordID(config
, userPreferences
);
1438 sharedSecret
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1439 CFStringAppend(sharedSecret
, CFSTR(".SS"));
1442 return sharedSecret
;
1447 copyUserXAuthID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1449 CFMutableStringRef xauth_id
= NULL
;
1451 if (config
!= NULL
) {
1452 CFStringRef encryption
;
1454 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
1455 if (isA_CFString(encryption
) &&
1456 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
1457 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
1458 if (xauth_id
!= NULL
) {
1464 if (xauth_id
== NULL
) {
1465 CFStringRef unique_id
;
1467 unique_id
= getUserPasswordID(config
, userPreferences
);
1468 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1469 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
1477 checkUserPreferencesPassword(SCUserPreferencesRef userPreferences
,
1478 SCNetworkInterfaceRef interface
,
1479 SCNetworkInterfacePasswordType passwordType
)
1481 if (!isA_SCUserPreferences(userPreferences
)) {
1482 _SCErrorSet(kSCStatusInvalidArgument
);
1486 if (!isA_SCNetworkInterface(interface
)) {
1487 _SCErrorSet(kSCStatusInvalidArgument
);
1491 switch (passwordType
) {
1492 case kSCNetworkInterfacePasswordTypePPP
: {
1493 CFStringRef interfaceType
;
1495 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1496 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1497 _SCErrorSet(kSCStatusInvalidArgument
);
1503 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1504 CFStringRef interfaceType
;
1506 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1507 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1508 _SCErrorSet(kSCStatusInvalidArgument
);
1512 interface
= SCNetworkInterfaceGetInterface(interface
);
1513 if (interface
== NULL
) {
1514 _SCErrorSet(kSCStatusInvalidArgument
);
1518 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1519 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
1520 _SCErrorSet(kSCStatusInvalidArgument
);
1526 case kSCNetworkInterfacePasswordTypeEAPOL
: {
1527 _SCErrorSet(kSCStatusInvalidArgument
);
1531 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1532 CFStringRef interfaceType
;
1534 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1535 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
1536 _SCErrorSet(kSCStatusInvalidArgument
);
1542 case kSCNetworkInterfacePasswordTypeVPN
: {
1543 CFStringRef interfaceType
;
1545 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1546 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
1547 _SCErrorSet(kSCStatusInvalidArgument
);
1562 SCUserPreferencesCheckInterfacePassword(SCUserPreferencesRef userPreferences
,
1563 SCNetworkInterfaceRef interface
,
1564 SCNetworkInterfacePasswordType passwordType
)
1566 Boolean exists
= FALSE
;
1568 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1572 switch (passwordType
) {
1573 case kSCNetworkInterfacePasswordTypePPP
: {
1574 CFDictionaryRef config
;
1575 CFStringRef unique_id
;
1577 // get configuration
1578 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1580 // get userPreferences ID
1581 unique_id
= getUserPasswordID(config
, userPreferences
);
1584 exists
= __extract_password(NULL
,
1586 kSCPropNetPPPAuthPassword
,
1587 kSCPropNetPPPAuthPasswordEncryption
,
1588 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1592 if (config
!= NULL
) CFRelease(config
);
1596 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1597 CFDictionaryRef config
;
1598 CFStringRef shared_id
;
1600 // get configuration
1601 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1605 // get sharedSecret ID
1606 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1609 exists
= __extract_password(NULL
,
1611 kSCPropNetIPSecSharedSecret
,
1612 kSCPropNetIPSecSharedSecretEncryption
,
1613 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1617 if (config
!= NULL
) CFRelease(config
);
1618 CFRelease(shared_id
);
1622 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1623 CFDictionaryRef config
;
1624 CFStringRef xauth_id
;
1626 // get configuration
1627 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1630 xauth_id
= copyUserXAuthID(config
, userPreferences
);
1633 exists
= __extract_password(NULL
,
1635 kSCPropNetIPSecXAuthPassword
,
1636 kSCPropNetIPSecXAuthPasswordEncryption
,
1637 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
1641 if (config
!= NULL
) CFRelease(config
);
1642 CFRelease(xauth_id
);
1646 case kSCNetworkInterfacePasswordTypeVPN
: {
1647 CFDictionaryRef config
;
1648 CFStringRef unique_id
;
1650 // get configuration
1651 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1653 // get userPreferences ID
1654 unique_id
= getUserPasswordID(config
, userPreferences
);
1657 exists
= __extract_password(NULL
,
1659 kSCPropNetVPNAuthPassword
,
1660 kSCPropNetVPNAuthPasswordEncryption
,
1661 kSCValNetVPNAuthPasswordEncryptionKeychain
,
1665 if (config
!= NULL
) CFRelease(config
);
1670 _SCErrorSet(kSCStatusInvalidArgument
);
1679 SCUserPreferencesCopyInterfacePassword(SCUserPreferencesRef userPreferences
,
1680 SCNetworkInterfaceRef interface
,
1681 SCNetworkInterfacePasswordType passwordType
)
1683 CFDataRef password
= NULL
;
1685 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1689 switch (passwordType
) {
1690 case kSCNetworkInterfacePasswordTypePPP
: {
1691 CFDictionaryRef config
;
1692 CFStringRef unique_id
;
1694 // get configuration
1695 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1697 // get userPreferences ID
1698 unique_id
= getUserPasswordID(config
, userPreferences
);
1701 (void) __extract_password(NULL
,
1703 kSCPropNetPPPAuthPassword
,
1704 kSCPropNetPPPAuthPasswordEncryption
,
1705 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1709 if (config
!= NULL
) CFRelease(config
);
1713 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1714 CFDictionaryRef config
;
1715 CFStringRef shared_id
;
1717 // get configuration
1718 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1722 // get sharedSecret ID
1723 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1726 (void) __extract_password(NULL
,
1728 kSCPropNetIPSecSharedSecret
,
1729 kSCPropNetIPSecSharedSecretEncryption
,
1730 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1734 if (config
!= NULL
) CFRelease(config
);
1735 CFRelease(shared_id
);
1739 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1740 CFDictionaryRef config
;
1741 CFStringRef xauth_id
;
1743 // get configuration
1744 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1747 xauth_id
= copyUserXAuthID(config
, userPreferences
);
1750 (void) __extract_password(NULL
,
1752 kSCPropNetIPSecXAuthPassword
,
1753 kSCPropNetIPSecXAuthPasswordEncryption
,
1754 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
1758 if (config
!= NULL
) CFRelease(config
);
1759 CFRelease(xauth_id
);
1763 case kSCNetworkInterfacePasswordTypeVPN
: {
1764 CFDictionaryRef config
;
1765 CFStringRef unique_id
;
1767 // get configuration
1768 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1770 // get userPreferences ID
1771 unique_id
= getUserPasswordID(config
, userPreferences
);
1774 (void) __extract_password(NULL
,
1776 kSCPropNetVPNAuthPassword
,
1777 kSCPropNetVPNAuthPasswordEncryption
,
1778 kSCValNetVPNAuthPasswordEncryptionKeychain
,
1782 if (config
!= NULL
) CFRelease(config
);
1787 _SCErrorSet(kSCStatusInvalidArgument
);
1796 SCUserPreferencesRemoveInterfacePassword(SCUserPreferencesRef userPreferences
,
1797 SCNetworkInterfaceRef interface
,
1798 SCNetworkInterfacePasswordType passwordType
)
1802 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1806 switch (passwordType
) {
1807 case kSCNetworkInterfacePasswordTypePPP
: {
1808 CFDictionaryRef config
;
1809 CFDictionaryRef newConfig
= NULL
;
1810 CFStringRef unique_id
;
1812 // get configuration
1813 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1815 // get userPreferences ID
1816 unique_id
= getUserPasswordID(config
, userPreferences
);
1819 ok
= __remove_password(NULL
,
1821 kSCPropNetPPPAuthPassword
,
1822 kSCPropNetPPPAuthPasswordEncryption
,
1823 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1827 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1828 if (newConfig
!= NULL
) CFRelease(newConfig
);
1831 if (config
!= NULL
) CFRelease(config
);
1835 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1836 CFDictionaryRef config
;
1837 CFDictionaryRef newConfig
= NULL
;
1838 CFStringRef shared_id
;
1840 // get configuration
1841 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1845 // get sharedSecret ID
1846 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1849 ok
= __remove_password(NULL
,
1851 kSCPropNetIPSecSharedSecret
,
1852 kSCPropNetIPSecSharedSecretEncryption
,
1853 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1857 ok
= SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences
,
1861 if (newConfig
!= NULL
) CFRelease(newConfig
);
1864 if (config
!= NULL
) CFRelease(config
);
1865 CFRelease(shared_id
);
1869 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1870 CFDictionaryRef config
;
1871 CFDictionaryRef newConfig
= NULL
;
1872 CFStringRef xauth_id
;
1874 // get configuration
1875 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1878 xauth_id
= copyUserXAuthID(config
, userPreferences
);
1881 ok
= __remove_password(NULL
,
1883 kSCPropNetIPSecXAuthPassword
,
1884 kSCPropNetIPSecXAuthPasswordEncryption
,
1885 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
1889 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1890 if (newConfig
!= NULL
) CFRelease(newConfig
);
1893 if (config
!= NULL
) CFRelease(config
);
1894 CFRelease(xauth_id
);
1898 case kSCNetworkInterfacePasswordTypeVPN
: {
1899 CFDictionaryRef config
;
1900 CFDictionaryRef newConfig
= NULL
;
1901 CFStringRef unique_id
;
1903 // get configuration
1904 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1906 // get userPreferences ID
1907 unique_id
= getUserPasswordID(config
, userPreferences
);
1910 ok
= __remove_password(NULL
,
1912 kSCPropNetVPNAuthPassword
,
1913 kSCPropNetVPNAuthPasswordEncryption
,
1914 kSCValNetVPNAuthPasswordEncryptionKeychain
,
1918 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1919 if (newConfig
!= NULL
) CFRelease(newConfig
);
1922 if (config
!= NULL
) CFRelease(config
);
1927 _SCErrorSet(kSCStatusInvalidArgument
);
1936 SCUserPreferencesSetInterfacePassword(SCUserPreferencesRef userPreferences
,
1937 SCNetworkInterfaceRef interface
,
1938 SCNetworkInterfacePasswordType passwordType
,
1940 CFDictionaryRef options
)
1942 CFStringRef account
= NULL
;
1944 CFDictionaryRef config
;
1945 CFStringRef description
= NULL
;
1946 CFStringRef label
= NULL
;
1949 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1953 bundle
= _SC_CFBundleGet();
1955 switch (passwordType
) {
1956 case kSCNetworkInterfacePasswordTypePPP
: {
1957 CFStringRef unique_id
;
1959 // get configuration
1960 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1962 // get userPreferences ID
1963 unique_id
= getUserPasswordID(config
, userPreferences
);
1965 // User prefs auth name --> keychain "Account"
1966 if (config
!= NULL
) {
1967 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
1970 // User prefs "name" --> keychain "Name"
1971 label
= SCUserPreferencesCopyName(userPreferences
);
1973 // "PPP Password" --> keychain "Kind"
1974 if (bundle
!= NULL
) {
1975 description
= CFBundleCopyLocalizedString(bundle
,
1976 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
1977 CFSTR("PPP Password"),
1982 ok
= _SCSecKeychainPasswordItemSet(NULL
,
1984 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
1985 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
1990 CFMutableDictionaryRef newConfig
;
1992 if (config
!= NULL
) {
1993 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
1995 newConfig
= CFDictionaryCreateMutable(NULL
,
1997 &kCFTypeDictionaryKeyCallBacks
,
1998 &kCFTypeDictionaryValueCallBacks
);
2000 CFDictionarySetValue(newConfig
,
2001 kSCPropNetPPPAuthPassword
,
2003 CFDictionarySetValue(newConfig
,
2004 kSCPropNetPPPAuthPasswordEncryption
,
2005 kSCValNetPPPAuthPasswordEncryptionKeychain
);
2006 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
2007 CFRelease(newConfig
);
2010 if (config
!= NULL
) CFRelease(config
);
2011 if (description
!= NULL
) CFRelease(description
);
2012 if (label
!= NULL
) CFRelease(label
);
2016 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
2017 CFStringRef shared_id
;
2019 // get configuration
2020 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
2024 // get sharedSecret ID
2025 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
2027 // User prefs "name" --> keychain "Name"
2028 label
= SCUserPreferencesCopyName(userPreferences
);
2030 // "IPSec Shared Secret" --> keychain "Kind"
2031 if (bundle
!= NULL
) {
2032 description
= CFBundleCopyLocalizedString(bundle
,
2033 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
2034 CFSTR("IPSec Shared Secret"),
2039 ok
= _SCSecKeychainPasswordItemSet(NULL
,
2041 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
2042 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
2047 CFMutableDictionaryRef newConfig
= NULL
;
2049 if (config
!= NULL
) {
2050 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
2052 newConfig
= CFDictionaryCreateMutable(NULL
,
2054 &kCFTypeDictionaryKeyCallBacks
,
2055 &kCFTypeDictionaryValueCallBacks
);
2057 CFDictionarySetValue(newConfig
,
2058 kSCPropNetIPSecSharedSecret
,
2060 CFDictionarySetValue(newConfig
,
2061 kSCPropNetIPSecSharedSecretEncryption
,
2062 kSCValNetIPSecSharedSecretEncryptionKeychain
);
2063 ok
= SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences
,
2067 CFRelease(newConfig
);
2070 if (config
!= NULL
) CFRelease(config
);
2071 if (description
!= NULL
) CFRelease(description
);
2072 if (label
!= NULL
) CFRelease(label
);
2073 CFRelease(shared_id
);
2077 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
2078 CFStringRef xauth_id
;
2080 // get configuration
2081 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
2084 xauth_id
= copyUserXAuthID(config
, userPreferences
);
2086 // User prefs XAuth name --> keychain "Account"
2087 if (config
!= NULL
) {
2088 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
2091 // User prefs "name" --> keychain "Name"
2092 label
= SCUserPreferencesCopyName(userPreferences
);
2094 // "IPSec XAuth Password" --> keychain "Kind"
2095 if (bundle
!= NULL
) {
2096 description
= CFBundleCopyLocalizedString(bundle
,
2097 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
2098 CFSTR("IPSec XAuth Password"),
2103 ok
= _SCSecKeychainPasswordItemSet(NULL
,
2105 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
2106 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
2111 CFMutableDictionaryRef newConfig
;
2113 if (config
!= NULL
) {
2114 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
2116 newConfig
= CFDictionaryCreateMutable(NULL
,
2118 &kCFTypeDictionaryKeyCallBacks
,
2119 &kCFTypeDictionaryValueCallBacks
);
2121 CFDictionarySetValue(newConfig
,
2122 kSCPropNetIPSecXAuthPassword
,
2124 CFDictionarySetValue(newConfig
,
2125 kSCPropNetIPSecXAuthPasswordEncryption
,
2126 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
2127 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
2128 CFRelease(newConfig
);
2131 if (config
!= NULL
) CFRelease(config
);
2132 if (description
!= NULL
) CFRelease(description
);
2133 if (label
!= NULL
) CFRelease(label
);
2134 CFRelease(xauth_id
);
2138 case kSCNetworkInterfacePasswordTypeVPN
: {
2139 CFStringRef unique_id
;
2141 // get configuration
2142 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
2144 // get userPreferences ID
2145 unique_id
= getUserPasswordID(config
, userPreferences
);
2147 // User prefs auth name --> keychain "Account"
2148 if (config
!= NULL
) {
2149 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
2152 // User prefs "name" --> keychain "Name"
2153 label
= SCUserPreferencesCopyName(userPreferences
);
2155 // "VPN Password" --> keychain "Kind"
2156 if (bundle
!= NULL
) {
2157 description
= CFBundleCopyLocalizedString(bundle
,
2158 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
2159 CFSTR("VPN Password"),
2164 ok
= _SCSecKeychainPasswordItemSet(NULL
,
2166 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
2167 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
2172 CFMutableDictionaryRef newConfig
;
2174 if (config
!= NULL
) {
2175 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
2177 newConfig
= CFDictionaryCreateMutable(NULL
,
2179 &kCFTypeDictionaryKeyCallBacks
,
2180 &kCFTypeDictionaryValueCallBacks
);
2182 CFDictionarySetValue(newConfig
,
2183 kSCPropNetVPNAuthPassword
,
2185 CFDictionarySetValue(newConfig
,
2186 kSCPropNetVPNAuthPasswordEncryption
,
2187 kSCValNetVPNAuthPasswordEncryptionKeychain
);
2188 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
2189 CFRelease(newConfig
);
2192 if (config
!= NULL
) CFRelease(config
);
2193 if (description
!= NULL
) CFRelease(description
);
2194 if (label
!= NULL
) CFRelease(label
);
2199 _SCErrorSet(kSCStatusInvalidArgument
);