2 * Copyright (c) 2006-2009 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
);
204 if (!isA_CFBoolean(bVal
) || !CFBooleanGetValue(bVal
)) {
205 // if debugging not enabled
210 // if debugging not enabled
214 (void)gettimeofday(&tv_now
, NULL
);
215 (void)localtime_r(&tv_now
.tv_sec
, &tm_now
);
217 str
= CFStringCreateWithFormat(NULL
, NULL
,
218 CFSTR("/var/tmp/com.apple.networkConnect-%@-%4d%02d%02d.%02d%02d%02d.%03d"),
220 tm_now
.tm_year
+ 1900,
226 tv_now
.tv_usec
/ 1000);
227 _SC_cfstring_to_cstring(str
, dir
, sizeof(dir
), kCFStringEncodingUTF8
);
230 SCLog(TRUE
, LOG_ERR
, CFSTR("CFPreferences being updated, old/new in \"%s\""), dir
);
232 if (mkdir(dir
, 0755) == -1) {
233 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange mkdir() failed, error = %s"), SCErrorString(errno
));
237 trace
= _SC_copyBacktrace();
243 strlcpy(path
, dir
, sizeof(path
));
244 strlcat(path
, "/backtrace", sizeof(path
));
245 fd
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
247 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange fopen() failed, error = %s"), SCErrorString(errno
));
252 SCPrint(TRUE
, f
, CFSTR("%@"), trace
);
257 oldPreferences
= CFPreferencesCopyAppValue(serviceID
, USER_PREFERENCES_APPLICATION_ID
);
258 if (oldPreferences
!= NULL
) {
263 strlcpy(path
, dir
, sizeof(path
));
264 strlcat(path
, "/old", sizeof(path
));
265 fd
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
267 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange fopen() failed, error = %s"), SCErrorString(errno
));
268 CFRelease(oldPreferences
);
271 data
= CFPropertyListCreateXMLData(NULL
, oldPreferences
);
273 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange CFPropertyListCreateXMLData() failed"));
275 CFRelease(oldPreferences
);
278 (void) write(fd
, CFDataGetBytePtr(data
), CFDataGetLength(data
));
281 CFRelease(oldPreferences
);
284 if (newPreferences
!= NULL
) {
289 strlcpy(path
, dir
, sizeof(path
));
290 strlcat(path
, "/new", sizeof(path
));
291 fd
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
293 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange fopen() failed, error = %s"), SCErrorString(errno
));
296 data
= CFPropertyListCreateXMLData(NULL
, newPreferences
);
298 SCLog(TRUE
, LOG_ERR
, CFSTR("logCFPreferencesChange CFPropertyListCreateXMLData() failed"));
302 (void) write(fd
, CFDataGetBytePtr(data
), CFDataGetLength(data
));
309 #endif // LOG_CFPREFERENCES_CHANGES
313 copyCFPreferencesForServiceID(CFStringRef serviceID
)
317 // fetch "Managed" or "ByHost" user preferences
318 (void) CFPreferencesAppSynchronize(USER_PREFERENCES_APPLICATION_ID
);
319 prefs
= CFPreferencesCopyAppValue(serviceID
,
320 USER_PREFERENCES_APPLICATION_ID
);
322 if ((prefs
!= NULL
) && !isA_CFArray(prefs
)) {
332 setCFPreferencesForServiceID(CFStringRef serviceID
, CFArrayRef newPreferences
)
336 if (CFPreferencesAppValueIsForced(serviceID
, USER_PREFERENCES_APPLICATION_ID
)) {
340 #ifdef LOG_CFPREFERENCES_CHANGES
341 logCFPreferencesChange(serviceID
, newPreferences
);
342 #endif // LOG_CFPREFERENCES_CHANGES
344 CFPreferencesSetValue(serviceID
,
346 USER_PREFERENCES_APPLICATION_ID
,
347 kCFPreferencesCurrentUser
,
348 kCFPreferencesCurrentHost
);
349 ok
= CFPreferencesSynchronize(USER_PREFERENCES_APPLICATION_ID
,
350 kCFPreferencesCurrentUser
,
351 kCFPreferencesCurrentHost
);
353 (void) notify_post(USER_PREFERENCES_NOTIFICATION
);
360 addPreference(CFMutableArrayRef
*newPrefs
, CFDictionaryRef newDict
)
362 if (*newPrefs
== NULL
) {
363 *newPrefs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
365 CFArrayAppendValue(*newPrefs
, newDict
);
371 typedef CFDictionaryRef (*processPreferencesCallout
) (CFStringRef serviceID
,
372 CFDictionaryRef current
,
379 processPreferences(CFStringRef serviceID
,
380 processPreferencesCallout callout
,
385 Boolean changed
= FALSE
;
388 CFDictionaryRef newDict
= NULL
;
389 CFMutableArrayRef newPrefs
= NULL
;
393 prefs
= copyCFPreferencesForServiceID(serviceID
);
394 n
= (prefs
!= NULL
) ? CFArrayGetCount(prefs
) : 0;
395 for (i
= 0; i
< n
; i
++) {
396 CFDictionaryRef dict
;
398 dict
= CFArrayGetValueAtIndex(prefs
, i
);
399 if (isA_CFDictionary(dict
)) {
400 newDict
= (*callout
)(serviceID
, dict
, context1
, context2
, context3
);
401 if (newDict
== NULL
) {
402 // if entry to be removed
407 // if not a CFDictionary, leave as-is
408 newDict
= CFRetain(dict
);
411 if (!CFEqual(dict
, newDict
)) {
415 addPreference(&newPrefs
, newDict
);
418 if (prefs
!= NULL
) CFRelease(prefs
);
420 newDict
= (*callout
)(serviceID
, NULL
, context1
, context2
, context3
);
421 if (newDict
!= NULL
) {
424 addPreference(&newPrefs
, newDict
);
429 ok
= setCFPreferencesForServiceID(serviceID
, newPrefs
);
431 if (newPrefs
!= NULL
) CFRelease(newPrefs
);
437 static __inline__ Boolean
438 isMatchingPrefsID(CFDictionaryRef dict
, CFStringRef matchID
)
442 prefsID
= CFDictionaryGetValue(dict
, USER_PREFERENCES_ID
);
443 if (isA_CFString(prefsID
)) {
444 if (CFEqual(prefsID
, matchID
)) {
454 SCUserPreferencesGetTypeID(void)
456 pthread_once(&initialized
, __SCUserPreferencesInitialize
); /* initialize runtime */
457 return __kSCUserPreferencesTypeID
;
462 SCUserPreferencesGetUniqueID(SCUserPreferencesRef userPreferences
)
464 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
466 if (!isA_SCUserPreferences(userPreferences
)) {
467 _SCErrorSet(kSCStatusInvalidArgument
);
471 return userPrivate
->prefsID
;
476 SCUserPreferencesIsForced(SCUserPreferencesRef userPreferences
)
478 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
480 if (!isA_SCUserPreferences(userPreferences
)) {
481 _SCErrorSet(kSCStatusInvalidArgument
);
485 return CFPreferencesAppValueIsForced(userPrivate
->serviceID
, USER_PREFERENCES_APPLICATION_ID
);
489 static CFDictionaryRef
490 removeCallout(CFStringRef serviceID
,
491 CFDictionaryRef current
,
496 CFStringRef matchID
= (CFStringRef
)context1
;
498 if (current
== NULL
) {
499 // we have nothing to "add"
503 if (isMatchingPrefsID(current
, matchID
)) {
504 // if we match, don't add (i.e. remove)
508 return CFRetain(current
);
513 SCUserPreferencesRemove(SCUserPreferencesRef userPreferences
)
515 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
517 if (!isA_SCUserPreferences(userPreferences
)) {
518 _SCErrorSet(kSCStatusInvalidArgument
);
522 return processPreferences(userPrivate
->serviceID
,
524 (void *)userPrivate
->prefsID
,
530 static CFDictionaryRef
531 setCurrentCallout(CFStringRef serviceID
,
532 CFDictionaryRef current
,
537 CFStringRef matchID
= (CFStringRef
)context1
;
538 CFMutableDictionaryRef newDict
;
540 if (current
== NULL
) {
541 // we have nothing to "add"
545 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
547 // remove "default" flag
548 CFDictionaryRemoveValue(newDict
, USER_PREFERENCES_DEFAULT
);
550 if (isMatchingPrefsID(current
, matchID
)) {
551 // if we match, set "default" flag
552 CFDictionarySetValue(newDict
, USER_PREFERENCES_DEFAULT
, kCFBooleanTrue
);
560 SCUserPreferencesSetCurrent(SCUserPreferencesRef userPreferences
)
562 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
564 if (!isA_SCUserPreferences(userPreferences
)) {
565 _SCErrorSet(kSCStatusInvalidArgument
);
569 return processPreferences(userPrivate
->serviceID
,
571 (void *)userPrivate
->prefsID
,
577 static CFDictionaryRef
578 copyNameCallout(CFStringRef serviceID
,
579 CFDictionaryRef current
,
584 CFStringRef matchID
= (CFStringRef
)context1
;
585 CFStringRef
*name
= (CFStringRef
*)context3
;
587 if (current
== NULL
) {
588 // we have nothing to "add"
592 if (isMatchingPrefsID(current
, matchID
)) {
593 *name
= CFDictionaryGetValue(current
, kSCPropUserDefinedName
);
595 // for backwards compatibility, we also check for the name in the PPP entity
599 ppp
= CFDictionaryGetValue(current
, kSCEntNetPPP
);
600 if (isA_CFDictionary(ppp
)) {
601 *name
= CFDictionaryGetValue(ppp
, kSCPropUserDefinedName
);
605 *name
= isA_CFString(*name
);
611 return CFRetain(current
);
616 SCUserPreferencesCopyName(SCUserPreferencesRef userPreferences
)
618 CFStringRef name
= NULL
;
620 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
622 if (!isA_SCUserPreferences(userPreferences
)) {
623 _SCErrorSet(kSCStatusInvalidArgument
);
627 // find SCUserPreferences and copy name
628 ok
= processPreferences(userPrivate
->serviceID
,
630 (void *)userPrivate
->prefsID
,
644 static CFDictionaryRef
645 setNameCallout(CFStringRef serviceID
,
646 CFDictionaryRef current
,
651 CFStringRef matchID
= (CFStringRef
)context1
;
652 CFMutableDictionaryRef newDict
;
653 CFStringRef newName
= (CFStringRef
)context2
;
655 if (current
== NULL
) {
656 // we have nothing to "add"
660 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
662 if (isMatchingPrefsID(current
, matchID
)) {
663 CFDictionaryRef pppEntity
;
666 if (newName
!= NULL
) {
667 CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, newName
);
669 CFDictionaryRemoveValue(newDict
, kSCPropUserDefinedName
);
672 // for backwards compatibility, we also set the name in the PPP entity
673 pppEntity
= CFDictionaryGetValue(newDict
, kSCEntNetPPP
);
674 if (isA_CFDictionary(pppEntity
)) {
675 CFMutableDictionaryRef newPPPEntity
;
677 newPPPEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, pppEntity
);
678 if (newName
!= NULL
) {
679 CFDictionarySetValue(newPPPEntity
, kSCPropUserDefinedName
, newName
);
681 CFDictionaryRemoveValue(newPPPEntity
, kSCPropUserDefinedName
);
683 CFDictionarySetValue(newDict
, kSCEntNetPPP
, newPPPEntity
);
684 CFRelease(newPPPEntity
);
693 SCUserPreferencesSetName(SCUserPreferencesRef userPreferences
, CFStringRef newName
)
696 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
698 if (!isA_SCUserPreferences(userPreferences
)) {
699 _SCErrorSet(kSCStatusInvalidArgument
);
703 if ((newName
!= NULL
) && !isA_CFString(newName
)) {
704 _SCErrorSet(kSCStatusInvalidArgument
);
708 // find SCUserPreferences and set name
709 ok
= processPreferences(userPrivate
->serviceID
,
711 (void *)userPrivate
->prefsID
,
719 static CFDictionaryRef
720 copyInterfaceConfigurationCallout(CFStringRef serviceID
,
721 CFDictionaryRef current
,
726 CFDictionaryRef
*dict
= (CFDictionaryRef
*)context3
;
727 CFStringRef interfaceType
= (CFStringRef
)context2
;
728 CFStringRef matchID
= (CFStringRef
)context1
;
730 if (current
== NULL
) {
731 // we have nothing to "add"
735 if (isMatchingPrefsID(current
, matchID
)) {
736 *dict
= CFDictionaryGetValue(current
, interfaceType
);
737 *dict
= isA_CFDictionary(*dict
);
743 return CFRetain(current
);
748 SCUserPreferencesCopyInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
749 SCNetworkInterfaceRef interface
)
751 CFStringRef defaultType
;
752 CFDictionaryRef entity
= NULL
;
754 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
756 if (!isA_SCUserPreferences(userPreferences
)) {
757 _SCErrorSet(kSCStatusInvalidArgument
);
761 if (!isA_SCNetworkInterface(interface
)) {
762 _SCErrorSet(kSCStatusInvalidArgument
);
767 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
768 if (defaultType
== NULL
) {
769 _SCErrorSet(kSCStatusInvalidArgument
);
773 // find SCUserPreferences and copy interface entity
774 ok
= processPreferences(userPrivate
->serviceID
,
775 copyInterfaceConfigurationCallout
,
776 (void *)userPrivate
->prefsID
,
780 if (entity
!= NULL
) {
790 static CFDictionaryRef
791 setInterfaceConfigurationCallout(CFStringRef serviceID
,
792 CFDictionaryRef current
,
797 CFStringRef interfaceType
= (CFStringRef
)context2
;
798 CFStringRef matchID
= (CFStringRef
)context1
;
799 CFMutableDictionaryRef newDict
;
800 CFDictionaryRef newOptions
= (CFDictionaryRef
)context3
;
802 if (current
== NULL
) {
803 // we have nothing to "add"
807 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
809 if (isMatchingPrefsID(current
, matchID
)) {
810 if (newOptions
!= NULL
) {
811 CFDictionarySetValue(newDict
, interfaceType
, newOptions
);
813 // for backwards compatibility, we want to ensure that
814 // the name is set in both the top level and in the PPP
816 if (CFEqual(interfaceType
, kSCEntNetPPP
)) {
819 name
= CFDictionaryGetValue(newOptions
, kSCPropUserDefinedName
);
821 // if name was passed in newOptions, push up
822 CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, name
);
824 name
= CFDictionaryGetValue(newDict
, kSCPropUserDefinedName
);
826 CFMutableDictionaryRef newPPPEntity
;
828 // if name in parent, push into entity
829 newPPPEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, newOptions
);
830 CFDictionarySetValue(newPPPEntity
, kSCPropUserDefinedName
, name
);
831 CFDictionarySetValue(newDict
, interfaceType
, newPPPEntity
);
832 CFRelease(newPPPEntity
);
837 CFDictionaryRemoveValue(newDict
, interfaceType
);
846 SCUserPreferencesSetInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
847 SCNetworkInterfaceRef interface
,
848 CFDictionaryRef newOptions
)
850 CFStringRef defaultType
;
852 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
854 if (!isA_SCUserPreferences(userPreferences
)) {
855 _SCErrorSet(kSCStatusInvalidArgument
);
859 if (!isA_SCNetworkInterface(interface
)) {
860 _SCErrorSet(kSCStatusInvalidArgument
);
865 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
866 if (defaultType
== NULL
) {
867 _SCErrorSet(kSCStatusInvalidArgument
);
871 // set new interface entity for SCUserPreferences
872 ok
= processPreferences(userPrivate
->serviceID
,
873 setInterfaceConfigurationCallout
,
874 (void *)userPrivate
->prefsID
,
883 SCUserPreferencesCopyExtendedInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
884 SCNetworkInterfaceRef interface
,
885 CFStringRef extendedType
)
887 CFDictionaryRef entity
= NULL
;
889 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
891 if (!isA_SCUserPreferences(userPreferences
)) {
892 _SCErrorSet(kSCStatusInvalidArgument
);
896 if (!isA_SCNetworkInterface(interface
)) {
897 _SCErrorSet(kSCStatusInvalidArgument
);
901 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, FALSE
)) {
902 _SCErrorSet(kSCStatusInvalidArgument
);
906 // find SCUserPreferences and copy interface entity
907 ok
= processPreferences(userPrivate
->serviceID
,
908 copyInterfaceConfigurationCallout
,
909 (void *)userPrivate
->prefsID
,
910 (void *)extendedType
,
913 if (entity
!= NULL
) {
924 SCUserPreferencesSetExtendedInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
925 SCNetworkInterfaceRef interface
,
926 CFStringRef extendedType
,
927 CFDictionaryRef newOptions
)
930 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
932 if (!isA_SCUserPreferences(userPreferences
)) {
933 _SCErrorSet(kSCStatusInvalidArgument
);
937 if (!isA_SCNetworkInterface(interface
)) {
938 _SCErrorSet(kSCStatusInvalidArgument
);
942 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, FALSE
)) {
943 _SCErrorSet(kSCStatusInvalidArgument
);
947 // set new interface entity for SCUserPreferences
948 ok
= processPreferences(userPrivate
->serviceID
,
949 setInterfaceConfigurationCallout
,
950 (void *)userPrivate
->prefsID
,
951 (void *)extendedType
,
959 #pragma mark SCNetworkConnection + SCUserPreferences SPIs
962 static CFDictionaryRef
963 copyAllCallout(CFStringRef serviceID
,
964 CFDictionaryRef current
,
969 CFMutableArrayRef
*prefs
= (CFMutableArrayRef
*)context3
;
971 SCUserPreferencesPrivateRef userPrivate
;
973 if (current
== NULL
) {
974 // we have nothing to "add"
978 prefsID
= CFDictionaryGetValue(current
, USER_PREFERENCES_ID
);
979 if (!isA_CFString(prefsID
)) {
984 userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, prefsID
);
985 if (userPrivate
!= NULL
) {
986 if (*prefs
== NULL
) {
987 *prefs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
989 CFArrayAppendValue(*prefs
, (SCUserPreferencesRef
)userPrivate
);
990 CFRelease(userPrivate
);
995 return CFRetain(current
);
999 CFArrayRef
/* of SCUserPreferencesRef's */
1000 SCNetworkConnectionCopyAllUserPreferences(SCNetworkConnectionRef connection
)
1003 CFMutableArrayRef prefs
= NULL
;
1004 CFStringRef serviceID
;
1007 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
1009 // collect SCUserPreferences
1010 ok
= processPreferences(serviceID
,
1016 if (prefs
!= NULL
) {
1022 CFRelease(serviceID
);
1027 static CFDictionaryRef
1028 copyCurrentCallout(CFStringRef serviceID
,
1029 CFDictionaryRef current
,
1034 CFBooleanRef isDefault
;
1035 CFStringRef prefsID
;
1036 SCUserPreferencesPrivateRef
*userPrivate
= (SCUserPreferencesPrivateRef
*)context3
;
1038 if (current
== NULL
) {
1039 // we have nothing to "add"
1043 prefsID
= CFDictionaryGetValue(current
, USER_PREFERENCES_ID
);
1044 if (!isA_CFString(prefsID
)) {
1049 isDefault
= CFDictionaryGetValue(current
, USER_PREFERENCES_DEFAULT
);
1050 if (!isA_CFBoolean(isDefault
) || !CFBooleanGetValue(isDefault
)) {
1051 // if not the default configuration
1055 *userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, prefsID
);
1059 return CFRetain(current
);
1063 SCUserPreferencesRef
1064 SCNetworkConnectionCopyCurrentUserPreferences(SCNetworkConnectionRef connection
)
1066 SCUserPreferencesRef current
= NULL
;
1068 CFStringRef serviceID
;
1071 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
1073 // collect SCUserPreferences
1074 ok
= processPreferences(serviceID
,
1080 if (current
!= NULL
) {
1086 CFRelease(serviceID
);
1091 static CFDictionaryRef
1092 createCallout(CFStringRef serviceID
,
1093 CFDictionaryRef current
,
1098 CFMutableDictionaryRef newDict
;
1099 CFStringRef newPrefsID
= (CFStringRef
)context1
;
1101 if (current
!= NULL
) {
1102 // don't change existing entries
1103 return CFRetain(current
);
1106 newDict
= CFDictionaryCreateMutable(NULL
,
1108 &kCFTypeDictionaryKeyCallBacks
,
1109 &kCFTypeDictionaryValueCallBacks
);
1110 CFDictionarySetValue(newDict
, USER_PREFERENCES_ID
, newPrefsID
);
1115 SCUserPreferencesRef
1116 SCNetworkConnectionCreateUserPreferences(SCNetworkConnectionRef connection
)
1118 CFStringRef newPrefsID
;
1119 CFStringRef serviceID
;
1120 SCUserPreferencesPrivateRef userPrivate
;
1124 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
1126 // allocate a new user preferences ID
1127 uuid
= CFUUIDCreate(NULL
);
1128 newPrefsID
= CFUUIDCreateString(NULL
, uuid
);
1131 userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, newPrefsID
);
1132 if (userPrivate
!= NULL
) {
1133 (void) processPreferences(serviceID
,
1140 CFRelease(newPrefsID
);
1141 CFRelease(serviceID
);
1142 return (SCUserPreferencesRef
)userPrivate
;
1147 update_PPP_entity(SCUserPreferencesRef userPreferences
, CFDictionaryRef
*userOptions
)
1149 CFStringRef encryption
;
1150 CFDictionaryRef entity
;
1151 CFStringRef keychainID
;
1153 entity
= CFDictionaryGetValue(*userOptions
, kSCEntNetPPP
);
1154 if (!isA_CFDictionary(entity
)) {
1158 encryption
= CFDictionaryGetValue(entity
, kSCPropNetPPPAuthPasswordEncryption
);
1159 if (encryption
== NULL
) {
1160 // provide default encryption method
1161 encryption
= kSCValNetPPPAuthPasswordEncryptionKeychain
;
1164 if (!isA_CFString(encryption
) ||
1165 !CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1169 keychainID
= CFDictionaryGetValue(entity
, kSCPropNetPPPAuthPassword
);
1170 if (isA_CFString(keychainID
)) {
1171 // if password is keychain ID
1172 } else if (isA_CFData(keychainID
) &&
1173 ((CFDataGetLength((CFDataRef
)keychainID
) % sizeof(UniChar
)) == 0)) {
1174 // if inline password
1177 keychainID
= SCUserPreferencesGetUniqueID(userPreferences
);
1180 if (_SCSecKeychainPasswordItemExists(NULL
, keychainID
)) {
1181 CFMutableDictionaryRef new_entity
;
1182 CFMutableDictionaryRef new_options
;
1184 // access PPP password from system keychain
1185 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1187 CFDictionarySetValue(new_entity
,
1188 kSCPropNetPPPAuthPassword
,
1190 CFDictionarySetValue(new_entity
,
1191 kSCPropNetPPPAuthPasswordEncryption
,
1192 kSCValNetPPPAuthPasswordEncryptionKeychain
);
1194 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1195 CFDictionarySetValue(new_options
, kSCEntNetPPP
, new_entity
);
1196 CFRelease(new_entity
);
1198 CFRelease(*userOptions
);
1199 *userOptions
= new_options
;
1207 update_IPSec_entity(SCUserPreferencesRef userPreferences
, CFDictionaryRef
*userOptions
)
1209 CFStringRef encryption
;
1210 CFDictionaryRef entity
;
1211 SecKeychainRef keychain
= NULL
;
1212 CFStringRef keychainID
;
1214 CFDataRef sharedSecret
;
1216 entity
= CFDictionaryGetValue(*userOptions
, kSCEntNetIPSec
);
1217 if (!isA_CFDictionary(entity
)) {
1221 method
= CFDictionaryGetValue(entity
, kSCPropNetIPSecAuthenticationMethod
);
1222 if (!isA_CFString(method
) ||
1223 !CFEqual(method
, kSCValNetIPSecAuthenticationMethodSharedSecret
)) {
1227 encryption
= CFDictionaryGetValue(entity
, kSCPropNetIPSecSharedSecretEncryption
);
1228 if (encryption
== NULL
) {
1229 // provide default encryption method
1230 encryption
= kSCValNetIPSecSharedSecretEncryptionKeychain
;
1233 if (!isA_CFString(encryption
) ||
1234 !CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1238 keychainID
= CFDictionaryGetValue(entity
, kSCPropNetIPSecSharedSecret
);
1239 if (isA_CFString(keychainID
)) {
1240 // if shared secret is keychain ID
1241 CFRetain(keychainID
);
1242 } else if (isA_CFData(keychainID
) &&
1243 ((CFDataGetLength((CFDataRef
)keychainID
) % sizeof(UniChar
)) == 0)) {
1244 // if inline shared secret
1247 CFStringRef unique_id
;
1249 unique_id
= SCUserPreferencesGetUniqueID(userPreferences
);
1250 keychainID
= (CFStringRef
)CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1251 CFStringAppend((CFMutableStringRef
)keychainID
, CFSTR(".SS"));
1254 sharedSecret
= _SCSecKeychainPasswordItemCopy(NULL
, keychainID
);
1255 if (sharedSecret
!= NULL
) {
1256 CFMutableDictionaryRef new_entity
;
1257 CFMutableDictionaryRef new_options
;
1258 CFStringRef password
;
1260 // pass SharedSecret from user keychain
1261 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1263 password
= CFStringCreateWithBytes(NULL
,
1264 CFDataGetBytePtr(sharedSecret
),
1265 CFDataGetLength(sharedSecret
),
1266 kCFStringEncodingUTF8
,
1268 CFRelease(sharedSecret
);
1269 CFDictionarySetValue(new_entity
,
1270 kSCPropNetIPSecSharedSecret
,
1272 CFRelease(password
);
1273 CFDictionaryRemoveValue(new_entity
,
1274 kSCPropNetIPSecSharedSecretEncryption
);
1276 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1277 CFDictionarySetValue(new_options
, kSCEntNetIPSec
, new_entity
);
1278 CFRelease(new_entity
);
1280 CFRelease(*userOptions
);
1281 *userOptions
= new_options
;
1285 keychain
= _SCSecKeychainCopySystemKeychain();
1286 if (keychain
== NULL
) {
1290 if (_SCSecKeychainPasswordItemExists(keychain
, keychainID
)) {
1291 CFMutableDictionaryRef new_entity
;
1292 CFMutableDictionaryRef new_options
;
1294 // access SharedSecret from system keychain
1295 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1297 CFDictionarySetValue(new_entity
,
1298 kSCPropNetIPSecSharedSecret
,
1300 CFDictionarySetValue(new_entity
,
1301 kSCPropNetIPSecSharedSecretEncryption
,
1302 kSCValNetIPSecSharedSecretEncryptionKeychain
);
1304 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1305 CFDictionarySetValue(new_options
, kSCEntNetIPSec
, new_entity
);
1306 CFRelease(new_entity
);
1308 CFRelease(*userOptions
);
1309 *userOptions
= new_options
;
1314 if (keychain
!= NULL
) CFRelease(keychain
);
1315 CFRelease(keychainID
);
1320 static CFDictionaryRef
1321 copyOptionsCallout(CFStringRef serviceID
,
1322 CFDictionaryRef current
,
1327 CFStringRef matchID
= (CFStringRef
)context1
;
1328 CFMutableDictionaryRef
*userOptions
= (CFMutableDictionaryRef
*)context3
;
1330 if (current
== NULL
) {
1331 // we have nothing to "add"
1335 if (isMatchingPrefsID(current
, matchID
)) {
1336 // if we match, return options dictionary
1337 if (*userOptions
!= NULL
) CFRelease(*userOptions
);
1338 *userOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
1339 CFDictionaryRemoveValue(*userOptions
, USER_PREFERENCES_ID
);
1340 CFDictionaryRemoveValue(*userOptions
, USER_PREFERENCES_DEFAULT
);
1343 return CFRetain(current
);
1348 SCNetworkConnectionStartWithUserPreferences(SCNetworkConnectionRef connection
,
1349 SCUserPreferencesRef userPreferences
,
1353 CFDictionaryRef userOptions
= NULL
;
1354 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
1356 if (!isA_SCUserPreferences(userPreferences
)) {
1357 _SCErrorSet(kSCStatusInvalidArgument
);
1361 (void) processPreferences(userPrivate
->serviceID
,
1363 (void *)userPrivate
->prefsID
,
1368 * For some legacy preferences, some of the user options
1369 * were missing yet handled by the APIs. Make sure that
1370 * everything still works!
1372 if (userOptions
!= NULL
) {
1373 update_PPP_entity (userPreferences
, &userOptions
);
1374 update_IPSec_entity(userPreferences
, &userOptions
);
1377 ok
= SCNetworkConnectionStart(connection
, userOptions
, linger
);
1379 if (userOptions
!= NULL
) {
1380 CFRelease(userOptions
);
1388 #pragma mark SCUserPreferences + SCNetworkInterface Password SPIs
1392 getUserPasswordID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1394 CFStringRef unique_id
= NULL
;
1396 if (config
!= NULL
) {
1397 CFStringRef encryption
;
1399 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
1400 if (isA_CFString(encryption
) &&
1401 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1402 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
1405 if (unique_id
== NULL
) {
1406 unique_id
= SCUserPreferencesGetUniqueID(userPreferences
);
1414 copyUserSharedSecretID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1416 CFMutableStringRef sharedSecret
= NULL
;
1418 if (config
!= NULL
) {
1419 CFStringRef encryption
;
1421 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
1422 if (isA_CFString(encryption
) &&
1423 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1424 sharedSecret
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
1425 if (sharedSecret
!= NULL
) {
1426 CFRetain(sharedSecret
);
1431 if (sharedSecret
== NULL
) {
1432 CFStringRef unique_id
;
1434 unique_id
= getUserPasswordID(config
, userPreferences
);
1435 sharedSecret
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1436 CFStringAppend(sharedSecret
, CFSTR(".SS"));
1439 return sharedSecret
;
1444 copyUserXAuthID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1446 CFMutableStringRef xauth_id
= NULL
;
1448 if (config
!= NULL
) {
1449 CFStringRef encryption
;
1451 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
1452 if (isA_CFString(encryption
) &&
1453 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
1454 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
1455 if (xauth_id
!= NULL
) {
1461 if (xauth_id
== NULL
) {
1462 CFStringRef unique_id
;
1464 unique_id
= getUserPasswordID(config
, userPreferences
);
1465 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1466 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
1474 checkUserPreferencesPassword(SCUserPreferencesRef userPreferences
,
1475 SCNetworkInterfaceRef interface
,
1476 SCNetworkInterfacePasswordType passwordType
)
1478 if (!isA_SCUserPreferences(userPreferences
)) {
1479 _SCErrorSet(kSCStatusInvalidArgument
);
1483 if (!isA_SCNetworkInterface(interface
)) {
1484 _SCErrorSet(kSCStatusInvalidArgument
);
1488 switch (passwordType
) {
1489 case kSCNetworkInterfacePasswordTypePPP
: {
1490 CFStringRef interfaceType
;
1492 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1493 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1494 _SCErrorSet(kSCStatusInvalidArgument
);
1500 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1501 CFStringRef interfaceType
;
1503 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1504 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1505 _SCErrorSet(kSCStatusInvalidArgument
);
1509 interface
= SCNetworkInterfaceGetInterface(interface
);
1510 if (interface
== NULL
) {
1511 _SCErrorSet(kSCStatusInvalidArgument
);
1515 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1516 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
1517 _SCErrorSet(kSCStatusInvalidArgument
);
1523 case kSCNetworkInterfacePasswordTypeEAPOL
: {
1524 _SCErrorSet(kSCStatusInvalidArgument
);
1528 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1529 CFStringRef interfaceType
;
1531 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1532 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
1533 _SCErrorSet(kSCStatusInvalidArgument
);
1548 SCUserPreferencesCheckInterfacePassword(SCUserPreferencesRef userPreferences
,
1549 SCNetworkInterfaceRef interface
,
1550 SCNetworkInterfacePasswordType passwordType
)
1552 Boolean exists
= FALSE
;
1554 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1558 switch (passwordType
) {
1559 case kSCNetworkInterfacePasswordTypePPP
: {
1560 CFDictionaryRef config
;
1561 CFStringRef unique_id
;
1563 // get configuration
1564 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1566 // get userPreferences ID
1567 unique_id
= getUserPasswordID(config
, userPreferences
);
1570 exists
= __extract_password(NULL
,
1572 kSCPropNetPPPAuthPassword
,
1573 kSCPropNetPPPAuthPasswordEncryption
,
1574 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1578 if (config
!= NULL
) CFRelease(config
);
1582 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1583 CFDictionaryRef config
;
1584 CFStringRef shared_id
;
1586 // get configuration
1587 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1591 // get sharedSecret ID
1592 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1595 exists
= __extract_password(NULL
,
1597 kSCPropNetIPSecSharedSecret
,
1598 kSCPropNetIPSecSharedSecretEncryption
,
1599 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1603 if (config
!= NULL
) CFRelease(config
);
1604 CFRelease(shared_id
);
1608 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1609 CFDictionaryRef config
;
1610 CFStringRef xauth_id
;
1612 // get configuration
1613 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1616 xauth_id
= copyUserXAuthID(config
, userPreferences
);
1619 exists
= __extract_password(NULL
,
1621 kSCPropNetIPSecXAuthPassword
,
1622 kSCPropNetIPSecXAuthPasswordEncryption
,
1623 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
1627 if (config
!= NULL
) CFRelease(config
);
1628 CFRelease(xauth_id
);
1633 _SCErrorSet(kSCStatusInvalidArgument
);
1642 SCUserPreferencesCopyInterfacePassword(SCUserPreferencesRef userPreferences
,
1643 SCNetworkInterfaceRef interface
,
1644 SCNetworkInterfacePasswordType passwordType
)
1646 CFDataRef password
= NULL
;
1648 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1652 switch (passwordType
) {
1653 case kSCNetworkInterfacePasswordTypePPP
: {
1654 CFDictionaryRef config
;
1655 CFStringRef unique_id
;
1657 // get configuration
1658 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1660 // get userPreferences ID
1661 unique_id
= getUserPasswordID(config
, userPreferences
);
1664 (void) __extract_password(NULL
,
1666 kSCPropNetPPPAuthPassword
,
1667 kSCPropNetPPPAuthPasswordEncryption
,
1668 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1672 if (config
!= NULL
) CFRelease(config
);
1676 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1677 CFDictionaryRef config
;
1678 CFStringRef shared_id
;
1680 // get configuration
1681 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1685 // get sharedSecret ID
1686 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1689 (void) __extract_password(NULL
,
1691 kSCPropNetIPSecSharedSecret
,
1692 kSCPropNetIPSecSharedSecretEncryption
,
1693 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1697 if (config
!= NULL
) CFRelease(config
);
1698 CFRelease(shared_id
);
1702 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1703 CFDictionaryRef config
;
1704 CFStringRef xauth_id
;
1706 // get configuration
1707 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1710 xauth_id
= copyUserXAuthID(config
, userPreferences
);
1713 (void) __extract_password(NULL
,
1715 kSCPropNetIPSecXAuthPassword
,
1716 kSCPropNetIPSecXAuthPasswordEncryption
,
1717 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
1721 if (config
!= NULL
) CFRelease(config
);
1722 CFRelease(xauth_id
);
1727 _SCErrorSet(kSCStatusInvalidArgument
);
1736 SCUserPreferencesRemoveInterfacePassword(SCUserPreferencesRef userPreferences
,
1737 SCNetworkInterfaceRef interface
,
1738 SCNetworkInterfacePasswordType passwordType
)
1742 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1746 switch (passwordType
) {
1747 case kSCNetworkInterfacePasswordTypePPP
: {
1748 CFDictionaryRef config
;
1749 CFDictionaryRef newConfig
= NULL
;
1750 CFStringRef unique_id
;
1752 // get configuration
1753 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1755 // get userPreferences ID
1756 unique_id
= getUserPasswordID(config
, userPreferences
);
1759 ok
= __remove_password(NULL
,
1761 kSCPropNetPPPAuthPassword
,
1762 kSCPropNetPPPAuthPasswordEncryption
,
1763 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1767 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1768 if (newConfig
!= NULL
) CFRelease(newConfig
);
1771 if (config
!= NULL
) CFRelease(config
);
1775 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1776 CFDictionaryRef config
;
1777 CFDictionaryRef newConfig
= NULL
;
1778 CFStringRef shared_id
;
1780 // get configuration
1781 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1785 // get sharedSecret ID
1786 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1789 ok
= __remove_password(NULL
,
1791 kSCPropNetIPSecSharedSecret
,
1792 kSCPropNetIPSecSharedSecretEncryption
,
1793 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1797 ok
= SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences
,
1801 if (newConfig
!= NULL
) CFRelease(newConfig
);
1804 if (config
!= NULL
) CFRelease(config
);
1805 CFRelease(shared_id
);
1809 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1810 CFDictionaryRef config
;
1811 CFDictionaryRef newConfig
= NULL
;
1812 CFStringRef xauth_id
;
1814 // get configuration
1815 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1818 xauth_id
= copyUserXAuthID(config
, userPreferences
);
1821 ok
= __remove_password(NULL
,
1823 kSCPropNetIPSecXAuthPassword
,
1824 kSCPropNetIPSecXAuthPasswordEncryption
,
1825 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
1829 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1830 if (newConfig
!= NULL
) CFRelease(newConfig
);
1833 if (config
!= NULL
) CFRelease(config
);
1834 CFRelease(xauth_id
);
1839 _SCErrorSet(kSCStatusInvalidArgument
);
1848 SCUserPreferencesSetInterfacePassword(SCUserPreferencesRef userPreferences
,
1849 SCNetworkInterfaceRef interface
,
1850 SCNetworkInterfacePasswordType passwordType
,
1852 CFDictionaryRef options
)
1854 CFStringRef account
= NULL
;
1856 CFDictionaryRef config
;
1857 CFStringRef description
= NULL
;
1858 CFStringRef label
= NULL
;
1861 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1865 bundle
= _SC_CFBundleGet();
1867 switch (passwordType
) {
1868 case kSCNetworkInterfacePasswordTypePPP
: {
1869 CFStringRef unique_id
;
1871 // get configuration
1872 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1874 // get userPreferences ID
1875 unique_id
= getUserPasswordID(config
, userPreferences
);
1877 // User prefs auth name --> keychain "Account"
1878 if (config
!= NULL
) {
1879 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
1882 // User prefs "name" --> keychain "Name"
1883 label
= SCUserPreferencesCopyName(userPreferences
);
1885 // "PPP Password" --> keychain "Kind"
1886 if (bundle
!= NULL
) {
1887 description
= CFBundleCopyLocalizedString(bundle
,
1888 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
1889 CFSTR("PPP Password"),
1894 ok
= _SCSecKeychainPasswordItemSet(NULL
,
1896 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
1897 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
1902 CFMutableDictionaryRef newConfig
;
1904 if (config
!= NULL
) {
1905 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
1907 newConfig
= CFDictionaryCreateMutable(NULL
,
1909 &kCFTypeDictionaryKeyCallBacks
,
1910 &kCFTypeDictionaryValueCallBacks
);
1912 CFDictionarySetValue(newConfig
,
1913 kSCPropNetPPPAuthPassword
,
1915 CFDictionarySetValue(newConfig
,
1916 kSCPropNetPPPAuthPasswordEncryption
,
1917 kSCValNetPPPAuthPasswordEncryptionKeychain
);
1918 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1919 CFRelease(newConfig
);
1922 if (config
!= NULL
) CFRelease(config
);
1923 if (description
!= NULL
) CFRelease(description
);
1924 if (label
!= NULL
) CFRelease(label
);
1928 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1929 CFStringRef shared_id
;
1931 // get configuration
1932 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1936 // get sharedSecret ID
1937 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1939 // User prefs "name" --> keychain "Name"
1940 label
= SCUserPreferencesCopyName(userPreferences
);
1942 // "IPSec Shared Secret" --> keychain "Kind"
1943 if (bundle
!= NULL
) {
1944 description
= CFBundleCopyLocalizedString(bundle
,
1945 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
1946 CFSTR("IPSec Shared Secret"),
1951 ok
= _SCSecKeychainPasswordItemSet(NULL
,
1953 (label
!= NULL
) ? label
: CFSTR("VPN Connection"),
1954 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
1959 CFMutableDictionaryRef newConfig
= NULL
;
1961 if (config
!= NULL
) {
1962 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
1964 newConfig
= CFDictionaryCreateMutable(NULL
,
1966 &kCFTypeDictionaryKeyCallBacks
,
1967 &kCFTypeDictionaryValueCallBacks
);
1969 CFDictionarySetValue(newConfig
,
1970 kSCPropNetIPSecSharedSecret
,
1972 CFDictionarySetValue(newConfig
,
1973 kSCPropNetIPSecSharedSecretEncryption
,
1974 kSCValNetIPSecSharedSecretEncryptionKeychain
);
1975 ok
= SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences
,
1979 CFRelease(newConfig
);
1982 if (config
!= NULL
) CFRelease(config
);
1983 if (description
!= NULL
) CFRelease(description
);
1984 if (label
!= NULL
) CFRelease(label
);
1985 CFRelease(shared_id
);
1989 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1990 CFStringRef xauth_id
;
1992 // get configuration
1993 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1996 xauth_id
= copyUserXAuthID(config
, userPreferences
);
1998 // User prefs XAuth name --> keychain "Account"
1999 if (config
!= NULL
) {
2000 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
2003 // User prefs "name" --> keychain "Name"
2004 label
= SCUserPreferencesCopyName(userPreferences
);
2006 // "IPSec XAuth Password" --> keychain "Kind"
2007 if (bundle
!= NULL
) {
2008 description
= CFBundleCopyLocalizedString(bundle
,
2009 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
2010 CFSTR("IPSec XAuth Password"),
2015 ok
= _SCSecKeychainPasswordItemSet(NULL
,
2017 (label
!= NULL
) ? label
: CFSTR("VPN Connection"),
2018 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
2023 CFMutableDictionaryRef newConfig
;
2025 if (config
!= NULL
) {
2026 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
2028 newConfig
= CFDictionaryCreateMutable(NULL
,
2030 &kCFTypeDictionaryKeyCallBacks
,
2031 &kCFTypeDictionaryValueCallBacks
);
2033 CFDictionarySetValue(newConfig
,
2034 kSCPropNetIPSecXAuthPassword
,
2036 CFDictionarySetValue(newConfig
,
2037 kSCPropNetIPSecXAuthPasswordEncryption
,
2038 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
2039 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
2040 CFRelease(newConfig
);
2043 if (config
!= NULL
) CFRelease(config
);
2044 if (description
!= NULL
) CFRelease(description
);
2045 if (label
!= NULL
) CFRelease(label
);
2046 CFRelease(xauth_id
);
2051 _SCErrorSet(kSCStatusInvalidArgument
);