2  * Copyright (c) 2006-2012, 2015 Apple Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  24 #include <CoreFoundation/CoreFoundation.h> 
  25 #include <CoreFoundation/CFRuntime.h> 
  26 #include <SystemConfiguration/SystemConfiguration.h> 
  27 #include <SystemConfiguration/SCPrivate.h>              // for SCLog 
  28 #include "SCNetworkConfigurationInternal.h" 
  34 #pragma mark SCUserPreferences 
  39         // base CFType information 
  43         CFStringRef             serviceID
; 
  45         // user preferences [unique] id 
  48 } SCUserPreferencesPrivate
, *SCUserPreferencesPrivateRef
; 
  51 static CFStringRef      
__SCUserPreferencesCopyDescription      (CFTypeRef cf
); 
  52 static void             __SCUserPreferencesDeallocate           (CFTypeRef cf
); 
  53 static Boolean          
__SCUserPreferencesEqual                (CFTypeRef cf1
, CFTypeRef cf2
); 
  54 static CFHashCode       
__SCUserPreferencesHash                 (CFTypeRef cf
); 
  57 static CFTypeID __kSCUserPreferencesTypeID      
= _kCFRuntimeNotATypeID
; 
  60 static const CFRuntimeClass __SCUserPreferencesClass 
= { 
  62         "SCUserPreferences",                    // className 
  65         __SCUserPreferencesDeallocate
,          // dealloc 
  66         __SCUserPreferencesEqual
,               // equal 
  67         __SCUserPreferencesHash
,                // hash 
  68         NULL
,                                   // copyFormattingDesc 
  69         __SCUserPreferencesCopyDescription      
// copyDebugDesc 
  73 static pthread_once_t           initialized     
= PTHREAD_ONCE_INIT
; 
  77 __SCUserPreferencesCopyDescription(CFTypeRef cf
) 
  79         CFAllocatorRef                  allocator       
= CFGetAllocator(cf
); 
  80         CFMutableStringRef              result
; 
  81         SCUserPreferencesPrivateRef     prefsPrivate    
= (SCUserPreferencesPrivateRef
)cf
; 
  83         result 
= CFStringCreateMutable(allocator
, 0); 
  84         CFStringAppendFormat(result
, NULL
, CFSTR("<SCUserPreferences %p [%p]> {"), cf
, allocator
); 
  85         CFStringAppendFormat(result
, NULL
, CFSTR("service = %@"), prefsPrivate
->serviceID
); 
  86         CFStringAppendFormat(result
, NULL
, CFSTR(", id = %@"), prefsPrivate
->prefsID
); 
  87         CFStringAppendFormat(result
, NULL
, CFSTR("}")); 
  94 __SCUserPreferencesDeallocate(CFTypeRef cf
) 
  96         SCUserPreferencesPrivateRef     prefsPrivate    
= (SCUserPreferencesPrivateRef
)cf
; 
  98         /* release resources */ 
 100         CFRelease(prefsPrivate
->prefsID
); 
 101         CFRelease(prefsPrivate
->serviceID
); 
 108 __SCUserPreferencesEqual(CFTypeRef cf1
, CFTypeRef cf2
) 
 110         SCUserPreferencesPrivateRef     s1      
= (SCUserPreferencesPrivateRef
)cf1
; 
 111         SCUserPreferencesPrivateRef     s2      
= (SCUserPreferencesPrivateRef
)cf2
; 
 116         if (!CFEqual(s1
->prefsID
, s2
->prefsID
)) 
 117                 return FALSE
;   // if not the same [unique] prefs identifier 
 124 __SCUserPreferencesHash(CFTypeRef cf
) 
 126         SCUserPreferencesPrivateRef     prefsPrivate    
= (SCUserPreferencesPrivateRef
)cf
; 
 128         return CFHash(prefsPrivate
->prefsID
); 
 133 __SCUserPreferencesInitialize(void) 
 135         __kSCUserPreferencesTypeID 
= _CFRuntimeRegisterClass(&__SCUserPreferencesClass
); 
 140 static SCUserPreferencesPrivateRef
 
 141 __SCUserPreferencesCreatePrivate(CFAllocatorRef         allocator
, 
 142                                  CFStringRef            serviceID
, 
 145         SCUserPreferencesPrivateRef     prefsPrivate
; 
 148         /* initialize runtime */ 
 149         pthread_once(&initialized
, __SCUserPreferencesInitialize
); 
 151         /* allocate target */ 
 152         size         
= sizeof(SCUserPreferencesPrivate
) - sizeof(CFRuntimeBase
); 
 153         prefsPrivate 
= (SCUserPreferencesPrivateRef
)_CFRuntimeCreateInstance(allocator
, 
 154                                                                              __kSCUserPreferencesTypeID
, 
 157         if (prefsPrivate 
== NULL
) { 
 161         prefsPrivate
->serviceID 
= CFStringCreateCopy(NULL
, serviceID
); 
 162         prefsPrivate
->prefsID   
= CFStringCreateCopy(NULL
, prefsID
); 
 168 static __inline__ CFTypeRef
 
 169 isA_SCUserPreferences(CFTypeRef obj
) 
 171         return (isA_CFType(obj
, SCUserPreferencesGetTypeID())); 
 176 #pragma mark SCUserPreferences SPIs 
 179 #define USER_PREFERENCES_NOTIFICATION   "com.apple.networkConnect" 
 180 #define USER_PREFERENCES_APPLICATION_ID CFSTR("com.apple.networkConnect") 
 181 #define USER_PREFERENCES_ID             CFSTR("UniqueIdentifier") 
 182 #define USER_PREFERENCES_DEFAULT        CFSTR("ConnectByDefault") 
 185 #define LOG_CFPREFERENCES_CHANGES 
 186 #ifdef  LOG_CFPREFERENCES_CHANGES 
 189 #include <sys/stat.h> 
 190 #include <sys/time.h> 
 192 logCFPreferencesChange(CFStringRef serviceID
, CFArrayRef newPreferences
) 
 196         CFArrayRef      oldPreferences
; 
 200         struct timeval  tv_now
; 
 202         bVal 
= CFPreferencesCopyAppValue(CFSTR("LOG_SC_CHANGES"), USER_PREFERENCES_APPLICATION_ID
); 
 206                 enabled 
= isA_CFBoolean(bVal
) && CFBooleanGetValue(bVal
); 
 209                         // if debugging not enabled 
 213                 // if debugging not enabled 
 217         (void)gettimeofday(&tv_now
, NULL
); 
 218         (void)localtime_r(&tv_now
.tv_sec
, &tm_now
); 
 220         str 
= CFStringCreateWithFormat(NULL
, NULL
, 
 221                                        CFSTR("/var/tmp/com.apple.networkConnect-%@-%4d%02d%02d.%02d%02d%02d.%03d"), 
 223                                        tm_now
.tm_year 
+ 1900, 
 229                                        tv_now
.tv_usec 
/ 1000); 
 230         _SC_cfstring_to_cstring(str
, dir
, sizeof(dir
), kCFStringEncodingUTF8
); 
 233         SC_log(LOG_NOTICE
, "CFPreferences being updated, old/new in \"%s\"", dir
); 
 235         if (mkdir(dir
, 0755) == -1) { 
 236                 SC_log(LOG_NOTICE
, "mkdir() failed: %s", SCErrorString(errno
)); 
 240         trace 
= _SC_copyBacktrace(); 
 246                 strlcpy(path
, dir
, sizeof(path
)); 
 247                 strlcat(path
, "/backtrace", sizeof(path
)); 
 248                 fd 
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644); 
 250                         SC_log(LOG_NOTICE
, "fopen() failed: %s", SCErrorString(errno
)); 
 255                 SCPrint(TRUE
, f
, CFSTR("%@"), trace
); 
 260         oldPreferences 
= CFPreferencesCopyAppValue(serviceID
, USER_PREFERENCES_APPLICATION_ID
); 
 261         if (oldPreferences 
!= NULL
) { 
 266                 strlcpy(path
, dir
, sizeof(path
)); 
 267                 strlcat(path
, "/old", sizeof(path
)); 
 268                 fd 
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644); 
 270                         SC_log(LOG_NOTICE
, "fopen() failed: %s", SCErrorString(errno
)); 
 271                         CFRelease(oldPreferences
); 
 274                 data 
= CFPropertyListCreateData(NULL
, oldPreferences
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
); 
 276                         SC_log(LOG_NOTICE
, "CFPropertyListCreateData() failed"); 
 278                         CFRelease(oldPreferences
); 
 281                 (void) write(fd
, CFDataGetBytePtr(data
), CFDataGetLength(data
)); 
 284                 CFRelease(oldPreferences
); 
 287         if (newPreferences 
!= NULL
) { 
 292                 strlcpy(path
, dir
, sizeof(path
)); 
 293                 strlcat(path
, "/new", sizeof(path
)); 
 294                 fd 
= open(path
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644); 
 296                         SC_log(LOG_NOTICE
, "fopen() failed: %s", SCErrorString(errno
)); 
 299                 data 
= CFPropertyListCreateData(NULL
, newPreferences
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
); 
 301                         SC_log(LOG_NOTICE
, "CFPropertyListCreateData() failed"); 
 305                 (void) write(fd
, CFDataGetBytePtr(data
), CFDataGetLength(data
)); 
 312 #endif  // LOG_CFPREFERENCES_CHANGES 
 316 copyCFPreferencesForServiceID(CFStringRef serviceID
) 
 320         // fetch "Managed" or "ByHost" user preferences 
 321         (void) CFPreferencesAppSynchronize(USER_PREFERENCES_APPLICATION_ID
); 
 322         prefs 
= CFPreferencesCopyAppValue(serviceID
, 
 323                                           USER_PREFERENCES_APPLICATION_ID
); 
 325         if ((prefs 
!= NULL
) && !isA_CFArray(prefs
)) { 
 335 setCFPreferencesForServiceID(CFStringRef serviceID
, CFArrayRef newPreferences
) 
 339         if (CFPreferencesAppValueIsForced(serviceID
, USER_PREFERENCES_APPLICATION_ID
)) { 
 343 #ifdef  LOG_CFPREFERENCES_CHANGES 
 344         logCFPreferencesChange(serviceID
, newPreferences
); 
 345 #endif  // LOG_CFPREFERENCES_CHANGES 
 347         CFPreferencesSetValue(serviceID
, 
 349                               USER_PREFERENCES_APPLICATION_ID
, 
 350                               kCFPreferencesCurrentUser
, 
 351                               kCFPreferencesCurrentHost
); 
 352         ok 
= CFPreferencesSynchronize(USER_PREFERENCES_APPLICATION_ID
, 
 353                                       kCFPreferencesCurrentUser
, 
 354                                       kCFPreferencesCurrentHost
); 
 356         (void) notify_post(USER_PREFERENCES_NOTIFICATION
); 
 363 addPreference(CFMutableArrayRef 
*newPrefs
, CFDictionaryRef newDict
) 
 365         if (*newPrefs 
== NULL
) { 
 366                 *newPrefs 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 368         CFArrayAppendValue(*newPrefs
, newDict
); 
 374 typedef CFDictionaryRef (*processPreferencesCallout
)    (CFStringRef            serviceID
, 
 375                                                          CFDictionaryRef        current
, 
 382 processPreferences(CFStringRef                  serviceID
, 
 383                    processPreferencesCallout    callout
, 
 388         Boolean                         changed         
= FALSE
; 
 391         CFDictionaryRef                 newDict         
= NULL
; 
 392         CFMutableArrayRef               newPrefs        
= NULL
; 
 396         prefs 
= copyCFPreferencesForServiceID(serviceID
); 
 397         n 
= (prefs 
!= NULL
) ? CFArrayGetCount(prefs
) : 0; 
 398         for (i 
= 0; i 
< n
; i
++) { 
 399                 CFDictionaryRef dict
; 
 401                 dict 
= CFArrayGetValueAtIndex(prefs
, i
); 
 402                 assert(dict 
!= NULL
); 
 403                 if (isA_CFDictionary(dict
)) { 
 404                         newDict 
= (*callout
)(serviceID
, dict
, context1
, context2
, context3
); 
 405                         if (newDict 
== NULL
) { 
 406                                 // if entry to be removed 
 411                         // if not a CFDictionary, leave as-is 
 412                         newDict 
= CFRetain(dict
); 
 415                 if (!CFEqual(dict
, newDict
)) { 
 419                 addPreference(&newPrefs
, newDict
); 
 422         if (prefs 
!= NULL
) CFRelease(prefs
); 
 424         newDict 
= (*callout
)(serviceID
, NULL
, context1
, context2
, context3
); 
 425         if (newDict 
!= NULL
) { 
 428                 addPreference(&newPrefs
, newDict
); 
 433                 ok 
= setCFPreferencesForServiceID(serviceID
, newPrefs
); 
 435         if (newPrefs 
!= NULL
) CFRelease(newPrefs
); 
 441 static __inline__ Boolean
 
 442 isMatchingPrefsID(CFDictionaryRef dict
, CFStringRef matchID
) 
 446         prefsID 
= CFDictionaryGetValue(dict
, USER_PREFERENCES_ID
); 
 447         if (isA_CFString(prefsID
)) { 
 448                 if (CFEqual(prefsID
, matchID
)) { 
 458 SCUserPreferencesGetTypeID(void) 
 460         pthread_once(&initialized
, __SCUserPreferencesInitialize
);      /* initialize runtime */ 
 461         return __kSCUserPreferencesTypeID
; 
 466 SCUserPreferencesGetUniqueID(SCUserPreferencesRef userPreferences
) 
 468         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
 470         if (!isA_SCUserPreferences(userPreferences
)) { 
 471                 _SCErrorSet(kSCStatusInvalidArgument
); 
 475         return userPrivate
->prefsID
; 
 480 SCUserPreferencesIsForced(SCUserPreferencesRef userPreferences
) 
 482         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
 484         if (!isA_SCUserPreferences(userPreferences
)) { 
 485                 _SCErrorSet(kSCStatusInvalidArgument
); 
 489         return CFPreferencesAppValueIsForced(userPrivate
->serviceID
, USER_PREFERENCES_APPLICATION_ID
); 
 493 static CFDictionaryRef
 
 494 removeCallout(CFStringRef       serviceID
, 
 495               CFDictionaryRef   current
, 
 500         CFStringRef     matchID 
= (CFStringRef
)context1
; 
 502         if (current 
== NULL
) { 
 503                 // we have nothing to "add" 
 507         if (isMatchingPrefsID(current
, matchID
)) { 
 508                 // if we match, don't add (i.e. remove) 
 512         return CFRetain(current
); 
 517 SCUserPreferencesRemove(SCUserPreferencesRef userPreferences
) 
 519         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
 521         if (!isA_SCUserPreferences(userPreferences
)) { 
 522                 _SCErrorSet(kSCStatusInvalidArgument
); 
 526         return processPreferences(userPrivate
->serviceID
, 
 528                                   (void *)userPrivate
->prefsID
, 
 534 static CF_RETURNS_RETAINED CFDictionaryRef
 
 535 setCurrentCallout(CFStringRef           serviceID
, 
 536                   CFDictionaryRef       current
, 
 541         CFStringRef                     matchID         
= (CFStringRef
)context1
; 
 542         CFMutableDictionaryRef          newDict
; 
 544         if (current 
== NULL
) { 
 545                 // we have nothing to "add" 
 549         newDict 
= CFDictionaryCreateMutableCopy(NULL
, 0, current
); 
 551         // remove "default" flag 
 552         CFDictionaryRemoveValue(newDict
, USER_PREFERENCES_DEFAULT
); 
 554         if (isMatchingPrefsID(current
, matchID
)) { 
 555                 // if we match, set "default" flag 
 556                 CFDictionarySetValue(newDict
, USER_PREFERENCES_DEFAULT
, kCFBooleanTrue
); 
 564 SCUserPreferencesSetCurrent(SCUserPreferencesRef userPreferences
) 
 566         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
 568         if (!isA_SCUserPreferences(userPreferences
)) { 
 569                 _SCErrorSet(kSCStatusInvalidArgument
); 
 573         return processPreferences(userPrivate
->serviceID
, 
 575                                   (void *)userPrivate
->prefsID
, 
 581 static CFDictionaryRef
 
 582 copyNameCallout(CFStringRef     serviceID
, 
 583                 CFDictionaryRef current
, 
 588         CFStringRef     matchID 
= (CFStringRef
)context1
; 
 589         CFStringRef     
*name   
= (CFStringRef 
*)context3
; 
 591         if (current 
== NULL
) { 
 592                 // we have nothing to "add" 
 596         if (isMatchingPrefsID(current
, matchID
)) { 
 597                 *name 
= CFDictionaryGetValue(current
, kSCPropUserDefinedName
); 
 599                 // for backwards compatibility, we also check for the name in the PPP entity 
 603                         ppp 
= CFDictionaryGetValue(current
, kSCEntNetPPP
); 
 604                         if (isA_CFDictionary(ppp
)) { 
 605                                 *name 
= CFDictionaryGetValue(ppp
, kSCPropUserDefinedName
); 
 609                 *name 
= isA_CFString(*name
); 
 615         return CFRetain(current
); 
 620 SCUserPreferencesCopyName(SCUserPreferencesRef userPreferences
) 
 622         CFStringRef                     name            
= NULL
; 
 624         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
 626         if (!isA_SCUserPreferences(userPreferences
)) { 
 627                 _SCErrorSet(kSCStatusInvalidArgument
); 
 631         // find SCUserPreferences and copy name 
 632         ok 
= processPreferences(userPrivate
->serviceID
, 
 634                                 (void *)userPrivate
->prefsID
, 
 648 static CF_RETURNS_RETAINED CFDictionaryRef
 
 649 setNameCallout(CFStringRef      serviceID
, 
 650                CFDictionaryRef  current
, 
 655         CFStringRef             matchID 
= (CFStringRef
)context1
; 
 656         CFMutableDictionaryRef  newDict
; 
 657         CFStringRef             newName 
= (CFStringRef
)context2
; 
 659         if (current 
== NULL
) { 
 660                 // we have nothing to "add" 
 664         newDict 
= CFDictionaryCreateMutableCopy(NULL
, 0, current
); 
 666         if (isMatchingPrefsID(current
, matchID
)) { 
 667                 CFDictionaryRef pppEntity
; 
 670                 if (newName 
!= NULL
) { 
 671                         CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, newName
); 
 673                         CFDictionaryRemoveValue(newDict
, kSCPropUserDefinedName
); 
 676                 // for backwards compatibility, we also set the name in the PPP entity 
 677                 pppEntity 
= CFDictionaryGetValue(newDict
, kSCEntNetPPP
); 
 678                 if (isA_CFDictionary(pppEntity
)) { 
 679                         CFMutableDictionaryRef  newPPPEntity
; 
 681                         newPPPEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, pppEntity
); 
 682                         if (newName 
!= NULL
) { 
 683                                 CFDictionarySetValue(newPPPEntity
, kSCPropUserDefinedName
, newName
); 
 685                                 CFDictionaryRemoveValue(newPPPEntity
, kSCPropUserDefinedName
); 
 687                         CFDictionarySetValue(newDict
, kSCEntNetPPP
, newPPPEntity
); 
 688                         CFRelease(newPPPEntity
); 
 697 SCUserPreferencesSetName(SCUserPreferencesRef userPreferences
, CFStringRef newName
) 
 700         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
 702         if (!isA_SCUserPreferences(userPreferences
)) { 
 703                 _SCErrorSet(kSCStatusInvalidArgument
); 
 707         if ((newName 
!= NULL
) && !isA_CFString(newName
)) { 
 708                 _SCErrorSet(kSCStatusInvalidArgument
); 
 712         // find SCUserPreferences and set name 
 713         ok 
= processPreferences(userPrivate
->serviceID
, 
 715                                 (void *)userPrivate
->prefsID
, 
 723 static CFDictionaryRef
 
 724 copyInterfaceConfigurationCallout(CFStringRef           serviceID
, 
 725                                   CFDictionaryRef       current
, 
 730         CFDictionaryRef 
*dict           
= (CFDictionaryRef 
*)context3
; 
 731         CFStringRef     interfaceType   
= (CFStringRef
)context2
; 
 732         CFStringRef     matchID         
= (CFStringRef
)context1
; 
 734         if (current 
== NULL
) { 
 735                 // we have nothing to "add" 
 739         if (isMatchingPrefsID(current
, matchID
)) { 
 740                 *dict 
= CFDictionaryGetValue(current
, interfaceType
); 
 741                 *dict 
= isA_CFDictionary(*dict
); 
 747         return CFRetain(current
); 
 752 SCUserPreferencesCopyInterfaceConfiguration(SCUserPreferencesRef        userPreferences
, 
 753                                             SCNetworkInterfaceRef       interface
) 
 755         CFStringRef                     defaultType
; 
 756         CFDictionaryRef                 entity          
= NULL
; 
 758         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
 760         if (!isA_SCUserPreferences(userPreferences
)) { 
 761                 _SCErrorSet(kSCStatusInvalidArgument
); 
 765         if (!isA_SCNetworkInterface(interface
)) { 
 766                 _SCErrorSet(kSCStatusInvalidArgument
); 
 771         defaultType 
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
); 
 772         if (defaultType 
== NULL
) { 
 773                 _SCErrorSet(kSCStatusInvalidArgument
); 
 777         // find SCUserPreferences and copy interface entity 
 778         ok 
= processPreferences(userPrivate
->serviceID
, 
 779                                 copyInterfaceConfigurationCallout
, 
 780                                 (void *)userPrivate
->prefsID
, 
 784                 if (entity 
!= NULL
) { 
 794 static CF_RETURNS_RETAINED CFDictionaryRef
 
 795 setInterfaceConfigurationCallout(CFStringRef            serviceID
, 
 796                                   CFDictionaryRef       current
, 
 801         CFStringRef             interfaceType   
= (CFStringRef
)context2
; 
 802         CFStringRef             matchID         
= (CFStringRef
)context1
; 
 803         CFMutableDictionaryRef  newDict
; 
 804         CFDictionaryRef         newOptions      
= (CFDictionaryRef
)context3
; 
 806         if (current 
== NULL
) { 
 807                 // we have nothing to "add" 
 811         newDict 
= CFDictionaryCreateMutableCopy(NULL
, 0, current
); 
 813         if (isMatchingPrefsID(current
, matchID
)) { 
 814                 if (newOptions 
!= NULL
) { 
 815                         CFDictionarySetValue(newDict
, interfaceType
, newOptions
); 
 817                         // for backwards compatibility, we want to ensure that 
 818                         // the name is set in both the top level and in the PPP 
 820                         if (CFEqual(interfaceType
, kSCEntNetPPP
)) { 
 823                                 name 
= CFDictionaryGetValue(newOptions
, kSCPropUserDefinedName
); 
 825                                         // if name was passed in newOptions, push up 
 826                                         CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, name
); 
 828                                         name 
= CFDictionaryGetValue(newDict
, kSCPropUserDefinedName
); 
 830                                                 CFMutableDictionaryRef  newPPPEntity
; 
 832                                                 // if name in parent, push into entity 
 833                                                 newPPPEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, newOptions
); 
 834                                                 CFDictionarySetValue(newPPPEntity
, kSCPropUserDefinedName
, name
); 
 835                                                 CFDictionarySetValue(newDict
, interfaceType
, newPPPEntity
); 
 836                                                 CFRelease(newPPPEntity
); 
 841                         CFDictionaryRemoveValue(newDict
, interfaceType
); 
 850 SCUserPreferencesSetInterfaceConfiguration(SCUserPreferencesRef         userPreferences
, 
 851                                            SCNetworkInterfaceRef        interface
, 
 852                                            CFDictionaryRef              newOptions
) 
 854         CFStringRef                     defaultType
; 
 856         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
 858         if (!isA_SCUserPreferences(userPreferences
)) { 
 859                 _SCErrorSet(kSCStatusInvalidArgument
); 
 863         if (!isA_SCNetworkInterface(interface
)) { 
 864                 _SCErrorSet(kSCStatusInvalidArgument
); 
 869         defaultType 
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
); 
 870         if (defaultType 
== NULL
) { 
 871                 _SCErrorSet(kSCStatusInvalidArgument
); 
 875         // set new interface entity for SCUserPreferences 
 876         ok 
= processPreferences(userPrivate
->serviceID
, 
 877                                 setInterfaceConfigurationCallout
, 
 878                                 (void *)userPrivate
->prefsID
, 
 887 SCUserPreferencesCopyExtendedInterfaceConfiguration(SCUserPreferencesRef        userPreferences
, 
 888                                                     SCNetworkInterfaceRef       interface
, 
 889                                                     CFStringRef                 extendedType
) 
 891         CFDictionaryRef                 entity          
= NULL
; 
 893         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
 895         if (!isA_SCUserPreferences(userPreferences
)) { 
 896                 _SCErrorSet(kSCStatusInvalidArgument
); 
 900         if (!isA_SCNetworkInterface(interface
)) { 
 901                 _SCErrorSet(kSCStatusInvalidArgument
); 
 905         if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, FALSE
)) { 
 906                 _SCErrorSet(kSCStatusInvalidArgument
); 
 910         // find SCUserPreferences and copy interface entity 
 911         ok 
= processPreferences(userPrivate
->serviceID
, 
 912                                 copyInterfaceConfigurationCallout
, 
 913                                 (void *)userPrivate
->prefsID
, 
 914                                 (void *)extendedType
, 
 917                 if (entity 
!= NULL
) { 
 928 SCUserPreferencesSetExtendedInterfaceConfiguration(SCUserPreferencesRef         userPreferences
, 
 929                                                    SCNetworkInterfaceRef        interface
, 
 930                                                    CFStringRef                  extendedType
, 
 931                                                    CFDictionaryRef              newOptions
) 
 934         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
 936         if (!isA_SCUserPreferences(userPreferences
)) { 
 937                 _SCErrorSet(kSCStatusInvalidArgument
); 
 941         if (!isA_SCNetworkInterface(interface
)) { 
 942                 _SCErrorSet(kSCStatusInvalidArgument
); 
 946         if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, FALSE
)) { 
 947                 _SCErrorSet(kSCStatusInvalidArgument
); 
 951         // set new interface entity for SCUserPreferences 
 952         ok 
= processPreferences(userPrivate
->serviceID
, 
 953                                 setInterfaceConfigurationCallout
, 
 954                                 (void *)userPrivate
->prefsID
, 
 955                                 (void *)extendedType
, 
 963 #pragma mark SCNetworkConnection + SCUserPreferences SPIs 
 966 static CFDictionaryRef
 
 967 copyAllCallout(CFStringRef      serviceID
, 
 968                CFDictionaryRef  current
, 
 973         CFMutableArrayRef               
*prefs          
= (CFMutableArrayRef 
*)context3
; 
 975         SCUserPreferencesPrivateRef     userPrivate
; 
 977         if (current 
== NULL
) { 
 978                 // we have nothing to "add" 
 982         prefsID 
= CFDictionaryGetValue(current
, USER_PREFERENCES_ID
); 
 983         if (!isA_CFString(prefsID
)) { 
 988         userPrivate 
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, prefsID
); 
 989         if (userPrivate 
!= NULL
) { 
 990                 if (*prefs 
== NULL
) { 
 991                         *prefs 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 993                 CFArrayAppendValue(*prefs
, (SCUserPreferencesRef
)userPrivate
); 
 994                 CFRelease(userPrivate
); 
 999         return CFRetain(current
); 
1003 CFArrayRef 
/* of SCUserPreferencesRef's */ 
1004 SCNetworkConnectionCopyAllUserPreferences(SCNetworkConnectionRef connection
) 
1007         CFMutableArrayRef       prefs           
= NULL
; 
1008         CFStringRef             serviceID
; 
1011         serviceID 
= SCNetworkConnectionCopyServiceID(connection
); 
1013         // collect SCUserPreferences 
1014         ok 
= processPreferences(serviceID
, 
1020                 if (prefs 
!= NULL
) { 
1026         CFRelease(serviceID
); 
1031 static CFDictionaryRef
 
1032 copyCurrentCallout(CFStringRef          serviceID
, 
1033                    CFDictionaryRef      current
, 
1038         CFBooleanRef                    isDefault
; 
1039         CFStringRef                     prefsID
; 
1040         SCUserPreferencesPrivateRef     
*userPrivate    
= (SCUserPreferencesPrivateRef 
*)context3
; 
1042         if (current 
== NULL
) { 
1043                 // we have nothing to "add" 
1047         prefsID 
= CFDictionaryGetValue(current
, USER_PREFERENCES_ID
); 
1048         if (!isA_CFString(prefsID
)) { 
1053         isDefault 
= CFDictionaryGetValue(current
, USER_PREFERENCES_DEFAULT
); 
1054         if (!isA_CFBoolean(isDefault
) || !CFBooleanGetValue(isDefault
)) { 
1055                 // if not the default configuration 
1059         *userPrivate 
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, prefsID
); 
1063         return CFRetain(current
); 
1067 SCUserPreferencesRef
 
1068 SCNetworkConnectionCopyCurrentUserPreferences(SCNetworkConnectionRef connection
) 
1070         SCUserPreferencesRef    current         
= NULL
; 
1072         CFStringRef             serviceID
; 
1075         serviceID 
= SCNetworkConnectionCopyServiceID(connection
); 
1077         // collect SCUserPreferences 
1078         ok 
= processPreferences(serviceID
, 
1084                 if (current 
!= NULL
) { 
1090         CFRelease(serviceID
); 
1095 static CFDictionaryRef
 
1096 createCallout(CFStringRef       serviceID
, 
1097               CFDictionaryRef   current
, 
1102         CFMutableDictionaryRef          newDict
; 
1103         CFStringRef                     newPrefsID      
= (CFStringRef
)context1
; 
1105         if (current 
!= NULL
) { 
1106                 // don't change existing entries 
1107                 return CFRetain(current
); 
1110         newDict 
= CFDictionaryCreateMutable(NULL
, 
1112                                             &kCFTypeDictionaryKeyCallBacks
, 
1113                                             &kCFTypeDictionaryValueCallBacks
); 
1114         CFDictionarySetValue(newDict
, USER_PREFERENCES_ID
, newPrefsID
); 
1119 SCUserPreferencesRef
 
1120 SCNetworkConnectionCreateUserPreferences(SCNetworkConnectionRef connection
) 
1122         CFStringRef                     newPrefsID
; 
1123         CFStringRef                     serviceID
; 
1124         SCUserPreferencesPrivateRef     userPrivate
; 
1128         serviceID 
= SCNetworkConnectionCopyServiceID(connection
); 
1130         // allocate a new user preferences ID 
1131         uuid       
= CFUUIDCreate(NULL
); 
1132         newPrefsID 
= CFUUIDCreateString(NULL
, uuid
); 
1135         userPrivate 
= __SCUserPreferencesCreatePrivate(NULL
, serviceID
, newPrefsID
); 
1136         if (userPrivate 
!= NULL
) { 
1137                 (void) processPreferences(serviceID
, 
1144         CFRelease(newPrefsID
); 
1145         CFRelease(serviceID
); 
1146         return (SCUserPreferencesRef
)userPrivate
; 
1151 update_PPP_entity(SCUserPreferencesRef userPreferences
, CFDictionaryRef 
*userOptions
) 
1153         CFStringRef     encryption
; 
1154         CFDictionaryRef entity
; 
1155         CFStringRef     keychainID
; 
1157         entity 
= CFDictionaryGetValue(*userOptions
, kSCEntNetPPP
); 
1158         if (!isA_CFDictionary(entity
)) { 
1162         encryption 
= CFDictionaryGetValue(entity
, kSCPropNetPPPAuthPasswordEncryption
); 
1163         if (encryption 
== NULL
) { 
1164                 // provide default encryption method 
1165                 encryption 
= kSCValNetPPPAuthPasswordEncryptionKeychain
; 
1168         if (!isA_CFString(encryption
) || 
1169             !CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) { 
1173         keychainID 
= CFDictionaryGetValue(entity
, kSCPropNetPPPAuthPassword
); 
1174         if (isA_CFString(keychainID
)) { 
1175                 // if password is keychain ID 
1176         } else if (isA_CFData(keychainID
) && 
1177                    ((CFDataGetLength((CFDataRef
)keychainID
) % sizeof(UniChar
)) == 0)) { 
1178                 // if inline password 
1181                 keychainID 
= SCUserPreferencesGetUniqueID(userPreferences
); 
1184         if (_SCSecKeychainPasswordItemExists(NULL
, keychainID
)) { 
1185                 CFMutableDictionaryRef  new_entity
; 
1186                 CFMutableDictionaryRef  new_options
; 
1188                 // access PPP password from system keychain 
1189                 new_entity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1191                 CFDictionarySetValue(new_entity
, 
1192                                      kSCPropNetPPPAuthPassword
, 
1194                 CFDictionarySetValue(new_entity
, 
1195                                      kSCPropNetPPPAuthPasswordEncryption
, 
1196                                      kSCValNetPPPAuthPasswordEncryptionKeychain
); 
1198                 new_options 
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
); 
1199                 CFDictionarySetValue(new_options
, kSCEntNetPPP
, new_entity
); 
1200                 CFRelease(new_entity
); 
1202                 CFRelease(*userOptions
); 
1203                 *userOptions 
= new_options
; 
1211 update_IPSec_entity(SCUserPreferencesRef userPreferences
, CFDictionaryRef 
*userOptions
) 
1213         CFStringRef     encryption
; 
1214         CFDictionaryRef entity
; 
1215         SecKeychainRef  keychain        
= NULL
; 
1216         CFStringRef     keychainID
; 
1218         CFDataRef       sharedSecret
; 
1220         entity 
= CFDictionaryGetValue(*userOptions
, kSCEntNetIPSec
); 
1221         if (!isA_CFDictionary(entity
)) { 
1225         method 
= CFDictionaryGetValue(entity
, kSCPropNetIPSecAuthenticationMethod
); 
1226         if (!isA_CFString(method
) || 
1227             !CFEqual(method
, kSCValNetIPSecAuthenticationMethodSharedSecret
)) { 
1231         encryption 
= CFDictionaryGetValue(entity
, kSCPropNetIPSecSharedSecretEncryption
); 
1232         if (encryption 
== NULL
) { 
1233                 // provide default encryption method 
1234                 encryption 
= kSCValNetIPSecSharedSecretEncryptionKeychain
; 
1237         if (!isA_CFString(encryption
) || 
1238             !CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) { 
1242         keychainID 
= CFDictionaryGetValue(entity
, kSCPropNetIPSecSharedSecret
); 
1243         if (isA_CFString(keychainID
)) { 
1244                 // if shared secret is keychain ID 
1245                 CFRetain(keychainID
); 
1246         } else if (isA_CFData(keychainID
) && 
1247                    ((CFDataGetLength((CFDataRef
)keychainID
) % sizeof(UniChar
)) == 0)) { 
1248                 // if inline shared secret 
1251                 CFStringRef     unique_id
; 
1253                 unique_id 
= SCUserPreferencesGetUniqueID(userPreferences
); 
1254                 keychainID 
= (CFStringRef
)CFStringCreateMutableCopy(NULL
, 0, unique_id
); 
1255                 CFStringAppend((CFMutableStringRef
)keychainID
, CFSTR(".SS")); 
1258         sharedSecret 
= _SCSecKeychainPasswordItemCopy(NULL
, keychainID
); 
1259         if (sharedSecret 
!= NULL
) { 
1260                 CFMutableDictionaryRef  new_entity
; 
1261                 CFMutableDictionaryRef  new_options
; 
1262                 CFStringRef             password
; 
1264                 // pass SharedSecret from user keychain 
1265                 new_entity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1267                 password 
= CFStringCreateWithBytes(NULL
, 
1268                                                    CFDataGetBytePtr(sharedSecret
), 
1269                                                    CFDataGetLength(sharedSecret
), 
1270                                                    kCFStringEncodingUTF8
, 
1272                 CFRelease(sharedSecret
); 
1273                 CFDictionarySetValue(new_entity
, 
1274                                      kSCPropNetIPSecSharedSecret
, 
1276                 CFRelease(password
); 
1277                 CFDictionaryRemoveValue(new_entity
, 
1278                                         kSCPropNetIPSecSharedSecretEncryption
); 
1280                 new_options 
= CFDictionaryCreateMutableCopy(NULL
, 0, *userOptions
); 
1281                 CFDictionarySetValue(new_options
, kSCEntNetIPSec
, new_entity
); 
1282                 CFRelease(new_entity
); 
1284                 CFRelease(*userOptions
); 
1285                 *userOptions 
= new_options
; 
1289         keychain 
= _SCSecKeychainCopySystemKeychain(); 
1290         if (keychain 
== NULL
) { 
1294         if (_SCSecKeychainPasswordItemExists(keychain
, keychainID
)) { 
1295                 CFMutableDictionaryRef  new_entity
; 
1296                 CFMutableDictionaryRef  new_options
; 
1298                 // access SharedSecret from system keychain 
1299                 new_entity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1301                 CFDictionarySetValue(new_entity
, 
1302                                      kSCPropNetIPSecSharedSecret
, 
1304                 CFDictionarySetValue(new_entity
, 
1305                                      kSCPropNetIPSecSharedSecretEncryption
, 
1306                                      kSCValNetIPSecSharedSecretEncryptionKeychain
); 
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
; 
1318         if (keychain 
!= NULL
) CFRelease(keychain
); 
1319         CFRelease(keychainID
); 
1324 static CFDictionaryRef
 
1325 copyOptionsCallout(CFStringRef          serviceID
, 
1326                    CFDictionaryRef      current
, 
1331         CFStringRef             matchID         
= (CFStringRef
)context1
; 
1332         CFMutableDictionaryRef  
*userOptions    
= (CFMutableDictionaryRef 
*)context3
; 
1334         if (current 
== NULL
) { 
1335                 // we have nothing to "add" 
1339         if (isMatchingPrefsID(current
, matchID
)) { 
1340                 // if we match, return options dictionary 
1341                 if (*userOptions 
!= NULL
) CFRelease(*userOptions
); 
1342                 *userOptions 
= CFDictionaryCreateMutableCopy(NULL
, 0, current
); 
1343                 CFDictionaryRemoveValue(*userOptions
, USER_PREFERENCES_ID
); 
1344                 CFDictionaryRemoveValue(*userOptions
, USER_PREFERENCES_DEFAULT
); 
1347         return CFRetain(current
); 
1352 SCNetworkConnectionStartWithUserPreferences(SCNetworkConnectionRef      connection
, 
1353                                             SCUserPreferencesRef        userPreferences
, 
1357         CFDictionaryRef                 userOptions     
= NULL
; 
1358         SCUserPreferencesPrivateRef     userPrivate     
= (SCUserPreferencesPrivateRef
)userPreferences
; 
1360         if (!isA_SCUserPreferences(userPreferences
)) { 
1361                 _SCErrorSet(kSCStatusInvalidArgument
); 
1365         (void) processPreferences(userPrivate
->serviceID
, 
1367                                   (void *)userPrivate
->prefsID
, 
1372          * For some legacy preferences, some of the user options 
1373          * were missing yet handled by the APIs.  Make sure that 
1374          * everything still works! 
1376         if (userOptions 
!= NULL
) { 
1377                 update_PPP_entity  (userPreferences
, &userOptions
); 
1378                 update_IPSec_entity(userPreferences
, &userOptions
); 
1381         ok 
= SCNetworkConnectionStart(connection
, userOptions
, linger
); 
1383         if (userOptions 
!= NULL
) { 
1384                 CFRelease(userOptions
); 
1392 #pragma mark SCUserPreferences + SCNetworkInterface Password SPIs 
1396 getUserPasswordID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
) 
1398         CFStringRef     unique_id       
= NULL
; 
1400         if (config 
!= NULL
) { 
1401                 CFStringRef     encryption
; 
1403                 encryption 
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
); 
1404                 if (isA_CFString(encryption
) && 
1405                     CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) { 
1406                         unique_id 
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
); 
1409         if (unique_id 
== NULL
) { 
1410                 unique_id 
= SCUserPreferencesGetUniqueID(userPreferences
); 
1418 copyUserSharedSecretID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
) 
1420         CFMutableStringRef      sharedSecret    
= NULL
; 
1422         if (config 
!= NULL
) { 
1423                 CFStringRef     encryption
; 
1425                 encryption 
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
); 
1426                 if (isA_CFString(encryption
) && 
1427                     CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) { 
1428                         sharedSecret 
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
); 
1429                         if (sharedSecret 
!= NULL
) { 
1430                                 CFRetain(sharedSecret
); 
1435         if (sharedSecret 
== NULL
) { 
1436                 CFStringRef     unique_id
; 
1438                 unique_id 
= getUserPasswordID(config
, userPreferences
); 
1439                 sharedSecret 
= CFStringCreateMutableCopy(NULL
, 0, unique_id
); 
1440                 CFStringAppend(sharedSecret
, CFSTR(".SS")); 
1443         return sharedSecret
; 
1448 copyUserXAuthID(CFDictionaryRef config
, SCUserPreferencesRef userPreferences
) 
1450         CFMutableStringRef      xauth_id        
= NULL
; 
1452         if (config 
!= NULL
) { 
1453                 CFStringRef     encryption
; 
1455                 encryption 
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
); 
1456                 if (isA_CFString(encryption
) && 
1457                     CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) { 
1458                         xauth_id 
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
); 
1459                         if (xauth_id 
!= NULL
) { 
1465         if (xauth_id 
== NULL
) { 
1466                 CFStringRef     unique_id
; 
1468                 unique_id 
= getUserPasswordID(config
, userPreferences
); 
1469                 xauth_id 
= CFStringCreateMutableCopy(NULL
, 0, unique_id
); 
1470                 CFStringAppend(xauth_id
, CFSTR(".XAUTH")); 
1478 checkUserPreferencesPassword(SCUserPreferencesRef               userPreferences
, 
1479                              SCNetworkInterfaceRef              interface
, 
1480                              SCNetworkInterfacePasswordType     passwordType
) 
1482         if (!isA_SCUserPreferences(userPreferences
)) { 
1483                 _SCErrorSet(kSCStatusInvalidArgument
); 
1487         if (!isA_SCNetworkInterface(interface
)) { 
1488                 _SCErrorSet(kSCStatusInvalidArgument
); 
1492         switch (passwordType
) { 
1493                 case kSCNetworkInterfacePasswordTypePPP 
: { 
1494                         CFStringRef     interfaceType
; 
1496                         interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1497                         if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) { 
1498                                 _SCErrorSet(kSCStatusInvalidArgument
); 
1504                 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret 
: { 
1505                         CFStringRef             interfaceType
; 
1507                         interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1508                         if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) { 
1509                                 _SCErrorSet(kSCStatusInvalidArgument
); 
1513                         interface 
= SCNetworkInterfaceGetInterface(interface
); 
1514                         if (interface 
== NULL
) { 
1515                                 _SCErrorSet(kSCStatusInvalidArgument
); 
1519                         interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1520                         if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) { 
1521                                 _SCErrorSet(kSCStatusInvalidArgument
); 
1527                 case kSCNetworkInterfacePasswordTypeEAPOL 
: { 
1528                         _SCErrorSet(kSCStatusInvalidArgument
); 
1532                 case kSCNetworkInterfacePasswordTypeIPSecXAuth 
: { 
1533                         CFStringRef     interfaceType
; 
1535                         interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1536                         if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) { 
1537                                 _SCErrorSet(kSCStatusInvalidArgument
); 
1543                 case kSCNetworkInterfacePasswordTypeVPN 
: { 
1544                         CFStringRef     interfaceType
; 
1546                         interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1547                         if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) { 
1548                                 _SCErrorSet(kSCStatusInvalidArgument
); 
1563 SCUserPreferencesCheckInterfacePassword(SCUserPreferencesRef            userPreferences
, 
1564                                         SCNetworkInterfaceRef           interface
, 
1565                                         SCNetworkInterfacePasswordType  passwordType
) 
1567         Boolean         exists  
= FALSE
; 
1569         if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) { 
1573         switch (passwordType
) { 
1574                 case kSCNetworkInterfacePasswordTypePPP 
: { 
1575                         CFDictionaryRef config
; 
1576                         CFStringRef     unique_id
; 
1578                         // get configuration 
1579                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
1581                         // get userPreferences ID 
1582                         unique_id 
= getUserPasswordID(config
, userPreferences
); 
1585                         exists 
= __extract_password(NULL
, 
1587                                                     kSCPropNetPPPAuthPassword
, 
1588                                                     kSCPropNetPPPAuthPasswordEncryption
, 
1589                                                     kSCValNetPPPAuthPasswordEncryptionKeychain
, 
1593                         if (config 
!= NULL
)     CFRelease(config
); 
1597                 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret 
: { 
1598                         CFDictionaryRef config
; 
1599                         CFStringRef     shared_id
; 
1601                         // get configuration 
1602                         config 
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
, 
1606                         // get sharedSecret ID 
1607                         shared_id 
= copyUserSharedSecretID(config
, userPreferences
); 
1610                         exists 
= __extract_password(NULL
, 
1612                                                     kSCPropNetIPSecSharedSecret
, 
1613                                                     kSCPropNetIPSecSharedSecretEncryption
, 
1614                                                     kSCValNetIPSecSharedSecretEncryptionKeychain
, 
1618                         if (config 
!= NULL
)     CFRelease(config
); 
1619                         CFRelease(shared_id
); 
1623                 case kSCNetworkInterfacePasswordTypeIPSecXAuth 
: { 
1624                         CFDictionaryRef config
; 
1625                         CFStringRef     xauth_id
; 
1627                         // get configuration 
1628                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
1631                         xauth_id 
= copyUserXAuthID(config
, userPreferences
); 
1634                         exists 
= __extract_password(NULL
, 
1636                                                     kSCPropNetIPSecXAuthPassword
, 
1637                                                     kSCPropNetIPSecXAuthPasswordEncryption
, 
1638                                                     kSCValNetIPSecXAuthPasswordEncryptionKeychain
, 
1642                         if (config 
!= NULL
)     CFRelease(config
); 
1643                         CFRelease(xauth_id
); 
1647                 case kSCNetworkInterfacePasswordTypeVPN 
: { 
1648                         CFDictionaryRef config
; 
1649                         CFStringRef     unique_id
; 
1651                         // get configuration 
1652                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
1654                         // get userPreferences ID 
1655                         unique_id 
= getUserPasswordID(config
, userPreferences
); 
1658                         exists 
= __extract_password(NULL
, 
1660                                                     kSCPropNetVPNAuthPassword
, 
1661                                                     kSCPropNetVPNAuthPasswordEncryption
, 
1662                                                     kSCValNetVPNAuthPasswordEncryptionKeychain
, 
1666                         if (config 
!= NULL
)     CFRelease(config
); 
1671                         _SCErrorSet(kSCStatusInvalidArgument
); 
1680 SCUserPreferencesCopyInterfacePassword(SCUserPreferencesRef             userPreferences
, 
1681                                        SCNetworkInterfaceRef            interface
, 
1682                                        SCNetworkInterfacePasswordType   passwordType
) 
1684         CFDataRef       password        
= NULL
; 
1686         if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) { 
1690         switch (passwordType
) { 
1691                 case kSCNetworkInterfacePasswordTypePPP 
: { 
1692                         CFDictionaryRef config
; 
1693                         CFStringRef     unique_id
; 
1695                         // get configuration 
1696                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
1698                         // get userPreferences ID 
1699                         unique_id 
= getUserPasswordID(config
, userPreferences
); 
1702                         (void) __extract_password(NULL
, 
1704                                                   kSCPropNetPPPAuthPassword
, 
1705                                                   kSCPropNetPPPAuthPasswordEncryption
, 
1706                                                   kSCValNetPPPAuthPasswordEncryptionKeychain
, 
1710                         if (config 
!= NULL
)     CFRelease(config
); 
1714                 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret 
: { 
1715                         CFDictionaryRef config
; 
1716                         CFStringRef     shared_id
; 
1718                         // get configuration 
1719                         config 
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
, 
1723                         // get sharedSecret ID 
1724                         shared_id 
= copyUserSharedSecretID(config
, userPreferences
); 
1727                         (void) __extract_password(NULL
, 
1729                                                   kSCPropNetIPSecSharedSecret
, 
1730                                                   kSCPropNetIPSecSharedSecretEncryption
, 
1731                                                   kSCValNetIPSecSharedSecretEncryptionKeychain
, 
1735                         if (config 
!= NULL
)     CFRelease(config
); 
1736                         CFRelease(shared_id
); 
1740                 case kSCNetworkInterfacePasswordTypeIPSecXAuth 
: { 
1741                         CFDictionaryRef config
; 
1742                         CFStringRef     xauth_id
; 
1744                         // get configuration 
1745                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
1748                         xauth_id 
= copyUserXAuthID(config
, userPreferences
); 
1751                         (void) __extract_password(NULL
, 
1753                                                   kSCPropNetIPSecXAuthPassword
, 
1754                                                   kSCPropNetIPSecXAuthPasswordEncryption
, 
1755                                                   kSCValNetIPSecXAuthPasswordEncryptionKeychain
, 
1759                         if (config 
!= NULL
)     CFRelease(config
); 
1760                         CFRelease(xauth_id
); 
1764                 case kSCNetworkInterfacePasswordTypeVPN 
: { 
1765                         CFDictionaryRef config
; 
1766                         CFStringRef     unique_id
; 
1768                         // get configuration 
1769                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
1771                         // get userPreferences ID 
1772                         unique_id 
= getUserPasswordID(config
, userPreferences
); 
1775                         (void) __extract_password(NULL
, 
1777                                                   kSCPropNetVPNAuthPassword
, 
1778                                                   kSCPropNetVPNAuthPasswordEncryption
, 
1779                                                   kSCValNetVPNAuthPasswordEncryptionKeychain
, 
1783                         if (config 
!= NULL
)     CFRelease(config
); 
1788                         _SCErrorSet(kSCStatusInvalidArgument
); 
1797 SCUserPreferencesRemoveInterfacePassword(SCUserPreferencesRef           userPreferences
, 
1798                                          SCNetworkInterfaceRef          interface
, 
1799                                          SCNetworkInterfacePasswordType passwordType
) 
1803         if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) { 
1807         switch (passwordType
) { 
1808                 case kSCNetworkInterfacePasswordTypePPP 
: { 
1809                         CFDictionaryRef config
; 
1810                         CFDictionaryRef newConfig       
= NULL
; 
1811                         CFStringRef     unique_id
; 
1813                         // get configuration 
1814                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
1816                         // get userPreferences ID 
1817                         unique_id 
= getUserPasswordID(config
, userPreferences
); 
1820                         ok 
= __remove_password(NULL
, 
1822                                                kSCPropNetPPPAuthPassword
, 
1823                                                kSCPropNetPPPAuthPasswordEncryption
, 
1824                                                kSCValNetPPPAuthPasswordEncryptionKeychain
, 
1828                                 ok 
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
); 
1829                                 if (newConfig 
!= NULL
) CFRelease(newConfig
); 
1832                         if (config 
!= NULL
) CFRelease(config
); 
1836                 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret 
: { 
1837                         CFDictionaryRef config
; 
1838                         CFDictionaryRef newConfig       
= NULL
; 
1839                         CFStringRef     shared_id
; 
1841                         // get configuration 
1842                         config 
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
, 
1846                         // get sharedSecret ID 
1847                         shared_id 
= copyUserSharedSecretID(config
, userPreferences
); 
1850                         ok 
= __remove_password(NULL
, 
1852                                                kSCPropNetIPSecSharedSecret
, 
1853                                                kSCPropNetIPSecSharedSecretEncryption
, 
1854                                                kSCValNetIPSecSharedSecretEncryptionKeychain
, 
1858                                 ok 
= SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences
, 
1862                                 if (newConfig 
!= NULL
) CFRelease(newConfig
); 
1865                         if (config 
!= NULL
) CFRelease(config
); 
1866                         CFRelease(shared_id
); 
1870                 case kSCNetworkInterfacePasswordTypeIPSecXAuth 
: { 
1871                         CFDictionaryRef config
; 
1872                         CFDictionaryRef newConfig       
= NULL
; 
1873                         CFStringRef     xauth_id
; 
1875                         // get configuration 
1876                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
1879                         xauth_id 
= copyUserXAuthID(config
, userPreferences
); 
1882                         ok 
= __remove_password(NULL
, 
1884                                                kSCPropNetIPSecXAuthPassword
, 
1885                                                kSCPropNetIPSecXAuthPasswordEncryption
, 
1886                                                kSCValNetIPSecXAuthPasswordEncryptionKeychain
, 
1890                                 ok 
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
); 
1891                                 if (newConfig 
!= NULL
) CFRelease(newConfig
); 
1894                         if (config 
!= NULL
) CFRelease(config
); 
1895                         CFRelease(xauth_id
); 
1899                 case kSCNetworkInterfacePasswordTypeVPN 
: { 
1900                         CFDictionaryRef config
; 
1901                         CFDictionaryRef newConfig       
= NULL
; 
1902                         CFStringRef     unique_id
; 
1904                         // get configuration 
1905                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
1907                         // get userPreferences ID 
1908                         unique_id 
= getUserPasswordID(config
, userPreferences
); 
1911                         ok 
= __remove_password(NULL
, 
1913                                                kSCPropNetVPNAuthPassword
, 
1914                                                kSCPropNetVPNAuthPasswordEncryption
, 
1915                                                kSCValNetVPNAuthPasswordEncryptionKeychain
, 
1919                                 ok 
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
); 
1920                                 if (newConfig 
!= NULL
) CFRelease(newConfig
); 
1923                         if (config 
!= NULL
) CFRelease(config
); 
1928                         _SCErrorSet(kSCStatusInvalidArgument
); 
1937 SCUserPreferencesSetInterfacePassword(SCUserPreferencesRef              userPreferences
, 
1938                                       SCNetworkInterfaceRef             interface
, 
1939                                       SCNetworkInterfacePasswordType    passwordType
, 
1941                                       CFDictionaryRef                   options
) 
1943         CFStringRef     account         
= NULL
; 
1945         CFDictionaryRef config
; 
1946         CFStringRef     description     
= NULL
; 
1947         CFStringRef     label           
= NULL
; 
1950         if (!checkUserPreferencesPassword(userPreferences
, interface
, passwordType
)) { 
1954         bundle 
= _SC_CFBundleGet(); 
1956         switch (passwordType
) { 
1957                 case kSCNetworkInterfacePasswordTypePPP 
: { 
1958                         CFStringRef     unique_id
; 
1960                         // get configuration 
1961                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
1963                         // get userPreferences ID 
1964                         unique_id 
= getUserPasswordID(config
, userPreferences
); 
1966                         // User prefs auth name --> keychain "Account" 
1967                         if (config 
!= NULL
) { 
1968                                 account 
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
); 
1971                         // User prefs "name" --> keychain "Name" 
1972                         label 
= SCUserPreferencesCopyName(userPreferences
); 
1974                         // "PPP Password" --> keychain "Kind" 
1975                         if (bundle 
!= NULL
) { 
1976                                 description 
= CFBundleCopyLocalizedString(bundle
, 
1977                                                                           CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"), 
1978                                                                           CFSTR("PPP Password"), 
1983                         ok 
= _SCSecKeychainPasswordItemSet(NULL
, 
1985                                                            (label 
!= NULL
)       ? label       
: CFSTR("Network Connection"), 
1986                                                            (description 
!= NULL
) ? description 
: CFSTR("PPP Password"), 
1991                                 CFMutableDictionaryRef  newConfig
; 
1993                                 if (config 
!= NULL
) { 
1994                                         newConfig 
= CFDictionaryCreateMutableCopy(NULL
, 0, config
); 
1996                                         newConfig 
= CFDictionaryCreateMutable(NULL
, 
1998                                                                               &kCFTypeDictionaryKeyCallBacks
, 
1999                                                                               &kCFTypeDictionaryValueCallBacks
); 
2001                                 CFDictionarySetValue(newConfig
, 
2002                                                      kSCPropNetPPPAuthPassword
, 
2004                                 CFDictionarySetValue(newConfig
, 
2005                                                      kSCPropNetPPPAuthPasswordEncryption
, 
2006                                                      kSCValNetPPPAuthPasswordEncryptionKeychain
); 
2007                                 ok 
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
); 
2008                                 CFRelease(newConfig
); 
2011                         if (config      
!= NULL
) CFRelease(config
); 
2012                         if (description 
!= NULL
) CFRelease(description
); 
2013                         if (label       
!= NULL
) CFRelease(label
); 
2017                 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret 
: { 
2018                         CFStringRef     shared_id
; 
2020                         // get configuration 
2021                         config 
= SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences
, 
2025                         // get sharedSecret ID 
2026                         shared_id 
= copyUserSharedSecretID(config
, userPreferences
); 
2028                         // User prefs "name" --> keychain "Name" 
2029                         label 
= SCUserPreferencesCopyName(userPreferences
); 
2031                         // "IPSec Shared Secret" --> keychain "Kind" 
2032                         if (bundle 
!= NULL
) { 
2033                                 description 
= CFBundleCopyLocalizedString(bundle
, 
2034                                                                           CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"), 
2035                                                                           CFSTR("IPSec Shared Secret"), 
2040                         ok 
= _SCSecKeychainPasswordItemSet(NULL
, 
2042                                                            (label 
!= NULL
)       ? label       
: CFSTR("Network Connection"), 
2043                                                            (description 
!= NULL
) ? description 
: CFSTR("IPSec Shared Secret"), 
2048                                 CFMutableDictionaryRef  newConfig       
= NULL
; 
2050                                 if (config 
!= NULL
) { 
2051                                         newConfig 
= CFDictionaryCreateMutableCopy(NULL
, 0, config
); 
2053                                         newConfig 
= CFDictionaryCreateMutable(NULL
, 
2055                                                                               &kCFTypeDictionaryKeyCallBacks
, 
2056                                                                               &kCFTypeDictionaryValueCallBacks
); 
2058                                 CFDictionarySetValue(newConfig
, 
2059                                                      kSCPropNetIPSecSharedSecret
, 
2061                                 CFDictionarySetValue(newConfig
, 
2062                                                      kSCPropNetIPSecSharedSecretEncryption
, 
2063                                                      kSCValNetIPSecSharedSecretEncryptionKeychain
); 
2064                                 ok 
= SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences
, 
2068                                 CFRelease(newConfig
); 
2071                         if (config      
!= NULL
) CFRelease(config
); 
2072                         if (description 
!= NULL
) CFRelease(description
); 
2073                         if (label       
!= NULL
) CFRelease(label
); 
2074                         CFRelease(shared_id
); 
2078                 case kSCNetworkInterfacePasswordTypeIPSecXAuth 
: { 
2079                         CFStringRef     xauth_id
; 
2081                         // get configuration 
2082                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
2085                         xauth_id 
= copyUserXAuthID(config
, userPreferences
); 
2087                         // User prefs XAuth name --> keychain "Account" 
2088                         if (config 
!= NULL
) { 
2089                                 account 
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
); 
2092                         // User prefs "name" --> keychain "Name" 
2093                         label 
= SCUserPreferencesCopyName(userPreferences
); 
2095                         // "IPSec XAuth Password" --> keychain "Kind" 
2096                         if (bundle 
!= NULL
) { 
2097                                 description 
= CFBundleCopyLocalizedString(bundle
, 
2098                                                                           CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"), 
2099                                                                           CFSTR("IPSec XAuth Password"), 
2104                         ok 
= _SCSecKeychainPasswordItemSet(NULL
, 
2106                                                            (label 
!= NULL
)       ? label       
: CFSTR("Network Connection"), 
2107                                                            (description 
!= NULL
) ? description 
: CFSTR("IPSec XAuth Password"), 
2112                                 CFMutableDictionaryRef  newConfig
; 
2114                                 if (config 
!= NULL
) { 
2115                                         newConfig 
= CFDictionaryCreateMutableCopy(NULL
, 0, config
); 
2117                                         newConfig 
= CFDictionaryCreateMutable(NULL
, 
2119                                                                               &kCFTypeDictionaryKeyCallBacks
, 
2120                                                                               &kCFTypeDictionaryValueCallBacks
); 
2122                                 CFDictionarySetValue(newConfig
, 
2123                                                      kSCPropNetIPSecXAuthPassword
, 
2125                                 CFDictionarySetValue(newConfig
, 
2126                                                      kSCPropNetIPSecXAuthPasswordEncryption
, 
2127                                                      kSCValNetIPSecXAuthPasswordEncryptionKeychain
); 
2128                                 ok 
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
); 
2129                                 CFRelease(newConfig
); 
2132                         if (config      
!= NULL
) CFRelease(config
); 
2133                         if (description 
!= NULL
) CFRelease(description
); 
2134                         if (label       
!= NULL
) CFRelease(label
); 
2135                         CFRelease(xauth_id
); 
2139                 case kSCNetworkInterfacePasswordTypeVPN 
: { 
2140                         CFStringRef     unique_id
; 
2142                         // get configuration 
2143                         config 
= SCUserPreferencesCopyInterfaceConfiguration(userPreferences
, interface
); 
2145                         // get userPreferences ID 
2146                         unique_id 
= getUserPasswordID(config
, userPreferences
); 
2148                         // User prefs auth name --> keychain "Account" 
2149                         if (config 
!= NULL
) { 
2150                                 account 
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
); 
2153                         // User prefs "name" --> keychain "Name" 
2154                         label 
= SCUserPreferencesCopyName(userPreferences
); 
2156                         // "VPN Password" --> keychain "Kind" 
2157                         if (bundle 
!= NULL
) { 
2158                                 description 
= CFBundleCopyLocalizedString(bundle
, 
2159                                                                           CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"), 
2160                                                                           CFSTR("VPN Password"), 
2165                         ok 
= _SCSecKeychainPasswordItemSet(NULL
, 
2167                                                            (label 
!= NULL
)       ? label       
: CFSTR("Network Connection"), 
2168                                                            (description 
!= NULL
) ? description 
: CFSTR("VPN Password"), 
2173                                 CFMutableDictionaryRef  newConfig
; 
2175                                 if (config 
!= NULL
) { 
2176                                         newConfig 
= CFDictionaryCreateMutableCopy(NULL
, 0, config
); 
2178                                         newConfig 
= CFDictionaryCreateMutable(NULL
, 
2180                                                                               &kCFTypeDictionaryKeyCallBacks
, 
2181                                                                               &kCFTypeDictionaryValueCallBacks
); 
2183                                 assert(newConfig 
!= NULL
); 
2184                                 CFDictionarySetValue(newConfig
, 
2185                                                      kSCPropNetVPNAuthPassword
, 
2187                                 CFDictionarySetValue(newConfig
, 
2188                                                      kSCPropNetVPNAuthPasswordEncryption
, 
2189                                                      kSCValNetVPNAuthPasswordEncryptionKeychain
); 
2190                                 ok 
= SCUserPreferencesSetInterfaceConfiguration(userPreferences
, interface
, newConfig
); 
2191                                 CFRelease(newConfig
); 
2194                         if (config      
!= NULL
) CFRelease(config
); 
2195                         if (description 
!= NULL
) CFRelease(description
); 
2196                         if (label       
!= NULL
) CFRelease(label
); 
2201                         _SCErrorSet(kSCStatusInvalidArgument
);