2 * Copyright (c) 2006-2012, 2015-2018 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 "SCNetworkConfigurationInternal.h"
32 #pragma mark SCUserPreferences
37 // base CFType information
41 CFStringRef serviceID
;
43 // user preferences [unique] id
46 } SCUserPreferencesPrivate
, *SCUserPreferencesPrivateRef
;
49 static CFStringRef
__SCUserPreferencesCopyDescription (CFTypeRef cf
);
50 static void __SCUserPreferencesDeallocate (CFTypeRef cf
);
51 static Boolean
__SCUserPreferencesEqual (CFTypeRef cf1
, CFTypeRef cf2
);
52 static CFHashCode
__SCUserPreferencesHash (CFTypeRef cf
);
55 static CFTypeID __kSCUserPreferencesTypeID
= _kCFRuntimeNotATypeID
;
58 static const CFRuntimeClass __SCUserPreferencesClass
= {
60 "SCUserPreferences", // className
63 __SCUserPreferencesDeallocate
, // dealloc
64 __SCUserPreferencesEqual
, // equal
65 __SCUserPreferencesHash
, // hash
66 NULL
, // copyFormattingDesc
67 __SCUserPreferencesCopyDescription
// copyDebugDesc
71 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
75 __SCUserPreferencesCopyDescription(CFTypeRef cf
)
77 CFAllocatorRef allocator
= CFGetAllocator(cf
);
78 CFMutableStringRef result
;
79 SCUserPreferencesPrivateRef prefsPrivate
= (SCUserPreferencesPrivateRef
)cf
;
81 result
= CFStringCreateMutable(allocator
, 0);
82 CFStringAppendFormat(result
, NULL
, CFSTR("<SCUserPreferences %p [%p]> {"), cf
, allocator
);
83 CFStringAppendFormat(result
, NULL
, CFSTR("service = %@"), prefsPrivate
->serviceID
);
84 CFStringAppendFormat(result
, NULL
, CFSTR(", id = %@"), prefsPrivate
->prefsID
);
85 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
92 __SCUserPreferencesDeallocate(CFTypeRef cf
)
94 SCUserPreferencesPrivateRef prefsPrivate
= (SCUserPreferencesPrivateRef
)cf
;
96 /* release resources */
98 CFRelease(prefsPrivate
->prefsID
);
99 CFRelease(prefsPrivate
->serviceID
);
106 __SCUserPreferencesEqual(CFTypeRef cf1
, CFTypeRef cf2
)
108 SCUserPreferencesPrivateRef s1
= (SCUserPreferencesPrivateRef
)cf1
;
109 SCUserPreferencesPrivateRef s2
= (SCUserPreferencesPrivateRef
)cf2
;
114 if (!CFEqual(s1
->prefsID
, s2
->prefsID
))
115 return FALSE
; // if not the same [unique] prefs identifier
122 __SCUserPreferencesHash(CFTypeRef cf
)
124 SCUserPreferencesPrivateRef prefsPrivate
= (SCUserPreferencesPrivateRef
)cf
;
126 return CFHash(prefsPrivate
->prefsID
);
131 __SCUserPreferencesInitialize(void)
133 __kSCUserPreferencesTypeID
= _CFRuntimeRegisterClass(&__SCUserPreferencesClass
);
138 static SCUserPreferencesPrivateRef
139 __SCUserPreferencesCreatePrivate(CFAllocatorRef allocator
,
140 CFStringRef serviceID
,
143 SCUserPreferencesPrivateRef prefsPrivate
;
146 /* initialize runtime */
147 pthread_once(&initialized
, __SCUserPreferencesInitialize
);
149 /* allocate target */
150 size
= sizeof(SCUserPreferencesPrivate
) - sizeof(CFRuntimeBase
);
151 prefsPrivate
= (SCUserPreferencesPrivateRef
)_CFRuntimeCreateInstance(allocator
,
152 __kSCUserPreferencesTypeID
,
155 if (prefsPrivate
== NULL
) {
159 /* initialize non-zero/NULL members */
160 prefsPrivate
->serviceID
= CFStringCreateCopy(NULL
, serviceID
);
161 prefsPrivate
->prefsID
= CFStringCreateCopy(NULL
, prefsID
);
167 static __inline__ CFTypeRef
168 isA_SCUserPreferences(CFTypeRef obj
)
170 return (isA_CFType(obj
, SCUserPreferencesGetTypeID()));
175 #pragma mark SCUserPreferences SPIs
178 #define USER_PREFERENCES_NOTIFICATION "com.apple.networkConnect"
179 #define USER_PREFERENCES_APPLICATION_ID CFSTR("com.apple.networkConnect")
180 #define USER_PREFERENCES_ID CFSTR("UniqueIdentifier")
181 #define USER_PREFERENCES_DEFAULT CFSTR("ConnectByDefault")
184 #define LOG_CFPREFERENCES_CHANGES
185 #ifdef LOG_CFPREFERENCES_CHANGES
188 #include <sys/stat.h>
189 #include <sys/time.h>
191 logCFPreferencesChange(CFStringRef serviceID
, CFArrayRef newPreferences
)
195 CFArrayRef oldPreferences
;
199 struct timeval tv_now
;
201 bVal
= CFPreferencesCopyAppValue(CFSTR("LOG_SC_CHANGES"), USER_PREFERENCES_APPLICATION_ID
);
205 enabled
= isA_CFBoolean(bVal
) && CFBooleanGetValue(bVal
);
208 // if debugging not enabled
212 // if debugging not enabled
216 (void)gettimeofday(&tv_now
, NULL
);
217 (void)localtime_r(&tv_now
.tv_sec
, &tm_now
);
219 str
= CFStringCreateWithFormat(NULL
, NULL
,
220 CFSTR("/var/tmp/com.apple.networkConnect-%@-%4d%02d%02d.%02d%02d%02d.%03d"),
222 tm_now
.tm_year
+ 1900,
228 tv_now
.tv_usec
/ 1000);
229 _SC_cfstring_to_cstring(str
, dir
, sizeof(dir
), kCFStringEncodingUTF8
);
232 SC_log(LOG_NOTICE
, "CFPreferences being updated, old/new in \"%s\"", dir
);
234 if (mkdir(dir
, 0755) == -1) {
235 SC_log(LOG_NOTICE
, "mkdir() failed: %s", SCErrorString(errno
));
239 trace
= _SC_copyBacktrace();
245 strlcpy(path
, dir
, sizeof(path
));
246 strlcat(path
, "/backtrace", sizeof(path
));
247 fd
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
249 SC_log(LOG_NOTICE
, "fopen() failed: %s", SCErrorString(errno
));
254 SCPrint(TRUE
, f
, CFSTR("%@"), trace
);
259 oldPreferences
= CFPreferencesCopyAppValue(serviceID
, USER_PREFERENCES_APPLICATION_ID
);
260 if (oldPreferences
!= NULL
) {
265 strlcpy(path
, dir
, sizeof(path
));
266 strlcat(path
, "/old", sizeof(path
));
267 fd
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
269 SC_log(LOG_NOTICE
, "fopen() failed: %s", SCErrorString(errno
));
270 CFRelease(oldPreferences
);
273 data
= CFPropertyListCreateData(NULL
, oldPreferences
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
);
275 SC_log(LOG_NOTICE
, "CFPropertyListCreateData() failed");
277 CFRelease(oldPreferences
);
280 (void) write(fd
, CFDataGetBytePtr(data
), CFDataGetLength(data
));
283 CFRelease(oldPreferences
);
286 if (newPreferences
!= NULL
) {
291 strlcpy(path
, dir
, sizeof(path
));
292 strlcat(path
, "/new", sizeof(path
));
293 fd
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
295 SC_log(LOG_NOTICE
, "fopen() failed: %s", SCErrorString(errno
));
298 data
= CFPropertyListCreateData(NULL
, newPreferences
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
);
300 SC_log(LOG_NOTICE
, "CFPropertyListCreateData() failed");
304 (void) write(fd
, CFDataGetBytePtr(data
), CFDataGetLength(data
));
311 #endif // LOG_CFPREFERENCES_CHANGES
315 copyCFPreferencesForServiceID(CFStringRef serviceID
)
319 // fetch "Managed" or "ByHost" user preferences
320 (void) CFPreferencesAppSynchronize(USER_PREFERENCES_APPLICATION_ID
);
321 prefs
= CFPreferencesCopyAppValue(serviceID
,
322 USER_PREFERENCES_APPLICATION_ID
);
324 if ((prefs
!= NULL
) && !isA_CFArray(prefs
)) {
334 setCFPreferencesForServiceID(CFStringRef serviceID
, CFArrayRef newPreferences
)
338 if (CFPreferencesAppValueIsForced(serviceID
, USER_PREFERENCES_APPLICATION_ID
)) {
342 #ifdef LOG_CFPREFERENCES_CHANGES
343 logCFPreferencesChange(serviceID
, newPreferences
);
344 #endif // LOG_CFPREFERENCES_CHANGES
346 CFPreferencesSetValue(serviceID
,
348 USER_PREFERENCES_APPLICATION_ID
,
349 kCFPreferencesCurrentUser
,
350 kCFPreferencesCurrentHost
);
351 ok
= CFPreferencesSynchronize(USER_PREFERENCES_APPLICATION_ID
,
352 kCFPreferencesCurrentUser
,
353 kCFPreferencesCurrentHost
);
355 (void) notify_post(USER_PREFERENCES_NOTIFICATION
);
362 addPreference(CFMutableArrayRef
*newPrefs
, CFDictionaryRef newDict
)
364 if (*newPrefs
== NULL
) {
365 *newPrefs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
367 CFArrayAppendValue(*newPrefs
, newDict
);
373 typedef CFDictionaryRef (*processPreferencesCallout
) (CFStringRef serviceID
,
374 CFDictionaryRef current
,
381 processPreferences(CFStringRef serviceID
,
382 processPreferencesCallout callout
,
387 Boolean changed
= FALSE
;
390 CFDictionaryRef newDict
= NULL
;
391 CFMutableArrayRef newPrefs
= NULL
;
395 prefs
= copyCFPreferencesForServiceID(serviceID
);
396 n
= (prefs
!= NULL
) ? CFArrayGetCount(prefs
) : 0;
397 for (i
= 0; i
< n
; i
++) {
398 CFDictionaryRef dict
;
400 dict
= CFArrayGetValueAtIndex(prefs
, i
);
401 assert(dict
!= NULL
);
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 #pragma unused(serviceID)
500 #pragma unused(context2)
501 #pragma unused(context3)
502 CFStringRef matchID
= (CFStringRef
)context1
;
504 if (current
== NULL
) {
505 // we have nothing to "add"
509 if (isMatchingPrefsID(current
, matchID
)) {
510 // if we match, don't add (i.e. remove)
514 return CFRetain(current
);
519 SCUserPreferencesRemove(SCUserPreferencesRef userPreferences
)
521 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
523 if (!isA_SCUserPreferences(userPreferences
)) {
524 _SCErrorSet(kSCStatusInvalidArgument
);
528 return processPreferences(userPrivate
->serviceID
,
530 (void *)userPrivate
->prefsID
,
536 static CF_RETURNS_RETAINED CFDictionaryRef
537 setCurrentCallout(CFStringRef serviceID
,
538 CFDictionaryRef current
,
543 #pragma unused(serviceID)
544 #pragma unused(context2)
545 #pragma unused(context3)
546 CFStringRef matchID
= (CFStringRef
)context1
;
547 CFMutableDictionaryRef newDict
;
549 if (current
== NULL
) {
550 // we have nothing to "add"
554 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
556 // remove "default" flag
557 CFDictionaryRemoveValue(newDict
, USER_PREFERENCES_DEFAULT
);
559 if (isMatchingPrefsID(current
, matchID
)) {
560 // if we match, set "default" flag
561 CFDictionarySetValue(newDict
, USER_PREFERENCES_DEFAULT
, kCFBooleanTrue
);
569 SCUserPreferencesSetCurrent(SCUserPreferencesRef userPreferences
)
571 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
573 if (!isA_SCUserPreferences(userPreferences
)) {
574 _SCErrorSet(kSCStatusInvalidArgument
);
578 return processPreferences(userPrivate
->serviceID
,
580 (void *)userPrivate
->prefsID
,
586 static CFDictionaryRef
587 copyNameCallout(CFStringRef serviceID
,
588 CFDictionaryRef current
,
593 #pragma unused(serviceID)
594 #pragma unused(context2)
595 #pragma unused(context3)
596 CFStringRef matchID
= (CFStringRef
)context1
;
597 CFStringRef
*name
= (CFStringRef
*)context3
;
599 if (current
== NULL
) {
600 // we have nothing to "add"
604 if (isMatchingPrefsID(current
, matchID
)) {
609 *name
= CFDictionaryGetValue(current
, kSCPropUserDefinedName
);
611 // for backwards compatibility, we also check for the name in the PPP entity
615 ppp
= CFDictionaryGetValue(current
, kSCEntNetPPP
);
616 if (isA_CFDictionary(ppp
)) {
617 *name
= CFDictionaryGetValue(ppp
, kSCPropUserDefinedName
);
621 *name
= isA_CFString(*name
);
627 return CFRetain(current
);
632 SCUserPreferencesCopyName(SCUserPreferencesRef userPreferences
)
634 CFStringRef name
= NULL
;
636 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
638 if (!isA_SCUserPreferences(userPreferences
)) {
639 _SCErrorSet(kSCStatusInvalidArgument
);
643 // find SCUserPreferences and copy name
644 ok
= processPreferences(userPrivate
->serviceID
,
646 (void *)userPrivate
->prefsID
,
660 static CF_RETURNS_RETAINED CFDictionaryRef
661 setNameCallout(CFStringRef serviceID
,
662 CFDictionaryRef current
,
667 #pragma unused(serviceID)
668 #pragma unused(context2)
669 #pragma unused(context3)
670 CFStringRef matchID
= (CFStringRef
)context1
;
671 CFMutableDictionaryRef newDict
;
672 CFStringRef newName
= (CFStringRef
)context2
;
674 if (current
== NULL
) {
675 // we have nothing to "add"
679 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
681 if (isMatchingPrefsID(current
, matchID
)) {
682 CFDictionaryRef pppEntity
;
685 if (newName
!= NULL
) {
686 CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, newName
);
688 CFDictionaryRemoveValue(newDict
, kSCPropUserDefinedName
);
691 // for backwards compatibility, we also set the name in the PPP entity
692 pppEntity
= CFDictionaryGetValue(newDict
, kSCEntNetPPP
);
693 if (isA_CFDictionary(pppEntity
)) {
694 CFMutableDictionaryRef newPPPEntity
;
696 newPPPEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, pppEntity
);
697 if (newName
!= NULL
) {
698 CFDictionarySetValue(newPPPEntity
, kSCPropUserDefinedName
, newName
);
700 CFDictionaryRemoveValue(newPPPEntity
, kSCPropUserDefinedName
);
702 CFDictionarySetValue(newDict
, kSCEntNetPPP
, newPPPEntity
);
703 CFRelease(newPPPEntity
);
712 SCUserPreferencesSetName(SCUserPreferencesRef userPreferences
, CFStringRef newName
)
715 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
717 if (!isA_SCUserPreferences(userPreferences
)) {
718 _SCErrorSet(kSCStatusInvalidArgument
);
722 if ((newName
!= NULL
) && !isA_CFString(newName
)) {
723 _SCErrorSet(kSCStatusInvalidArgument
);
727 // find SCUserPreferences and set name
728 ok
= processPreferences(userPrivate
->serviceID
,
730 (void *)userPrivate
->prefsID
,
738 static CFDictionaryRef
739 copyInterfaceConfigurationCallout(CFStringRef serviceID
,
740 CFDictionaryRef current
,
745 #pragma unused(serviceID)
746 CFDictionaryRef
*dict
= (CFDictionaryRef
*)context3
;
747 CFStringRef interfaceType
= (CFStringRef
)context2
;
748 CFStringRef matchID
= (CFStringRef
)context1
;
750 if (current
== NULL
) {
751 // we have nothing to "add"
755 if (isMatchingPrefsID(current
, matchID
)) {
760 *dict
= CFDictionaryGetValue(current
, interfaceType
);
761 *dict
= isA_CFDictionary(*dict
);
767 return CFRetain(current
);
772 SCUserPreferencesCopyInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
773 SCNetworkInterfaceRef interface
)
775 CFStringRef defaultType
;
776 CFDictionaryRef entity
= NULL
;
778 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
780 if (!isA_SCUserPreferences(userPreferences
)) {
781 _SCErrorSet(kSCStatusInvalidArgument
);
785 if (!isA_SCNetworkInterface(interface
)) {
786 _SCErrorSet(kSCStatusInvalidArgument
);
791 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
792 if (defaultType
== NULL
) {
793 _SCErrorSet(kSCStatusInvalidArgument
);
797 // find SCUserPreferences and copy interface entity
798 ok
= processPreferences(userPrivate
->serviceID
,
799 copyInterfaceConfigurationCallout
,
800 (void *)userPrivate
->prefsID
,
804 if (entity
!= NULL
) {
814 static CF_RETURNS_RETAINED CFDictionaryRef
815 setInterfaceConfigurationCallout(CFStringRef serviceID
,
816 CFDictionaryRef current
,
821 #pragma unused(serviceID)
822 CFStringRef interfaceType
= (CFStringRef
)context2
;
823 CFStringRef matchID
= (CFStringRef
)context1
;
824 CFMutableDictionaryRef newDict
;
825 CFDictionaryRef newOptions
= (CFDictionaryRef
)context3
;
827 if (current
== NULL
) {
828 // we have nothing to "add"
832 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
834 if (isMatchingPrefsID(current
, matchID
)) {
835 if (newOptions
!= NULL
) {
836 CFDictionarySetValue(newDict
, interfaceType
, newOptions
);
838 // for backwards compatibility, we want to ensure that
839 // the name is set in both the top level and in the PPP
841 if (CFEqual(interfaceType
, kSCEntNetPPP
)) {
844 name
= CFDictionaryGetValue(newOptions
, kSCPropUserDefinedName
);
846 // if name was passed in newOptions, push up
847 CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, name
);
849 name
= CFDictionaryGetValue(newDict
, kSCPropUserDefinedName
);
851 CFMutableDictionaryRef newPPPEntity
;
853 // if name in parent, push into entity
854 newPPPEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, newOptions
);
855 CFDictionarySetValue(newPPPEntity
, kSCPropUserDefinedName
, name
);
856 CFDictionarySetValue(newDict
, interfaceType
, newPPPEntity
);
857 CFRelease(newPPPEntity
);
862 CFDictionaryRemoveValue(newDict
, interfaceType
);
871 SCUserPreferencesSetInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
872 SCNetworkInterfaceRef interface
,
873 CFDictionaryRef newOptions
)
875 CFStringRef defaultType
;
877 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
879 if (!isA_SCUserPreferences(userPreferences
)) {
880 _SCErrorSet(kSCStatusInvalidArgument
);
884 if (!isA_SCNetworkInterface(interface
)) {
885 _SCErrorSet(kSCStatusInvalidArgument
);
890 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
891 if (defaultType
== NULL
) {
892 _SCErrorSet(kSCStatusInvalidArgument
);
896 // set new interface entity for SCUserPreferences
897 ok
= processPreferences(userPrivate
->serviceID
,
898 setInterfaceConfigurationCallout
,
899 (void *)userPrivate
->prefsID
,
908 SCUserPreferencesCopyExtendedInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
909 SCNetworkInterfaceRef interface
,
910 CFStringRef extendedType
)
912 CFDictionaryRef entity
= NULL
;
914 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
916 if (!isA_SCUserPreferences(userPreferences
)) {
917 _SCErrorSet(kSCStatusInvalidArgument
);
921 if (!isA_SCNetworkInterface(interface
)) {
922 _SCErrorSet(kSCStatusInvalidArgument
);
926 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, FALSE
)) {
927 _SCErrorSet(kSCStatusInvalidArgument
);
931 // find SCUserPreferences and copy interface entity
932 ok
= processPreferences(userPrivate
->serviceID
,
933 copyInterfaceConfigurationCallout
,
934 (void *)userPrivate
->prefsID
,
935 (void *)extendedType
,
938 if (entity
!= NULL
) {
949 SCUserPreferencesSetExtendedInterfaceConfiguration(SCUserPreferencesRef userPreferences
,
950 SCNetworkInterfaceRef interface
,
951 CFStringRef extendedType
,
952 CFDictionaryRef newOptions
)
955 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
957 if (!isA_SCUserPreferences(userPreferences
)) {
958 _SCErrorSet(kSCStatusInvalidArgument
);
962 if (!isA_SCNetworkInterface(interface
)) {
963 _SCErrorSet(kSCStatusInvalidArgument
);
967 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, FALSE
)) {
968 _SCErrorSet(kSCStatusInvalidArgument
);
972 // set new interface entity for SCUserPreferences
973 ok
= processPreferences(userPrivate
->serviceID
,
974 setInterfaceConfigurationCallout
,
975 (void *)userPrivate
->prefsID
,
976 (void *)extendedType
,
984 #pragma mark SCNetworkConnection + SCUserPreferences SPIs
987 static CFDictionaryRef
988 copyAllCallout(CFStringRef serviceID
,
989 CFDictionaryRef current
,
994 #pragma unused(context1)
995 #pragma unused(context2)
996 CFMutableArrayRef
*prefs
= (CFMutableArrayRef
*)context3
;
998 SCUserPreferencesPrivateRef userPrivate
;
1000 if (current
== NULL
) {
1001 // we have nothing to "add"
1005 prefsID
= CFDictionaryGetValue(current
, USER_PREFERENCES_ID
);
1006 if (!isA_CFString(prefsID
)) {
1011 userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, prefsID
);
1012 if (userPrivate
!= NULL
) {
1013 if (*prefs
== NULL
) {
1014 *prefs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1016 CFArrayAppendValue(*prefs
, (SCUserPreferencesRef
)userPrivate
);
1017 CFRelease(userPrivate
);
1022 return CFRetain(current
);
1026 CFArrayRef
/* of SCUserPreferencesRef's */
1027 SCNetworkConnectionCopyAllUserPreferences(SCNetworkConnectionRef connection
)
1030 CFMutableArrayRef prefs
= NULL
;
1031 CFStringRef serviceID
;
1034 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
1036 // collect SCUserPreferences
1037 ok
= processPreferences(serviceID
,
1043 if (prefs
!= NULL
) {
1049 CFRelease(serviceID
);
1054 static CFDictionaryRef
1055 copyCurrentCallout(CFStringRef serviceID
,
1056 CFDictionaryRef current
,
1061 #pragma unused(context1)
1062 #pragma unused(context2)
1063 CFBooleanRef isDefault
;
1064 CFStringRef prefsID
;
1065 SCUserPreferencesPrivateRef
*userPrivate
= (SCUserPreferencesPrivateRef
*)context3
;
1067 if (current
== NULL
) {
1068 // we have nothing to "add"
1072 prefsID
= CFDictionaryGetValue(current
, USER_PREFERENCES_ID
);
1073 if (!isA_CFString(prefsID
)) {
1078 isDefault
= CFDictionaryGetValue(current
, USER_PREFERENCES_DEFAULT
);
1079 if (!isA_CFBoolean(isDefault
) || !CFBooleanGetValue(isDefault
)) {
1080 // if not the default configuration
1084 *userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, prefsID
);
1088 return CFRetain(current
);
1092 SCUserPreferencesRef
1093 SCNetworkConnectionCopyCurrentUserPreferences(SCNetworkConnectionRef connection
)
1095 SCUserPreferencesRef current
= NULL
;
1097 CFStringRef serviceID
;
1100 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
1102 // collect SCUserPreferences
1103 ok
= processPreferences(serviceID
,
1109 if (current
!= NULL
) {
1115 CFRelease(serviceID
);
1120 static CFDictionaryRef
1121 createCallout(CFStringRef serviceID
,
1122 CFDictionaryRef current
,
1127 #pragma unused(serviceID)
1128 #pragma unused(context2)
1129 #pragma unused(context3)
1130 CFMutableDictionaryRef newDict
;
1131 CFStringRef newPrefsID
= (CFStringRef
)context1
;
1133 if (current
!= NULL
) {
1134 // don't change existing entries
1135 return CFRetain(current
);
1138 newDict
= CFDictionaryCreateMutable(NULL
,
1140 &kCFTypeDictionaryKeyCallBacks
,
1141 &kCFTypeDictionaryValueCallBacks
);
1142 CFDictionarySetValue(newDict
, USER_PREFERENCES_ID
, newPrefsID
);
1147 SCUserPreferencesRef
1148 SCNetworkConnectionCreateUserPreferences(SCNetworkConnectionRef connection
)
1150 CFStringRef newPrefsID
;
1151 CFStringRef serviceID
;
1152 SCUserPreferencesPrivateRef userPrivate
;
1156 serviceID
= SCNetworkConnectionCopyServiceID(connection
);
1158 // allocate a new user preferences ID
1159 uuid
= CFUUIDCreate(NULL
);
1160 newPrefsID
= CFUUIDCreateString(NULL
, uuid
);
1163 userPrivate
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, newPrefsID
);
1164 if (userPrivate
!= NULL
) {
1165 (void) processPreferences(serviceID
,
1172 CFRelease(newPrefsID
);
1173 CFRelease(serviceID
);
1174 return (SCUserPreferencesRef
)userPrivate
;
1179 update_PPP_entity(SCUserPreferencesRef userPreferences
, CFDictionaryRef
*userOptions
)
1181 CFStringRef encryption
;
1182 CFDictionaryRef entity
;
1183 CFStringRef keychainID
;
1185 entity
= CFDictionaryGetValue(*userOptions
, kSCEntNetPPP
);
1186 if (!isA_CFDictionary(entity
)) {
1190 encryption
= CFDictionaryGetValue(entity
, kSCPropNetPPPAuthPasswordEncryption
);
1191 if (encryption
== NULL
) {
1192 // provide default encryption method
1193 encryption
= kSCValNetPPPAuthPasswordEncryptionKeychain
;
1196 if (!isA_CFString(encryption
) ||
1197 !CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1201 keychainID
= CFDictionaryGetValue(entity
, kSCPropNetPPPAuthPassword
);
1202 if (isA_CFString(keychainID
)) {
1203 // if password is keychain ID
1204 } else if (isA_CFData(keychainID
) &&
1205 ((CFDataGetLength((CFDataRef
)keychainID
) % sizeof(UniChar
)) == 0)) {
1206 // if inline password
1209 keychainID
= SCUserPreferencesGetUniqueID(userPreferences
);
1212 if (_SCSecKeychainPasswordItemExists(NULL
, keychainID
)) {
1213 CFMutableDictionaryRef new_entity
;
1214 CFMutableDictionaryRef new_options
;
1216 // access PPP password from system keychain
1217 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1219 CFDictionarySetValue(new_entity
,
1220 kSCPropNetPPPAuthPassword
,
1222 CFDictionarySetValue(new_entity
,
1223 kSCPropNetPPPAuthPasswordEncryption
,
1224 kSCValNetPPPAuthPasswordEncryptionKeychain
);
1226 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1227 CFDictionarySetValue(new_options
, kSCEntNetPPP
, new_entity
);
1228 CFRelease(new_entity
);
1230 CFRelease(*userOptions
);
1231 *userOptions
= new_options
;
1239 update_IPSec_entity(SCUserPreferencesRef userPreferences
, CFDictionaryRef
*userOptions
)
1241 CFStringRef encryption
;
1242 CFDictionaryRef entity
;
1243 SecKeychainRef keychain
= NULL
;
1244 CFStringRef keychainID
;
1246 CFDataRef sharedSecret
;
1248 entity
= CFDictionaryGetValue(*userOptions
, kSCEntNetIPSec
);
1249 if (!isA_CFDictionary(entity
)) {
1253 method
= CFDictionaryGetValue(entity
, kSCPropNetIPSecAuthenticationMethod
);
1254 if (!isA_CFString(method
) ||
1255 !CFEqual(method
, kSCValNetIPSecAuthenticationMethodSharedSecret
)) {
1259 encryption
= CFDictionaryGetValue(entity
, kSCPropNetIPSecSharedSecretEncryption
);
1260 if (encryption
== NULL
) {
1261 // provide default encryption method
1262 encryption
= kSCValNetIPSecSharedSecretEncryptionKeychain
;
1265 if (!isA_CFString(encryption
) ||
1266 !CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1270 keychainID
= CFDictionaryGetValue(entity
, kSCPropNetIPSecSharedSecret
);
1271 if (isA_CFString(keychainID
)) {
1272 // if shared secret is keychain ID
1273 CFRetain(keychainID
);
1274 } else if (isA_CFData(keychainID
) &&
1275 ((CFDataGetLength((CFDataRef
)keychainID
) % sizeof(UniChar
)) == 0)) {
1276 // if inline shared secret
1279 CFStringRef unique_id
;
1281 unique_id
= SCUserPreferencesGetUniqueID(userPreferences
);
1282 keychainID
= (CFStringRef
)CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1283 CFStringAppend((CFMutableStringRef
)keychainID
, CFSTR(".SS"));
1286 sharedSecret
= _SCSecKeychainPasswordItemCopy(NULL
, keychainID
);
1287 if (sharedSecret
!= NULL
) {
1288 CFMutableDictionaryRef new_entity
;
1289 CFMutableDictionaryRef new_options
;
1290 CFStringRef password
;
1292 // pass SharedSecret from user keychain
1293 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1295 password
= CFStringCreateWithBytes(NULL
,
1296 CFDataGetBytePtr(sharedSecret
),
1297 CFDataGetLength(sharedSecret
),
1298 kCFStringEncodingUTF8
,
1300 CFRelease(sharedSecret
);
1301 CFDictionarySetValue(new_entity
,
1302 kSCPropNetIPSecSharedSecret
,
1304 CFRelease(password
);
1305 CFDictionaryRemoveValue(new_entity
,
1306 kSCPropNetIPSecSharedSecretEncryption
);
1308 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1309 CFDictionarySetValue(new_options
, kSCEntNetIPSec
, new_entity
);
1310 CFRelease(new_entity
);
1312 CFRelease(*userOptions
);
1313 *userOptions
= new_options
;
1317 keychain
= _SCSecKeychainCopySystemKeychain();
1318 if (keychain
== NULL
) {
1322 if (_SCSecKeychainPasswordItemExists(keychain
, keychainID
)) {
1323 CFMutableDictionaryRef new_entity
;
1324 CFMutableDictionaryRef new_options
;
1326 // access SharedSecret from system keychain
1327 new_entity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1329 CFDictionarySetValue(new_entity
,
1330 kSCPropNetIPSecSharedSecret
,
1332 CFDictionarySetValue(new_entity
,
1333 kSCPropNetIPSecSharedSecretEncryption
,
1334 kSCValNetIPSecSharedSecretEncryptionKeychain
);
1336 new_options
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
);
1337 CFDictionarySetValue(new_options
, kSCEntNetIPSec
, new_entity
);
1338 CFRelease(new_entity
);
1340 CFRelease(*userOptions
);
1341 *userOptions
= new_options
;
1346 if (keychain
!= NULL
) CFRelease(keychain
);
1347 CFRelease(keychainID
);
1352 static CFDictionaryRef
1353 copyOptionsCallout(CFStringRef serviceID
,
1354 CFDictionaryRef current
,
1359 #pragma unused(serviceID)
1360 #pragma unused(context2)
1361 CFStringRef matchID
= (CFStringRef
)context1
;
1362 CFMutableDictionaryRef
*userOptions
= (CFMutableDictionaryRef
*)context3
;
1364 if (current
== NULL
) {
1365 // we have nothing to "add"
1369 if (isMatchingPrefsID(current
, matchID
)) {
1370 // if we match, return options dictionary
1371 if (*userOptions
!= NULL
) CFRelease(*userOptions
);
1372 *userOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, current
);
1373 CFDictionaryRemoveValue(*userOptions
, USER_PREFERENCES_ID
);
1374 CFDictionaryRemoveValue(*userOptions
, USER_PREFERENCES_DEFAULT
);
1377 return CFRetain(current
);
1382 SCNetworkConnectionStartWithUserPreferences(SCNetworkConnectionRef connection
,
1383 SCUserPreferencesRef userPreferences
,
1387 CFDictionaryRef userOptions
= NULL
;
1388 SCUserPreferencesPrivateRef userPrivate
= (SCUserPreferencesPrivateRef
)userPreferences
;
1390 if (!isA_SCUserPreferences(userPreferences
)) {
1391 _SCErrorSet(kSCStatusInvalidArgument
);
1395 (void) processPreferences(userPrivate
->serviceID
,
1397 (void *)userPrivate
->prefsID
,
1402 * For some legacy preferences, some of the user options
1403 * were missing yet handled by the APIs. Make sure that
1404 * everything still works!
1406 if (userOptions
!= NULL
) {
1407 update_PPP_entity (userPreferences
, &userOptions
);
1408 update_IPSec_entity(userPreferences
, &userOptions
);
1411 ok
= SCNetworkConnectionStart(connection
, userOptions
, linger
);
1413 if (userOptions
!= NULL
) {
1414 CFRelease(userOptions
);
1422 #pragma mark SCUserPreferences + SCNetworkInterface Password SPIs
1426 getUserPasswordID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1428 CFStringRef unique_id
= NULL
;
1430 if (config
!= NULL
) {
1431 CFStringRef encryption
;
1433 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
1434 if (isA_CFString(encryption
) &&
1435 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1436 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
1439 if (unique_id
== NULL
) {
1440 unique_id
= SCUserPreferencesGetUniqueID(userPreferences
);
1448 copyUserSharedSecretID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1450 CFMutableStringRef sharedSecret
= NULL
;
1452 if (config
!= NULL
) {
1453 CFStringRef encryption
;
1455 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
1456 if (isA_CFString(encryption
) &&
1457 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1458 sharedSecret
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
1459 if (sharedSecret
!= NULL
) {
1460 CFRetain(sharedSecret
);
1465 if (sharedSecret
== NULL
) {
1466 CFStringRef unique_id
;
1468 unique_id
= getUserPasswordID(config
, userPreferences
);
1469 sharedSecret
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1470 CFStringAppend(sharedSecret
, CFSTR(".SS"));
1473 return sharedSecret
;
1478 copyUserXAuthID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
)
1480 CFMutableStringRef xauth_id
= NULL
;
1482 if (config
!= NULL
) {
1483 CFStringRef encryption
;
1485 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
1486 if (isA_CFString(encryption
) &&
1487 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
1488 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
1489 if (xauth_id
!= NULL
) {
1495 if (xauth_id
== NULL
) {
1496 CFStringRef unique_id
;
1498 unique_id
= getUserPasswordID(config
, userPreferences
);
1499 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
1500 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
1508 checkUserPreferencesPassword(SCUserPreferencesRef userPreferences
,
1509 SCNetworkInterfaceRef interface
,
1510 SCNetworkInterfacePasswordType passwordType
)
1512 if (!isA_SCUserPreferences(userPreferences
)) {
1513 _SCErrorSet(kSCStatusInvalidArgument
);
1517 if (!isA_SCNetworkInterface(interface
)) {
1518 _SCErrorSet(kSCStatusInvalidArgument
);
1522 switch (passwordType
) {
1523 case kSCNetworkInterfacePasswordTypePPP
: {
1524 CFStringRef interfaceType
;
1526 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1527 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1528 _SCErrorSet(kSCStatusInvalidArgument
);
1534 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1535 CFStringRef interfaceType
;
1537 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1538 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1539 _SCErrorSet(kSCStatusInvalidArgument
);
1543 interface
= SCNetworkInterfaceGetInterface(interface
);
1544 if (interface
== NULL
) {
1545 _SCErrorSet(kSCStatusInvalidArgument
);
1549 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1550 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
1551 _SCErrorSet(kSCStatusInvalidArgument
);
1557 case kSCNetworkInterfacePasswordTypeEAPOL
: {
1558 _SCErrorSet(kSCStatusInvalidArgument
);
1562 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1563 CFStringRef interfaceType
;
1565 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1566 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
1567 _SCErrorSet(kSCStatusInvalidArgument
);
1573 case kSCNetworkInterfacePasswordTypeVPN
: {
1574 CFStringRef interfaceType
;
1576 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1577 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
1578 _SCErrorSet(kSCStatusInvalidArgument
);
1593 SCUserPreferencesCheckInterfacePassword(SCUserPreferencesRef userPreferences
,
1594 SCNetworkInterfaceRef interface
,
1595 SCNetworkInterfacePasswordType passwordType
)
1597 Boolean exists
= FALSE
;
1599 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1603 switch (passwordType
) {
1604 case kSCNetworkInterfacePasswordTypePPP
: {
1605 CFDictionaryRef config
;
1606 CFStringRef unique_id
;
1608 // get configuration
1609 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1611 // get userPreferences ID
1612 unique_id
= getUserPasswordID(config
, userPreferences
);
1615 exists
= __extract_password(NULL
,
1617 kSCPropNetPPPAuthPassword
,
1618 kSCPropNetPPPAuthPasswordEncryption
,
1619 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1623 if (config
!= NULL
) CFRelease(config
);
1627 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1628 CFDictionaryRef config
;
1629 CFStringRef shared_id
;
1631 // get configuration
1632 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1636 // get sharedSecret ID
1637 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1640 exists
= __extract_password(NULL
,
1642 kSCPropNetIPSecSharedSecret
,
1643 kSCPropNetIPSecSharedSecretEncryption
,
1644 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1648 if (config
!= NULL
) CFRelease(config
);
1649 CFRelease(shared_id
);
1653 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1654 CFDictionaryRef config
;
1655 CFStringRef xauth_id
;
1657 // get configuration
1658 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1661 xauth_id
= copyUserXAuthID(config
, userPreferences
);
1664 exists
= __extract_password(NULL
,
1666 kSCPropNetIPSecXAuthPassword
,
1667 kSCPropNetIPSecXAuthPasswordEncryption
,
1668 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
1672 if (config
!= NULL
) CFRelease(config
);
1673 CFRelease(xauth_id
);
1677 case kSCNetworkInterfacePasswordTypeVPN
: {
1678 CFDictionaryRef config
;
1679 CFStringRef unique_id
;
1681 // get configuration
1682 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1684 // get userPreferences ID
1685 unique_id
= getUserPasswordID(config
, userPreferences
);
1688 exists
= __extract_password(NULL
,
1690 kSCPropNetVPNAuthPassword
,
1691 kSCPropNetVPNAuthPasswordEncryption
,
1692 kSCValNetVPNAuthPasswordEncryptionKeychain
,
1696 if (config
!= NULL
) CFRelease(config
);
1701 _SCErrorSet(kSCStatusInvalidArgument
);
1710 SCUserPreferencesCopyInterfacePassword(SCUserPreferencesRef userPreferences
,
1711 SCNetworkInterfaceRef interface
,
1712 SCNetworkInterfacePasswordType passwordType
)
1714 CFDataRef password
= NULL
;
1716 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1720 switch (passwordType
) {
1721 case kSCNetworkInterfacePasswordTypePPP
: {
1722 CFDictionaryRef config
;
1723 CFStringRef unique_id
;
1725 // get configuration
1726 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1728 // get userPreferences ID
1729 unique_id
= getUserPasswordID(config
, userPreferences
);
1732 (void) __extract_password(NULL
,
1734 kSCPropNetPPPAuthPassword
,
1735 kSCPropNetPPPAuthPasswordEncryption
,
1736 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1740 if (config
!= NULL
) CFRelease(config
);
1744 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1745 CFDictionaryRef config
;
1746 CFStringRef shared_id
;
1748 // get configuration
1749 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1753 // get sharedSecret ID
1754 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1757 (void) __extract_password(NULL
,
1759 kSCPropNetIPSecSharedSecret
,
1760 kSCPropNetIPSecSharedSecretEncryption
,
1761 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1765 if (config
!= NULL
) CFRelease(config
);
1766 CFRelease(shared_id
);
1770 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1771 CFDictionaryRef config
;
1772 CFStringRef xauth_id
;
1774 // get configuration
1775 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1778 xauth_id
= copyUserXAuthID(config
, userPreferences
);
1781 (void) __extract_password(NULL
,
1783 kSCPropNetIPSecXAuthPassword
,
1784 kSCPropNetIPSecXAuthPasswordEncryption
,
1785 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
1789 if (config
!= NULL
) CFRelease(config
);
1790 CFRelease(xauth_id
);
1794 case kSCNetworkInterfacePasswordTypeVPN
: {
1795 CFDictionaryRef config
;
1796 CFStringRef unique_id
;
1798 // get configuration
1799 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1801 // get userPreferences ID
1802 unique_id
= getUserPasswordID(config
, userPreferences
);
1805 (void) __extract_password(NULL
,
1807 kSCPropNetVPNAuthPassword
,
1808 kSCPropNetVPNAuthPasswordEncryption
,
1809 kSCValNetVPNAuthPasswordEncryptionKeychain
,
1813 if (config
!= NULL
) CFRelease(config
);
1818 _SCErrorSet(kSCStatusInvalidArgument
);
1827 SCUserPreferencesRemoveInterfacePassword(SCUserPreferencesRef userPreferences
,
1828 SCNetworkInterfaceRef interface
,
1829 SCNetworkInterfacePasswordType passwordType
)
1833 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1837 switch (passwordType
) {
1838 case kSCNetworkInterfacePasswordTypePPP
: {
1839 CFDictionaryRef config
;
1840 CFDictionaryRef newConfig
= NULL
;
1841 CFStringRef unique_id
;
1843 // get configuration
1844 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1846 // get userPreferences ID
1847 unique_id
= getUserPasswordID(config
, userPreferences
);
1850 ok
= __remove_password(NULL
,
1852 kSCPropNetPPPAuthPassword
,
1853 kSCPropNetPPPAuthPasswordEncryption
,
1854 kSCValNetPPPAuthPasswordEncryptionKeychain
,
1858 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1859 if (newConfig
!= NULL
) CFRelease(newConfig
);
1862 if (config
!= NULL
) CFRelease(config
);
1866 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
1867 CFDictionaryRef config
;
1868 CFDictionaryRef newConfig
= NULL
;
1869 CFStringRef shared_id
;
1871 // get configuration
1872 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
1876 // get sharedSecret ID
1877 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
1880 ok
= __remove_password(NULL
,
1882 kSCPropNetIPSecSharedSecret
,
1883 kSCPropNetIPSecSharedSecretEncryption
,
1884 kSCValNetIPSecSharedSecretEncryptionKeychain
,
1888 ok
= SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences
,
1892 if (newConfig
!= NULL
) CFRelease(newConfig
);
1895 if (config
!= NULL
) CFRelease(config
);
1896 CFRelease(shared_id
);
1900 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
1901 CFDictionaryRef config
;
1902 CFDictionaryRef newConfig
= NULL
;
1903 CFStringRef xauth_id
;
1905 // get configuration
1906 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1909 xauth_id
= copyUserXAuthID(config
, userPreferences
);
1912 ok
= __remove_password(NULL
,
1914 kSCPropNetIPSecXAuthPassword
,
1915 kSCPropNetIPSecXAuthPasswordEncryption
,
1916 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
1920 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1921 if (newConfig
!= NULL
) CFRelease(newConfig
);
1924 if (config
!= NULL
) CFRelease(config
);
1925 CFRelease(xauth_id
);
1929 case kSCNetworkInterfacePasswordTypeVPN
: {
1930 CFDictionaryRef config
;
1931 CFDictionaryRef newConfig
= NULL
;
1932 CFStringRef unique_id
;
1934 // get configuration
1935 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1937 // get userPreferences ID
1938 unique_id
= getUserPasswordID(config
, userPreferences
);
1941 ok
= __remove_password(NULL
,
1943 kSCPropNetVPNAuthPassword
,
1944 kSCPropNetVPNAuthPasswordEncryption
,
1945 kSCValNetVPNAuthPasswordEncryptionKeychain
,
1949 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
1950 if (newConfig
!= NULL
) CFRelease(newConfig
);
1953 if (config
!= NULL
) CFRelease(config
);
1958 _SCErrorSet(kSCStatusInvalidArgument
);
1967 SCUserPreferencesSetInterfacePassword(SCUserPreferencesRef userPreferences
,
1968 SCNetworkInterfaceRef interface
,
1969 SCNetworkInterfacePasswordType passwordType
,
1971 CFDictionaryRef options
)
1973 CFStringRef account
= NULL
;
1975 CFDictionaryRef config
;
1976 CFStringRef description
= NULL
;
1977 CFStringRef label
= NULL
;
1980 if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) {
1984 bundle
= _SC_CFBundleGet();
1986 switch (passwordType
) {
1987 case kSCNetworkInterfacePasswordTypePPP
: {
1988 CFStringRef unique_id
;
1990 // get configuration
1991 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
1993 // get userPreferences ID
1994 unique_id
= getUserPasswordID(config
, userPreferences
);
1996 // User prefs auth name --> keychain "Account"
1997 if (config
!= NULL
) {
1998 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
2001 // User prefs "name" --> keychain "Name"
2002 label
= SCUserPreferencesCopyName(userPreferences
);
2004 // "PPP Password" --> keychain "Kind"
2005 if (bundle
!= NULL
) {
2006 description
= CFBundleCopyLocalizedString(bundle
,
2007 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
2008 CFSTR("PPP Password"),
2013 ok
= _SCSecKeychainPasswordItemSet(NULL
,
2015 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
2016 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
2021 CFMutableDictionaryRef newConfig
;
2023 if (config
!= NULL
) {
2024 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
2026 newConfig
= CFDictionaryCreateMutable(NULL
,
2028 &kCFTypeDictionaryKeyCallBacks
,
2029 &kCFTypeDictionaryValueCallBacks
);
2031 CFDictionarySetValue(newConfig
,
2032 kSCPropNetPPPAuthPassword
,
2034 CFDictionarySetValue(newConfig
,
2035 kSCPropNetPPPAuthPasswordEncryption
,
2036 kSCValNetPPPAuthPasswordEncryptionKeychain
);
2037 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
2038 CFRelease(newConfig
);
2041 if (config
!= NULL
) CFRelease(config
);
2042 if (description
!= NULL
) CFRelease(description
);
2043 if (label
!= NULL
) CFRelease(label
);
2047 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
2048 CFStringRef shared_id
;
2050 // get configuration
2051 config
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
,
2055 // get sharedSecret ID
2056 shared_id
= copyUserSharedSecretID(config
, userPreferences
);
2058 // User prefs "name" --> keychain "Name"
2059 label
= SCUserPreferencesCopyName(userPreferences
);
2061 // "IPSec Shared Secret" --> keychain "Kind"
2062 if (bundle
!= NULL
) {
2063 description
= CFBundleCopyLocalizedString(bundle
,
2064 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
2065 CFSTR("IPSec Shared Secret"),
2070 ok
= _SCSecKeychainPasswordItemSet(NULL
,
2072 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
2073 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
2078 CFMutableDictionaryRef newConfig
= NULL
;
2080 if (config
!= NULL
) {
2081 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
2083 newConfig
= CFDictionaryCreateMutable(NULL
,
2085 &kCFTypeDictionaryKeyCallBacks
,
2086 &kCFTypeDictionaryValueCallBacks
);
2088 CFDictionarySetValue(newConfig
,
2089 kSCPropNetIPSecSharedSecret
,
2091 CFDictionarySetValue(newConfig
,
2092 kSCPropNetIPSecSharedSecretEncryption
,
2093 kSCValNetIPSecSharedSecretEncryptionKeychain
);
2094 ok
= SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences
,
2098 CFRelease(newConfig
);
2101 if (config
!= NULL
) CFRelease(config
);
2102 if (description
!= NULL
) CFRelease(description
);
2103 if (label
!= NULL
) CFRelease(label
);
2104 CFRelease(shared_id
);
2108 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
2109 CFStringRef xauth_id
;
2111 // get configuration
2112 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
2115 xauth_id
= copyUserXAuthID(config
, userPreferences
);
2117 // User prefs XAuth name --> keychain "Account"
2118 if (config
!= NULL
) {
2119 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
2122 // User prefs "name" --> keychain "Name"
2123 label
= SCUserPreferencesCopyName(userPreferences
);
2125 // "IPSec XAuth Password" --> keychain "Kind"
2126 if (bundle
!= NULL
) {
2127 description
= CFBundleCopyLocalizedString(bundle
,
2128 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
2129 CFSTR("IPSec XAuth Password"),
2134 ok
= _SCSecKeychainPasswordItemSet(NULL
,
2136 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
2137 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
2142 CFMutableDictionaryRef newConfig
;
2144 if (config
!= NULL
) {
2145 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
2147 newConfig
= CFDictionaryCreateMutable(NULL
,
2149 &kCFTypeDictionaryKeyCallBacks
,
2150 &kCFTypeDictionaryValueCallBacks
);
2152 CFDictionarySetValue(newConfig
,
2153 kSCPropNetIPSecXAuthPassword
,
2155 CFDictionarySetValue(newConfig
,
2156 kSCPropNetIPSecXAuthPasswordEncryption
,
2157 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
2158 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
2159 CFRelease(newConfig
);
2162 if (config
!= NULL
) CFRelease(config
);
2163 if (description
!= NULL
) CFRelease(description
);
2164 if (label
!= NULL
) CFRelease(label
);
2165 CFRelease(xauth_id
);
2169 case kSCNetworkInterfacePasswordTypeVPN
: {
2170 CFStringRef unique_id
;
2172 // get configuration
2173 config
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
);
2175 // get userPreferences ID
2176 unique_id
= getUserPasswordID(config
, userPreferences
);
2178 // User prefs auth name --> keychain "Account"
2179 if (config
!= NULL
) {
2180 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
2183 // User prefs "name" --> keychain "Name"
2184 label
= SCUserPreferencesCopyName(userPreferences
);
2186 // "VPN Password" --> keychain "Kind"
2187 if (bundle
!= NULL
) {
2188 description
= CFBundleCopyLocalizedString(bundle
,
2189 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
2190 CFSTR("VPN Password"),
2195 ok
= _SCSecKeychainPasswordItemSet(NULL
,
2197 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
2198 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
2203 CFMutableDictionaryRef newConfig
;
2205 if (config
!= NULL
) {
2206 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
2208 newConfig
= CFDictionaryCreateMutable(NULL
,
2210 &kCFTypeDictionaryKeyCallBacks
,
2211 &kCFTypeDictionaryValueCallBacks
);
2213 assert(newConfig
!= NULL
);
2214 CFDictionarySetValue(newConfig
,
2215 kSCPropNetVPNAuthPassword
,
2217 CFDictionarySetValue(newConfig
,
2218 kSCPropNetVPNAuthPasswordEncryption
,
2219 kSCValNetVPNAuthPasswordEncryptionKeychain
);
2220 ok
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
);
2221 CFRelease(newConfig
);
2224 if (config
!= NULL
) CFRelease(config
);
2225 if (description
!= NULL
) CFRelease(description
);
2226 if (label
!= NULL
) CFRelease(label
);
2231 _SCErrorSet(kSCStatusInvalidArgument
);