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