Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
58 kB · 2236 lines
C
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237/* * Copyright (c) 2006-2012, 2015-2018 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */
#include <CoreFoundation/CoreFoundation.h>#include <CoreFoundation/CFRuntime.h>#include "SCNetworkConfigurationInternal.h"#include <notify.h>#include <pthread.h>
#pragma mark -#pragma mark SCUserPreferences
typedef struct {
// base CFType information CFRuntimeBase cfBase;
// serviceID CFStringRef serviceID;
// user preferences [unique] id CFStringRef prefsID;
} SCUserPreferencesPrivate, *SCUserPreferencesPrivateRef;
static CFStringRef __SCUserPreferencesCopyDescription (CFTypeRef cf);static void __SCUserPreferencesDeallocate (CFTypeRef cf);static Boolean __SCUserPreferencesEqual (CFTypeRef cf1, CFTypeRef cf2);static CFHashCode __SCUserPreferencesHash (CFTypeRef cf);
static CFTypeID __kSCUserPreferencesTypeID = _kCFRuntimeNotATypeID;
static const CFRuntimeClass __SCUserPreferencesClass = { 0, // version "SCUserPreferences", // className NULL, // init NULL, // copy __SCUserPreferencesDeallocate, // dealloc __SCUserPreferencesEqual, // equal __SCUserPreferencesHash, // hash NULL, // copyFormattingDesc __SCUserPreferencesCopyDescription // copyDebugDesc};
static pthread_once_t initialized = PTHREAD_ONCE_INIT;
static CFStringRef__SCUserPreferencesCopyDescription(CFTypeRef cf){ CFAllocatorRef allocator = CFGetAllocator(cf); CFMutableStringRef result; SCUserPreferencesPrivateRef prefsPrivate = (SCUserPreferencesPrivateRef)cf;
result = CFStringCreateMutable(allocator, 0); CFStringAppendFormat(result, NULL, CFSTR("<SCUserPreferences %p [%p]> {"), cf, allocator); CFStringAppendFormat(result, NULL, CFSTR("service = %@"), prefsPrivate->serviceID); CFStringAppendFormat(result, NULL, CFSTR(", id = %@"), prefsPrivate->prefsID); CFStringAppendFormat(result, NULL, CFSTR("}"));
return result;}
static void__SCUserPreferencesDeallocate(CFTypeRef cf){ SCUserPreferencesPrivateRef prefsPrivate = (SCUserPreferencesPrivateRef)cf;
/* release resources */
CFRelease(prefsPrivate->prefsID); CFRelease(prefsPrivate->serviceID);
return;}
static Boolean__SCUserPreferencesEqual(CFTypeRef cf1, CFTypeRef cf2){ SCUserPreferencesPrivateRef s1 = (SCUserPreferencesPrivateRef)cf1; SCUserPreferencesPrivateRef s2 = (SCUserPreferencesPrivateRef)cf2;
if (s1 == s2) return TRUE;
if (!CFEqual(s1->prefsID, s2->prefsID)) return FALSE; // if not the same [unique] prefs identifier
return TRUE;}
static CFHashCode__SCUserPreferencesHash(CFTypeRef cf){ SCUserPreferencesPrivateRef prefsPrivate = (SCUserPreferencesPrivateRef)cf;
return CFHash(prefsPrivate->prefsID);}
static void__SCUserPreferencesInitialize(void){ __kSCUserPreferencesTypeID = _CFRuntimeRegisterClass(&__SCUserPreferencesClass); return;}
static SCUserPreferencesPrivateRef__SCUserPreferencesCreatePrivate(CFAllocatorRef allocator, CFStringRef serviceID, CFStringRef prefsID){ SCUserPreferencesPrivateRef prefsPrivate; uint32_t size;
/* initialize runtime */ pthread_once(&initialized, __SCUserPreferencesInitialize);
/* allocate target */ size = sizeof(SCUserPreferencesPrivate) - sizeof(CFRuntimeBase); prefsPrivate = (SCUserPreferencesPrivateRef)_CFRuntimeCreateInstance(allocator, __kSCUserPreferencesTypeID, size, NULL); if (prefsPrivate == NULL) { return NULL; }
/* initialize non-zero/NULL members */ prefsPrivate->serviceID = CFStringCreateCopy(NULL, serviceID); prefsPrivate->prefsID = CFStringCreateCopy(NULL, prefsID);
return prefsPrivate;}
static __inline__ CFTypeRefisA_SCUserPreferences(CFTypeRef obj){ return (isA_CFType(obj, SCUserPreferencesGetTypeID()));}
#pragma mark -#pragma mark SCUserPreferences SPIs
#define USER_PREFERENCES_NOTIFICATION "com.apple.networkConnect"#define USER_PREFERENCES_APPLICATION_ID CFSTR("com.apple.networkConnect")#define USER_PREFERENCES_ID CFSTR("UniqueIdentifier")#define USER_PREFERENCES_DEFAULT CFSTR("ConnectByDefault")
#define LOG_CFPREFERENCES_CHANGES#ifdef LOG_CFPREFERENCES_CHANGES#include <fcntl.h>#include <unistd.h>#include <sys/stat.h>#include <sys/time.h>static voidlogCFPreferencesChange(CFStringRef serviceID, CFArrayRef newPreferences){ CFBooleanRef bVal; char dir[256]; CFArrayRef oldPreferences; CFStringRef str; CFStringRef trace; struct tm tm_now; struct timeval tv_now;
bVal = CFPreferencesCopyAppValue(CFSTR("LOG_SC_CHANGES"), USER_PREFERENCES_APPLICATION_ID); if (bVal != NULL) { Boolean enabled;
enabled = isA_CFBoolean(bVal) && CFBooleanGetValue(bVal); CFRelease(bVal); if (!enabled) { // if debugging not enabled return; } } else { // if debugging not enabled return; }
(void)gettimeofday(&tv_now, NULL); (void)localtime_r(&tv_now.tv_sec, &tm_now);
str = CFStringCreateWithFormat(NULL, NULL, CFSTR("/var/tmp/com.apple.networkConnect-%@-%4d%02d%02d.%02d%02d%02d.%03d"), serviceID, tm_now.tm_year + 1900, tm_now.tm_mon + 1, tm_now.tm_mday, tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec, tv_now.tv_usec / 1000); _SC_cfstring_to_cstring(str, dir, sizeof(dir), kCFStringEncodingUTF8); CFRelease(str);
SC_log(LOG_NOTICE, "CFPreferences being updated, old/new in \"%s\"", dir);
if (mkdir(dir, 0755) == -1) { SC_log(LOG_NOTICE, "mkdir() failed: %s", SCErrorString(errno)); return; }
trace = _SC_copyBacktrace(); if (trace != NULL) { FILE *f; int fd; char path[256];
strlcpy(path, dir, sizeof(path)); strlcat(path, "/backtrace", sizeof(path)); fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644); if (fd == -1) { SC_log(LOG_NOTICE, "fopen() failed: %s", SCErrorString(errno)); CFRelease(trace); return; } f = fdopen(fd, "w"); SCPrint(TRUE, f, CFSTR("%@"), trace); (void) fclose(f); CFRelease(trace); }
oldPreferences = CFPreferencesCopyAppValue(serviceID, USER_PREFERENCES_APPLICATION_ID); if (oldPreferences != NULL) { int fd; CFDataRef data; char path[256];
strlcpy(path, dir, sizeof(path)); strlcat(path, "/old", sizeof(path)); fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644); if (fd == -1) { SC_log(LOG_NOTICE, "fopen() failed: %s", SCErrorString(errno)); CFRelease(oldPreferences); return; } data = CFPropertyListCreateData(NULL, oldPreferences, kCFPropertyListXMLFormat_v1_0, 0, NULL); if (data == NULL) { SC_log(LOG_NOTICE, "CFPropertyListCreateData() failed"); close(fd); CFRelease(oldPreferences); return; } (void) write(fd, CFDataGetBytePtr(data), CFDataGetLength(data)); (void) close(fd); CFRelease(data); CFRelease(oldPreferences); }
if (newPreferences != NULL) { int fd; CFDataRef data; char path[256];
strlcpy(path, dir, sizeof(path)); strlcat(path, "/new", sizeof(path)); fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644); if (fd == -1) { SC_log(LOG_NOTICE, "fopen() failed: %s", SCErrorString(errno)); return; } data = CFPropertyListCreateData(NULL, newPreferences, kCFPropertyListXMLFormat_v1_0, 0, NULL); if (data == NULL) { SC_log(LOG_NOTICE, "CFPropertyListCreateData() failed"); close(fd); return; } (void) write(fd, CFDataGetBytePtr(data), CFDataGetLength(data)); (void) close(fd); CFRelease(data); }
return;}#endif // LOG_CFPREFERENCES_CHANGES
static CFArrayRefcopyCFPreferencesForServiceID(CFStringRef serviceID){ CFArrayRef prefs;
// fetch "Managed" or "ByHost" user preferences (void) CFPreferencesAppSynchronize(USER_PREFERENCES_APPLICATION_ID); prefs = CFPreferencesCopyAppValue(serviceID, USER_PREFERENCES_APPLICATION_ID);
if ((prefs != NULL) && !isA_CFArray(prefs)) { CFRelease(prefs); return NULL; }
return prefs;}
static BooleansetCFPreferencesForServiceID(CFStringRef serviceID, CFArrayRef newPreferences){ Boolean ok;
if (CFPreferencesAppValueIsForced(serviceID, USER_PREFERENCES_APPLICATION_ID)) { return FALSE; }
#ifdef LOG_CFPREFERENCES_CHANGES logCFPreferencesChange(serviceID, newPreferences);#endif // LOG_CFPREFERENCES_CHANGES
CFPreferencesSetValue(serviceID, newPreferences, USER_PREFERENCES_APPLICATION_ID, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); ok = CFPreferencesSynchronize(USER_PREFERENCES_APPLICATION_ID, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
(void) notify_post(USER_PREFERENCES_NOTIFICATION);
return ok;}
static voidaddPreference(CFMutableArrayRef *newPrefs, CFDictionaryRef newDict){ if (*newPrefs == NULL) { *newPrefs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } CFArrayAppendValue(*newPrefs, newDict);
return;}
typedef CFDictionaryRef (*processPreferencesCallout) (CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3);
static BooleanprocessPreferences(CFStringRef serviceID, processPreferencesCallout callout, void *context1, void *context2, void *context3){ Boolean changed = FALSE; CFIndex i; CFIndex n; CFDictionaryRef newDict = NULL; CFMutableArrayRef newPrefs = NULL; Boolean ok = TRUE; CFArrayRef prefs;
prefs = copyCFPreferencesForServiceID(serviceID); n = (prefs != NULL) ? CFArrayGetCount(prefs) : 0; for (i = 0; i < n; i++) { CFDictionaryRef dict;
dict = CFArrayGetValueAtIndex(prefs, i); assert(dict != NULL); if (isA_CFDictionary(dict)) { newDict = (*callout)(serviceID, dict, context1, context2, context3); if (newDict == NULL) { // if entry to be removed changed = TRUE; continue; } } else { // if not a CFDictionary, leave as-is newDict = CFRetain(dict); }
if (!CFEqual(dict, newDict)) { changed = TRUE; }
addPreference(&newPrefs, newDict); CFRelease(newDict); } if (prefs != NULL) CFRelease(prefs);
newDict = (*callout)(serviceID, NULL, context1, context2, context3); if (newDict != NULL) { // if new entry changed = TRUE; addPreference(&newPrefs, newDict); CFRelease(newDict); }
if (changed) { ok = setCFPreferencesForServiceID(serviceID, newPrefs); } if (newPrefs != NULL) CFRelease(newPrefs);
return ok;}
static __inline__ BooleanisMatchingPrefsID(CFDictionaryRef dict, CFStringRef matchID){ CFStringRef prefsID;
prefsID = CFDictionaryGetValue(dict, USER_PREFERENCES_ID); if (isA_CFString(prefsID)) { if (CFEqual(prefsID, matchID)) { return TRUE; } }
return FALSE;}
CFTypeIDSCUserPreferencesGetTypeID(void){ pthread_once(&initialized, __SCUserPreferencesInitialize); /* initialize runtime */ return __kSCUserPreferencesTypeID;}
CFStringRefSCUserPreferencesGetUniqueID(SCUserPreferencesRef userPreferences){ SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
return userPrivate->prefsID;}
BooleanSCUserPreferencesIsForced(SCUserPreferencesRef userPreferences){ SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
return CFPreferencesAppValueIsForced(userPrivate->serviceID, USER_PREFERENCES_APPLICATION_ID);}
static CFDictionaryRefremoveCallout(CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3){#pragma unused(serviceID)#pragma unused(context2)#pragma unused(context3) CFStringRef matchID = (CFStringRef)context1;
if (current == NULL) { // we have nothing to "add" return NULL; }
if (isMatchingPrefsID(current, matchID)) { // if we match, don't add (i.e. remove) return NULL; }
return CFRetain(current);}
BooleanSCUserPreferencesRemove(SCUserPreferencesRef userPreferences){ SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
return processPreferences(userPrivate->serviceID, removeCallout, (void *)userPrivate->prefsID, NULL, NULL);}
static CF_RETURNS_RETAINED CFDictionaryRefsetCurrentCallout(CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3){#pragma unused(serviceID)#pragma unused(context2)#pragma unused(context3) CFStringRef matchID = (CFStringRef)context1; CFMutableDictionaryRef newDict;
if (current == NULL) { // we have nothing to "add" return NULL; }
newDict = CFDictionaryCreateMutableCopy(NULL, 0, current);
// remove "default" flag CFDictionaryRemoveValue(newDict, USER_PREFERENCES_DEFAULT);
if (isMatchingPrefsID(current, matchID)) { // if we match, set "default" flag CFDictionarySetValue(newDict, USER_PREFERENCES_DEFAULT, kCFBooleanTrue); }
return newDict;}
BooleanSCUserPreferencesSetCurrent(SCUserPreferencesRef userPreferences){ SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
return processPreferences(userPrivate->serviceID, setCurrentCallout, (void *)userPrivate->prefsID, NULL, NULL);}
static CFDictionaryRefcopyNameCallout(CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3){#pragma unused(serviceID)#pragma unused(context2)#pragma unused(context3) CFStringRef matchID = (CFStringRef)context1; CFStringRef *name = (CFStringRef *)context3;
if (current == NULL) { // we have nothing to "add" return NULL; }
if (isMatchingPrefsID(current, matchID)) { if (*name != NULL) { CFRelease(*name); *name = NULL; } *name = CFDictionaryGetValue(current, kSCPropUserDefinedName);
// for backwards compatibility, we also check for the name in the PPP entity if (*name == NULL) { CFDictionaryRef ppp;
ppp = CFDictionaryGetValue(current, kSCEntNetPPP); if (isA_CFDictionary(ppp)) { *name = CFDictionaryGetValue(ppp, kSCPropUserDefinedName); } }
*name = isA_CFString(*name); if (*name != NULL) { CFRetain(*name); } }
return CFRetain(current);}
CFStringRefSCUserPreferencesCopyName(SCUserPreferencesRef userPreferences){ CFStringRef name = NULL; Boolean ok; SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
// find SCUserPreferences and copy name ok = processPreferences(userPrivate->serviceID, copyNameCallout, (void *)userPrivate->prefsID, NULL, (void *)&name); if (!ok) { if (name != NULL) { CFRelease(name); name = NULL; } }
return name;}
static CF_RETURNS_RETAINED CFDictionaryRefsetNameCallout(CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3){#pragma unused(serviceID)#pragma unused(context2)#pragma unused(context3) CFStringRef matchID = (CFStringRef)context1; CFMutableDictionaryRef newDict; CFStringRef newName = (CFStringRef)context2;
if (current == NULL) { // we have nothing to "add" return NULL; }
newDict = CFDictionaryCreateMutableCopy(NULL, 0, current);
if (isMatchingPrefsID(current, matchID)) { CFDictionaryRef pppEntity;
// set the name if (newName != NULL) { CFDictionarySetValue(newDict, kSCPropUserDefinedName, newName); } else { CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName); }
// for backwards compatibility, we also set the name in the PPP entity pppEntity = CFDictionaryGetValue(newDict, kSCEntNetPPP); if (isA_CFDictionary(pppEntity)) { CFMutableDictionaryRef newPPPEntity;
newPPPEntity = CFDictionaryCreateMutableCopy(NULL, 0, pppEntity); if (newName != NULL) { CFDictionarySetValue(newPPPEntity, kSCPropUserDefinedName, newName); } else { CFDictionaryRemoveValue(newPPPEntity, kSCPropUserDefinedName); } CFDictionarySetValue(newDict, kSCEntNetPPP, newPPPEntity); CFRelease(newPPPEntity); } }
return newDict;}
BooleanSCUserPreferencesSetName(SCUserPreferencesRef userPreferences, CFStringRef newName){ Boolean ok; SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
if ((newName != NULL) && !isA_CFString(newName)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
// find SCUserPreferences and set name ok = processPreferences(userPrivate->serviceID, setNameCallout, (void *)userPrivate->prefsID, (void *)newName, NULL);
return ok;}
static CFDictionaryRefcopyInterfaceConfigurationCallout(CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3){#pragma unused(serviceID) CFDictionaryRef *dict = (CFDictionaryRef *)context3; CFStringRef interfaceType = (CFStringRef)context2; CFStringRef matchID = (CFStringRef)context1;
if (current == NULL) { // we have nothing to "add" return NULL; }
if (isMatchingPrefsID(current, matchID)) { if (*dict != NULL) { CFRelease(*dict); *dict = NULL; } *dict = CFDictionaryGetValue(current, interfaceType); *dict = isA_CFDictionary(*dict); if (*dict != NULL) { CFRetain(*dict); } }
return CFRetain(current);}
CFDictionaryRefSCUserPreferencesCopyInterfaceConfiguration(SCUserPreferencesRef userPreferences, SCNetworkInterfaceRef interface){ CFStringRef defaultType; CFDictionaryRef entity = NULL; Boolean ok; SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
// get InterfaceType defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (defaultType == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
// find SCUserPreferences and copy interface entity ok = processPreferences(userPrivate->serviceID, copyInterfaceConfigurationCallout, (void *)userPrivate->prefsID, (void *)defaultType, (void *)&entity); if (!ok) { if (entity != NULL) { CFRelease(entity); entity = NULL; } }
return entity;}
static CF_RETURNS_RETAINED CFDictionaryRefsetInterfaceConfigurationCallout(CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3){#pragma unused(serviceID) CFStringRef interfaceType = (CFStringRef)context2; CFStringRef matchID = (CFStringRef)context1; CFMutableDictionaryRef newDict; CFDictionaryRef newOptions = (CFDictionaryRef)context3;
if (current == NULL) { // we have nothing to "add" return NULL; }
newDict = CFDictionaryCreateMutableCopy(NULL, 0, current);
if (isMatchingPrefsID(current, matchID)) { if (newOptions != NULL) { CFDictionarySetValue(newDict, interfaceType, newOptions);
// for backwards compatibility, we want to ensure that // the name is set in both the top level and in the PPP // entity. if (CFEqual(interfaceType, kSCEntNetPPP)) { CFStringRef name;
name = CFDictionaryGetValue(newOptions, kSCPropUserDefinedName); if (name != NULL) { // if name was passed in newOptions, push up CFDictionarySetValue(newDict, kSCPropUserDefinedName, name); } else { name = CFDictionaryGetValue(newDict, kSCPropUserDefinedName); if (name != NULL) { CFMutableDictionaryRef newPPPEntity;
// if name in parent, push into entity newPPPEntity = CFDictionaryCreateMutableCopy(NULL, 0, newOptions); CFDictionarySetValue(newPPPEntity, kSCPropUserDefinedName, name); CFDictionarySetValue(newDict, interfaceType, newPPPEntity); CFRelease(newPPPEntity); } } } } else { CFDictionaryRemoveValue(newDict, interfaceType); } }
return newDict;}
BooleanSCUserPreferencesSetInterfaceConfiguration(SCUserPreferencesRef userPreferences, SCNetworkInterfaceRef interface, CFDictionaryRef newOptions){ CFStringRef defaultType; Boolean ok; SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
// get InterfaceType defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (defaultType == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
// set new interface entity for SCUserPreferences ok = processPreferences(userPrivate->serviceID, setInterfaceConfigurationCallout, (void *)userPrivate->prefsID, (void *)defaultType, (void *)newOptions);
return ok;}
CFDictionaryRefSCUserPreferencesCopyExtendedInterfaceConfiguration(SCUserPreferencesRef userPreferences, SCNetworkInterfaceRef interface, CFStringRef extendedType){ CFDictionaryRef entity = NULL; Boolean ok; SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface, extendedType, FALSE)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
// find SCUserPreferences and copy interface entity ok = processPreferences(userPrivate->serviceID, copyInterfaceConfigurationCallout, (void *)userPrivate->prefsID, (void *)extendedType, (void *)&entity); if (!ok) { if (entity != NULL) { CFRelease(entity); entity = NULL; } }
return entity;}
BooleanSCUserPreferencesSetExtendedInterfaceConfiguration(SCUserPreferencesRef userPreferences, SCNetworkInterfaceRef interface, CFStringRef extendedType, CFDictionaryRef newOptions){ Boolean ok; SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface, extendedType, FALSE)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
// set new interface entity for SCUserPreferences ok = processPreferences(userPrivate->serviceID, setInterfaceConfigurationCallout, (void *)userPrivate->prefsID, (void *)extendedType, (void *)newOptions);
return ok;}
#pragma mark -#pragma mark SCNetworkConnection + SCUserPreferences SPIs
static CFDictionaryRefcopyAllCallout(CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3){#pragma unused(context1)#pragma unused(context2) CFMutableArrayRef *prefs = (CFMutableArrayRef *)context3; CFStringRef prefsID; SCUserPreferencesPrivateRef userPrivate;
if (current == NULL) { // we have nothing to "add" return NULL; }
prefsID = CFDictionaryGetValue(current, USER_PREFERENCES_ID); if (!isA_CFString(prefsID)) { // if no unique ID goto done; }
userPrivate = __SCUserPreferencesCreatePrivate(NULL, serviceID, prefsID); if (userPrivate != NULL) { if (*prefs == NULL) { *prefs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } CFArrayAppendValue(*prefs, (SCUserPreferencesRef)userPrivate); CFRelease(userPrivate); }
done :
return CFRetain(current);}
CFArrayRef /* of SCUserPreferencesRef's */SCNetworkConnectionCopyAllUserPreferences(SCNetworkConnectionRef connection){ Boolean ok; CFMutableArrayRef prefs = NULL; CFStringRef serviceID;
// get serviceID serviceID = SCNetworkConnectionCopyServiceID(connection);
// collect SCUserPreferences ok = processPreferences(serviceID, copyAllCallout, NULL, NULL, (void *)&prefs); if (!ok) { if (prefs != NULL) { CFRelease(prefs); prefs = NULL; } }
CFRelease(serviceID); return prefs;}
static CFDictionaryRefcopyCurrentCallout(CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3){#pragma unused(context1)#pragma unused(context2) CFBooleanRef isDefault; CFStringRef prefsID; SCUserPreferencesPrivateRef *userPrivate = (SCUserPreferencesPrivateRef *)context3;
if (current == NULL) { // we have nothing to "add" return NULL; }
prefsID = CFDictionaryGetValue(current, USER_PREFERENCES_ID); if (!isA_CFString(prefsID)) { // if no unique ID goto done; }
isDefault = CFDictionaryGetValue(current, USER_PREFERENCES_DEFAULT); if (!isA_CFBoolean(isDefault) || !CFBooleanGetValue(isDefault)) { // if not the default configuration goto done; }
*userPrivate = __SCUserPreferencesCreatePrivate(NULL, serviceID, prefsID);
done :
return CFRetain(current);}
SCUserPreferencesRefSCNetworkConnectionCopyCurrentUserPreferences(SCNetworkConnectionRef connection){ SCUserPreferencesRef current = NULL; Boolean ok; CFStringRef serviceID;
// get serviceID serviceID = SCNetworkConnectionCopyServiceID(connection);
// collect SCUserPreferences ok = processPreferences(serviceID, copyCurrentCallout, NULL, NULL, (void *)¤t); if (!ok) { if (current != NULL) { CFRelease(current); current = NULL; } }
CFRelease(serviceID); return current;}
static CFDictionaryRefcreateCallout(CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3){#pragma unused(serviceID)#pragma unused(context2)#pragma unused(context3) CFMutableDictionaryRef newDict; CFStringRef newPrefsID = (CFStringRef)context1;
if (current != NULL) { // don't change existing entries return CFRetain(current); }
newDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(newDict, USER_PREFERENCES_ID, newPrefsID); return newDict;}
SCUserPreferencesRefSCNetworkConnectionCreateUserPreferences(SCNetworkConnectionRef connection){ CFStringRef newPrefsID; CFStringRef serviceID; SCUserPreferencesPrivateRef userPrivate; CFUUIDRef uuid;
// get serviceID serviceID = SCNetworkConnectionCopyServiceID(connection);
// allocate a new user preferences ID uuid = CFUUIDCreate(NULL); newPrefsID = CFUUIDCreateString(NULL, uuid); CFRelease(uuid);
userPrivate = __SCUserPreferencesCreatePrivate(NULL, serviceID, newPrefsID); if (userPrivate != NULL) { (void) processPreferences(serviceID, createCallout, (void *)newPrefsID, NULL, NULL); }
CFRelease(newPrefsID); CFRelease(serviceID); return (SCUserPreferencesRef)userPrivate;}
static voidupdate_PPP_entity(SCUserPreferencesRef userPreferences, CFDictionaryRef *userOptions){ CFStringRef encryption; CFDictionaryRef entity; CFStringRef keychainID;
entity = CFDictionaryGetValue(*userOptions, kSCEntNetPPP); if (!isA_CFDictionary(entity)) { return; }
encryption = CFDictionaryGetValue(entity, kSCPropNetPPPAuthPasswordEncryption); if (encryption == NULL) { // provide default encryption method encryption = kSCValNetPPPAuthPasswordEncryptionKeychain; }
if (!isA_CFString(encryption) || !CFEqual(encryption, kSCValNetPPPAuthPasswordEncryptionKeychain)) { return; }
keychainID = CFDictionaryGetValue(entity, kSCPropNetPPPAuthPassword); if (isA_CFString(keychainID)) { // if password is keychain ID } else if (isA_CFData(keychainID) && ((CFDataGetLength((CFDataRef)keychainID) % sizeof(UniChar)) == 0)) { // if inline password return; } else { keychainID = SCUserPreferencesGetUniqueID(userPreferences); }
if (_SCSecKeychainPasswordItemExists(NULL, keychainID)) { CFMutableDictionaryRef new_entity; CFMutableDictionaryRef new_options;
// access PPP password from system keychain new_entity = CFDictionaryCreateMutableCopy(NULL, 0, entity);
CFDictionarySetValue(new_entity, kSCPropNetPPPAuthPassword, keychainID); CFDictionarySetValue(new_entity, kSCPropNetPPPAuthPasswordEncryption, kSCValNetPPPAuthPasswordEncryptionKeychain);
new_options = CFDictionaryCreateMutableCopy(NULL, 0, *userOptions); CFDictionarySetValue(new_options, kSCEntNetPPP, new_entity); CFRelease(new_entity);
CFRelease(*userOptions); *userOptions = new_options; }
return;}
static voidupdate_IPSec_entity(SCUserPreferencesRef userPreferences, CFDictionaryRef *userOptions){ CFStringRef encryption; CFDictionaryRef entity; SecKeychainRef keychain = NULL; CFStringRef keychainID; CFStringRef method; CFDataRef sharedSecret;
entity = CFDictionaryGetValue(*userOptions, kSCEntNetIPSec); if (!isA_CFDictionary(entity)) { return; }
method = CFDictionaryGetValue(entity, kSCPropNetIPSecAuthenticationMethod); if (!isA_CFString(method) || !CFEqual(method, kSCValNetIPSecAuthenticationMethodSharedSecret)) { return; }
encryption = CFDictionaryGetValue(entity, kSCPropNetIPSecSharedSecretEncryption); if (encryption == NULL) { // provide default encryption method encryption = kSCValNetIPSecSharedSecretEncryptionKeychain; }
if (!isA_CFString(encryption) || !CFEqual(encryption, kSCValNetIPSecSharedSecretEncryptionKeychain)) { return; }
keychainID = CFDictionaryGetValue(entity, kSCPropNetIPSecSharedSecret); if (isA_CFString(keychainID)) { // if shared secret is keychain ID CFRetain(keychainID); } else if (isA_CFData(keychainID) && ((CFDataGetLength((CFDataRef)keychainID) % sizeof(UniChar)) == 0)) { // if inline shared secret return; } else { CFStringRef unique_id;
unique_id = SCUserPreferencesGetUniqueID(userPreferences); keychainID = (CFStringRef)CFStringCreateMutableCopy(NULL, 0, unique_id); CFStringAppend((CFMutableStringRef)keychainID, CFSTR(".SS")); }
sharedSecret = _SCSecKeychainPasswordItemCopy(NULL, keychainID); if (sharedSecret != NULL) { CFMutableDictionaryRef new_entity; CFMutableDictionaryRef new_options; CFStringRef password;
// pass SharedSecret from user keychain new_entity = CFDictionaryCreateMutableCopy(NULL, 0, entity);
password = CFStringCreateWithBytes(NULL, CFDataGetBytePtr(sharedSecret), CFDataGetLength(sharedSecret), kCFStringEncodingUTF8, FALSE); CFRelease(sharedSecret); CFDictionarySetValue(new_entity, kSCPropNetIPSecSharedSecret, password); CFRelease(password); CFDictionaryRemoveValue(new_entity, kSCPropNetIPSecSharedSecretEncryption);
new_options = CFDictionaryCreateMutableCopy(NULL, 0, *userOptions); CFDictionarySetValue(new_options, kSCEntNetIPSec, new_entity); CFRelease(new_entity);
CFRelease(*userOptions); *userOptions = new_options; goto done; }
keychain = _SCSecKeychainCopySystemKeychain(); if (keychain == NULL) { goto done; }
if (_SCSecKeychainPasswordItemExists(keychain, keychainID)) { CFMutableDictionaryRef new_entity; CFMutableDictionaryRef new_options;
// access SharedSecret from system keychain new_entity = CFDictionaryCreateMutableCopy(NULL, 0, entity);
CFDictionarySetValue(new_entity, kSCPropNetIPSecSharedSecret, keychainID); CFDictionarySetValue(new_entity, kSCPropNetIPSecSharedSecretEncryption, kSCValNetIPSecSharedSecretEncryptionKeychain);
new_options = CFDictionaryCreateMutableCopy(NULL, 0, *userOptions); CFDictionarySetValue(new_options, kSCEntNetIPSec, new_entity); CFRelease(new_entity);
CFRelease(*userOptions); *userOptions = new_options; }
done :
if (keychain != NULL) CFRelease(keychain); CFRelease(keychainID); return;}
static CFDictionaryRefcopyOptionsCallout(CFStringRef serviceID, CFDictionaryRef current, void *context1, void *context2, void *context3){#pragma unused(serviceID)#pragma unused(context2) CFStringRef matchID = (CFStringRef)context1; CFMutableDictionaryRef *userOptions = (CFMutableDictionaryRef *)context3;
if (current == NULL) { // we have nothing to "add" return NULL; }
if (isMatchingPrefsID(current, matchID)) { // if we match, return options dictionary if (*userOptions != NULL) CFRelease(*userOptions); *userOptions = CFDictionaryCreateMutableCopy(NULL, 0, current); CFDictionaryRemoveValue(*userOptions, USER_PREFERENCES_ID); CFDictionaryRemoveValue(*userOptions, USER_PREFERENCES_DEFAULT); }
return CFRetain(current);}
BooleanSCNetworkConnectionStartWithUserPreferences(SCNetworkConnectionRef connection, SCUserPreferencesRef userPreferences, Boolean linger){ Boolean ok; CFDictionaryRef userOptions = NULL; SCUserPreferencesPrivateRef userPrivate = (SCUserPreferencesPrivateRef)userPreferences;
if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
(void) processPreferences(userPrivate->serviceID, copyOptionsCallout, (void *)userPrivate->prefsID, NULL, &userOptions);
/* * For some legacy preferences, some of the user options * were missing yet handled by the APIs. Make sure that * everything still works! */ if (userOptions != NULL) { update_PPP_entity (userPreferences, &userOptions); update_IPSec_entity(userPreferences, &userOptions); }
ok = SCNetworkConnectionStart(connection, userOptions, linger);
if (userOptions != NULL) { CFRelease(userOptions); }
return ok;}
#pragma mark -#pragma mark SCUserPreferences + SCNetworkInterface Password SPIs
static CFStringRefgetUserPasswordID(CFDictionaryRef config, SCUserPreferencesRef userPreferences){ CFStringRef unique_id = NULL;
if (config != NULL) { CFStringRef encryption;
encryption = CFDictionaryGetValue(config, kSCPropNetPPPAuthPasswordEncryption); if (isA_CFString(encryption) && CFEqual(encryption, kSCValNetPPPAuthPasswordEncryptionKeychain)) { unique_id = CFDictionaryGetValue(config, kSCPropNetPPPAuthPassword); } } if (unique_id == NULL) { unique_id = SCUserPreferencesGetUniqueID(userPreferences); }
return unique_id;}
static CFStringRefcopyUserSharedSecretID(CFDictionaryRef config, SCUserPreferencesRef userPreferences){ CFMutableStringRef sharedSecret = NULL;
if (config != NULL) { CFStringRef encryption;
encryption = CFDictionaryGetValue(config, kSCPropNetIPSecSharedSecretEncryption); if (isA_CFString(encryption) && CFEqual(encryption, kSCValNetIPSecSharedSecretEncryptionKeychain)) { sharedSecret = (CFMutableStringRef)CFDictionaryGetValue(config, kSCPropNetIPSecSharedSecret); if (sharedSecret != NULL) { CFRetain(sharedSecret); } } }
if (sharedSecret == NULL) { CFStringRef unique_id;
unique_id = getUserPasswordID(config, userPreferences); sharedSecret = CFStringCreateMutableCopy(NULL, 0, unique_id); CFStringAppend(sharedSecret, CFSTR(".SS")); }
return sharedSecret;}
static CFStringRefcopyUserXAuthID(CFDictionaryRef config, SCUserPreferencesRef userPreferences){ CFMutableStringRef xauth_id = NULL;
if (config != NULL) { CFStringRef encryption;
encryption = CFDictionaryGetValue(config, kSCPropNetIPSecXAuthPasswordEncryption); if (isA_CFString(encryption) && CFEqual(encryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain)) { xauth_id = (CFMutableStringRef)CFDictionaryGetValue(config, kSCPropNetIPSecXAuthPassword); if (xauth_id != NULL) { CFRetain(xauth_id); } } }
if (xauth_id == NULL) { CFStringRef unique_id;
unique_id = getUserPasswordID(config, userPreferences); xauth_id = CFStringCreateMutableCopy(NULL, 0, unique_id); CFStringAppend(xauth_id, CFSTR(".XAUTH")); }
return xauth_id;}
static BooleancheckUserPreferencesPassword(SCUserPreferencesRef userPreferences, SCNetworkInterfaceRef interface, SCNetworkInterfacePasswordType passwordType){ if (!isA_SCUserPreferences(userPreferences)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
switch (passwordType) { case kSCNetworkInterfacePasswordTypePPP : { CFStringRef interfaceType;
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (!CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } break; }
case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : { CFStringRef interfaceType;
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (!CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
interface = SCNetworkInterfaceGetInterface(interface); if (interface == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (!CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } break; }
case kSCNetworkInterfacePasswordTypeEAPOL : { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
case kSCNetworkInterfacePasswordTypeIPSecXAuth : { CFStringRef interfaceType;
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (!CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } break; }
case kSCNetworkInterfacePasswordTypeVPN : { CFStringRef interfaceType;
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (!CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } break; }
default : break; }
return TRUE;}
BooleanSCUserPreferencesCheckInterfacePassword(SCUserPreferencesRef userPreferences, SCNetworkInterfaceRef interface, SCNetworkInterfacePasswordType passwordType){ Boolean exists = FALSE;
if (!checkUserPreferencesPassword(userPreferences, interface, passwordType)) { return FALSE; }
switch (passwordType) { case kSCNetworkInterfacePasswordTypePPP : { CFDictionaryRef config; CFStringRef unique_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get userPreferences ID unique_id = getUserPasswordID(config, userPreferences);
// check exists = __extract_password(NULL, config, kSCPropNetPPPAuthPassword, kSCPropNetPPPAuthPasswordEncryption, kSCValNetPPPAuthPasswordEncryptionKeychain, unique_id, NULL);
if (config != NULL) CFRelease(config); break; }
case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : { CFDictionaryRef config; CFStringRef shared_id;
// get configuration config = SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences, interface, kSCEntNetIPSec);
// get sharedSecret ID shared_id = copyUserSharedSecretID(config, userPreferences);
// check exists = __extract_password(NULL, config, kSCPropNetIPSecSharedSecret, kSCPropNetIPSecSharedSecretEncryption, kSCValNetIPSecSharedSecretEncryptionKeychain, shared_id, NULL);
if (config != NULL) CFRelease(config); CFRelease(shared_id); break; }
case kSCNetworkInterfacePasswordTypeIPSecXAuth : { CFDictionaryRef config; CFStringRef xauth_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get XAuth ID xauth_id = copyUserXAuthID(config, userPreferences);
// check exists = __extract_password(NULL, config, kSCPropNetIPSecXAuthPassword, kSCPropNetIPSecXAuthPasswordEncryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain, xauth_id, NULL);
if (config != NULL) CFRelease(config); CFRelease(xauth_id); break; }
case kSCNetworkInterfacePasswordTypeVPN : { CFDictionaryRef config; CFStringRef unique_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get userPreferences ID unique_id = getUserPasswordID(config, userPreferences);
// check exists = __extract_password(NULL, config, kSCPropNetVPNAuthPassword, kSCPropNetVPNAuthPasswordEncryption, kSCValNetVPNAuthPasswordEncryptionKeychain, unique_id, NULL);
if (config != NULL) CFRelease(config); break; }
default : _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
return exists;}
CFDataRefSCUserPreferencesCopyInterfacePassword(SCUserPreferencesRef userPreferences, SCNetworkInterfaceRef interface, SCNetworkInterfacePasswordType passwordType){ CFDataRef password = NULL;
if (!checkUserPreferencesPassword(userPreferences, interface, passwordType)) { return FALSE; }
switch (passwordType) { case kSCNetworkInterfacePasswordTypePPP : { CFDictionaryRef config; CFStringRef unique_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get userPreferences ID unique_id = getUserPasswordID(config, userPreferences);
// extract (void) __extract_password(NULL, config, kSCPropNetPPPAuthPassword, kSCPropNetPPPAuthPasswordEncryption, kSCValNetPPPAuthPasswordEncryptionKeychain, unique_id, &password);
if (config != NULL) CFRelease(config); break; }
case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : { CFDictionaryRef config; CFStringRef shared_id;
// get configuration config = SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences, interface, kSCEntNetIPSec);
// get sharedSecret ID shared_id = copyUserSharedSecretID(config, userPreferences);
// extract (void) __extract_password(NULL, config, kSCPropNetIPSecSharedSecret, kSCPropNetIPSecSharedSecretEncryption, kSCValNetIPSecSharedSecretEncryptionKeychain, shared_id, &password);
if (config != NULL) CFRelease(config); CFRelease(shared_id); break; }
case kSCNetworkInterfacePasswordTypeIPSecXAuth : { CFDictionaryRef config; CFStringRef xauth_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get XAuth ID xauth_id = copyUserXAuthID(config, userPreferences);
// extract (void) __extract_password(NULL, config, kSCPropNetIPSecXAuthPassword, kSCPropNetIPSecXAuthPasswordEncryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain, xauth_id, &password);
if (config != NULL) CFRelease(config); CFRelease(xauth_id); break; }
case kSCNetworkInterfacePasswordTypeVPN : { CFDictionaryRef config; CFStringRef unique_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get userPreferences ID unique_id = getUserPasswordID(config, userPreferences);
// extract (void) __extract_password(NULL, config, kSCPropNetVPNAuthPassword, kSCPropNetVPNAuthPasswordEncryption, kSCValNetVPNAuthPasswordEncryptionKeychain, unique_id, &password);
if (config != NULL) CFRelease(config); break; }
default : _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
return password;}
BooleanSCUserPreferencesRemoveInterfacePassword(SCUserPreferencesRef userPreferences, SCNetworkInterfaceRef interface, SCNetworkInterfacePasswordType passwordType){ Boolean ok = FALSE;
if (!checkUserPreferencesPassword(userPreferences, interface, passwordType)) { return FALSE; }
switch (passwordType) { case kSCNetworkInterfacePasswordTypePPP : { CFDictionaryRef config; CFDictionaryRef newConfig = NULL; CFStringRef unique_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get userPreferences ID unique_id = getUserPasswordID(config, userPreferences);
// remove password ok = __remove_password(NULL, config, kSCPropNetPPPAuthPassword, kSCPropNetPPPAuthPasswordEncryption, kSCValNetPPPAuthPasswordEncryptionKeychain, unique_id, &newConfig); if (ok) { ok = SCUserPreferencesSetInterfaceConfiguration(userPreferences, interface, newConfig); if (newConfig != NULL) CFRelease(newConfig); }
if (config != NULL) CFRelease(config); break; }
case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : { CFDictionaryRef config; CFDictionaryRef newConfig = NULL; CFStringRef shared_id;
// get configuration config = SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences, interface, kSCEntNetIPSec);
// get sharedSecret ID shared_id = copyUserSharedSecretID(config, userPreferences);
// remove password ok = __remove_password(NULL, config, kSCPropNetIPSecSharedSecret, kSCPropNetIPSecSharedSecretEncryption, kSCValNetIPSecSharedSecretEncryptionKeychain, shared_id, &newConfig); if (ok) { ok = SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences, interface, kSCEntNetIPSec, newConfig); if (newConfig != NULL) CFRelease(newConfig); }
if (config != NULL) CFRelease(config); CFRelease(shared_id); break; }
case kSCNetworkInterfacePasswordTypeIPSecXAuth : { CFDictionaryRef config; CFDictionaryRef newConfig = NULL; CFStringRef xauth_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get XAuth ID xauth_id = copyUserXAuthID(config, userPreferences);
// remove password ok = __remove_password(NULL, config, kSCPropNetIPSecXAuthPassword, kSCPropNetIPSecXAuthPasswordEncryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain, xauth_id, &newConfig); if (ok) { ok = SCUserPreferencesSetInterfaceConfiguration(userPreferences, interface, newConfig); if (newConfig != NULL) CFRelease(newConfig); }
if (config != NULL) CFRelease(config); CFRelease(xauth_id); break; }
case kSCNetworkInterfacePasswordTypeVPN : { CFDictionaryRef config; CFDictionaryRef newConfig = NULL; CFStringRef unique_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get userPreferences ID unique_id = getUserPasswordID(config, userPreferences);
// remove password ok = __remove_password(NULL, config, kSCPropNetVPNAuthPassword, kSCPropNetVPNAuthPasswordEncryption, kSCValNetVPNAuthPasswordEncryptionKeychain, unique_id, &newConfig); if (ok) { ok = SCUserPreferencesSetInterfaceConfiguration(userPreferences, interface, newConfig); if (newConfig != NULL) CFRelease(newConfig); }
if (config != NULL) CFRelease(config); break; }
default : _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
return ok;}
BooleanSCUserPreferencesSetInterfacePassword(SCUserPreferencesRef userPreferences, SCNetworkInterfaceRef interface, SCNetworkInterfacePasswordType passwordType, CFDataRef password, CFDictionaryRef options){ CFStringRef account = NULL; CFBundleRef bundle; CFDictionaryRef config; CFStringRef description = NULL; CFStringRef label = NULL; Boolean ok = FALSE;
if (!checkUserPreferencesPassword(userPreferences, interface, passwordType)) { return FALSE; }
bundle = _SC_CFBundleGet();
switch (passwordType) { case kSCNetworkInterfacePasswordTypePPP : { CFStringRef unique_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get userPreferences ID unique_id = getUserPasswordID(config, userPreferences);
// User prefs auth name --> keychain "Account" if (config != NULL) { account = CFDictionaryGetValue(config, kSCPropNetPPPAuthName); }
// User prefs "name" --> keychain "Name" label = SCUserPreferencesCopyName(userPreferences);
// "PPP Password" --> keychain "Kind" if (bundle != NULL) { description = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"), CFSTR("PPP Password"), NULL); }
// store password ok = _SCSecKeychainPasswordItemSet(NULL, unique_id, (label != NULL) ? label : CFSTR("Network Connection"), (description != NULL) ? description : CFSTR("PPP Password"), account, password, options); if (ok) { CFMutableDictionaryRef newConfig;
if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } else { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newConfig, kSCPropNetPPPAuthPassword, unique_id); CFDictionarySetValue(newConfig, kSCPropNetPPPAuthPasswordEncryption, kSCValNetPPPAuthPasswordEncryptionKeychain); ok = SCUserPreferencesSetInterfaceConfiguration(userPreferences, interface, newConfig); CFRelease(newConfig); }
if (config != NULL) CFRelease(config); if (description != NULL) CFRelease(description); if (label != NULL) CFRelease(label); break; }
case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : { CFStringRef shared_id;
// get configuration config = SCUserPreferencesCopyExtendedInterfaceConfiguration(userPreferences, interface, kSCEntNetIPSec);
// get sharedSecret ID shared_id = copyUserSharedSecretID(config, userPreferences);
// User prefs "name" --> keychain "Name" label = SCUserPreferencesCopyName(userPreferences);
// "IPSec Shared Secret" --> keychain "Kind" if (bundle != NULL) { description = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"), CFSTR("IPSec Shared Secret"), NULL); }
// set password ok = _SCSecKeychainPasswordItemSet(NULL, shared_id, (label != NULL) ? label : CFSTR("Network Connection"), (description != NULL) ? description : CFSTR("IPSec Shared Secret"), NULL, password, options); if (ok) { CFMutableDictionaryRef newConfig = NULL;
if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } else { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newConfig, kSCPropNetIPSecSharedSecret, shared_id); CFDictionarySetValue(newConfig, kSCPropNetIPSecSharedSecretEncryption, kSCValNetIPSecSharedSecretEncryptionKeychain); ok = SCUserPreferencesSetExtendedInterfaceConfiguration(userPreferences, interface, kSCEntNetIPSec, newConfig); CFRelease(newConfig); }
if (config != NULL) CFRelease(config); if (description != NULL) CFRelease(description); if (label != NULL) CFRelease(label); CFRelease(shared_id); break; }
case kSCNetworkInterfacePasswordTypeIPSecXAuth : { CFStringRef xauth_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get XAuth ID xauth_id = copyUserXAuthID(config, userPreferences);
// User prefs XAuth name --> keychain "Account" if (config != NULL) { account = CFDictionaryGetValue(config, kSCPropNetIPSecXAuthName); }
// User prefs "name" --> keychain "Name" label = SCUserPreferencesCopyName(userPreferences);
// "IPSec XAuth Password" --> keychain "Kind" if (bundle != NULL) { description = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"), CFSTR("IPSec XAuth Password"), NULL); }
// store password ok = _SCSecKeychainPasswordItemSet(NULL, xauth_id, (label != NULL) ? label : CFSTR("Network Connection"), (description != NULL) ? description : CFSTR("IPSec XAuth Password"), account, password, options); if (ok) { CFMutableDictionaryRef newConfig;
if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } else { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newConfig, kSCPropNetIPSecXAuthPassword, xauth_id); CFDictionarySetValue(newConfig, kSCPropNetIPSecXAuthPasswordEncryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain); ok = SCUserPreferencesSetInterfaceConfiguration(userPreferences, interface, newConfig); CFRelease(newConfig); }
if (config != NULL) CFRelease(config); if (description != NULL) CFRelease(description); if (label != NULL) CFRelease(label); CFRelease(xauth_id); break; }
case kSCNetworkInterfacePasswordTypeVPN : { CFStringRef unique_id;
// get configuration config = SCUserPreferencesCopyInterfaceConfiguration(userPreferences, interface);
// get userPreferences ID unique_id = getUserPasswordID(config, userPreferences);
// User prefs auth name --> keychain "Account" if (config != NULL) { account = CFDictionaryGetValue(config, kSCPropNetVPNAuthName); }
// User prefs "name" --> keychain "Name" label = SCUserPreferencesCopyName(userPreferences);
// "VPN Password" --> keychain "Kind" if (bundle != NULL) { description = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"), CFSTR("VPN Password"), NULL); }
// store password ok = _SCSecKeychainPasswordItemSet(NULL, unique_id, (label != NULL) ? label : CFSTR("Network Connection"), (description != NULL) ? description : CFSTR("VPN Password"), account, password, options); if (ok) { CFMutableDictionaryRef newConfig;
if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } else { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } assert(newConfig != NULL); CFDictionarySetValue(newConfig, kSCPropNetVPNAuthPassword, unique_id); CFDictionarySetValue(newConfig, kSCPropNetVPNAuthPasswordEncryption, kSCValNetVPNAuthPasswordEncryptionKeychain); ok = SCUserPreferencesSetInterfaceConfiguration(userPreferences, interface, newConfig); CFRelease(newConfig); }
if (config != NULL) CFRelease(config); if (description != NULL) CFRelease(description); if (label != NULL) CFRelease(label); break; }
default : _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
return ok;}