]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SCNetworkConfigurationInternal.c
configd-1109.101.1.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkConfigurationInternal.c
1 /*
2 * Copyright (c) 2004-2007, 2009, 2010-2013, 2015-2021 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Modification History
26 *
27 * May 27, 2004 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31
32 #include "SCNetworkConfigurationInternal.h"
33 #include "SCPreferencesInternal.h"
34
35 #include <sys/ioctl.h>
36 #include <net/if.h>
37
38
39 #pragma mark -
40 #pragma mark SCNetworkConfiguration logging
41
42
43 __private_extern__ os_log_t
44 __log_SCNetworkConfiguration(void)
45 {
46 static os_log_t log = NULL;
47
48 if (log == NULL) {
49 log = os_log_create("com.apple.SystemConfiguration", "SCNetworkConfiguration");
50 }
51
52 return log;
53 }
54
55
56 static void
57 logConfiguration_NetworkInterfaces(int level, const char *description, SCPreferencesRef prefs)
58 {
59 CFArrayRef interfaces;
60
61 interfaces = SCPreferencesGetValue(prefs, INTERFACES);
62 if (isA_CFArray(interfaces)) {
63 CFStringRef model = SCPreferencesGetValue(prefs, MODEL);
64 CFIndex n = CFArrayGetCount(interfaces);
65
66 SC_log(level, "%s%sinterfaces (%@)",
67 description != NULL ? description : "",
68 description != NULL ? " " : "",
69 model != NULL ? model : CFSTR("No model"));
70
71 for (CFIndex i = 0; i < n; i++) {
72 CFStringRef bsdName;
73 CFDictionaryRef dict;
74 CFDictionaryRef info;
75 CFStringRef name;
76
77 dict = CFArrayGetValueAtIndex(interfaces, i);
78 if (!isA_CFDictionary(dict)) {
79 continue;
80 }
81
82 bsdName = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceBSDName));
83 if (!isA_CFString(bsdName)) {
84 continue;
85 }
86
87 info = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceInfo));
88 name = CFDictionaryGetValue(info, kSCPropUserDefinedName);
89 SC_log(level, " %@ (%@)",
90 bsdName,
91 name != NULL ? name : CFSTR("???"));
92 }
93
94 }
95 }
96
97 static void
98 logConfiguration_preferences(int level, const char *description, SCPreferencesRef prefs)
99 {
100 CFStringRef model = SCPreferencesGetValue(prefs, MODEL);
101 CFIndex n;
102 CFMutableArrayRef orphans;
103 CFArrayRef services;
104 CFArrayRef sets;
105
106 SC_log(level, "%s%sconfiguration (%@)",
107 description != NULL ? description : "",
108 description != NULL ? " " : "",
109 model != NULL ? model : CFSTR("No model"));
110
111 services = SCNetworkServiceCopyAll(prefs);
112 if (services != NULL) {
113 orphans = CFArrayCreateMutableCopy(NULL, 0, services);
114 CFRelease(services);
115 } else {
116 orphans = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
117 }
118
119 sets = SCNetworkSetCopyAll(prefs);
120 if (sets != NULL) {
121 n = CFArrayGetCount(sets);
122 for (CFIndex i = 0; i < n; i++) {
123 SCNetworkSetRef set;
124
125 set = CFArrayGetValueAtIndex(sets, i);
126 SC_log(level, " Set %@ (%@)",
127 SCNetworkSetGetSetID(set),
128 SCNetworkSetGetName(set));
129
130 services = SCNetworkSetCopyServices(set);
131 if (services != NULL) {
132 CFIndex n;
133 CFIndex nOrder = 0;
134 CFArrayRef order;
135
136 order = SCNetworkSetGetServiceOrder(set);
137 if (order != NULL) {
138 nOrder = CFArrayGetCount(order);
139 }
140
141 n = CFArrayGetCount(services);
142 if (n > 1) {
143 CFMutableArrayRef sorted;
144
145 sorted = CFArrayCreateMutableCopy(NULL, 0, services);
146 CFArraySortValues(sorted,
147 CFRangeMake(0, CFArrayGetCount(sorted)),
148 _SCNetworkServiceCompare,
149 (void *)order);
150 CFRelease(services);
151 services = sorted;
152 }
153
154 for (CFIndex i = 0; i < n; i++) {
155 CFStringRef bsdName;
156 SCNetworkInterfaceRef interface;
157 CFIndex o;
158 CFIndex orderIndex = kCFNotFound;
159 SCNetworkServiceRef service;
160 CFStringRef serviceName;
161 CFStringRef serviceID;
162 CFStringRef userDefinedName;
163
164 service = CFArrayGetValueAtIndex(services, i);
165 serviceID = SCNetworkServiceGetServiceID(service);
166 serviceName = SCNetworkServiceGetName(service);
167 if (serviceName == NULL) serviceName = CFSTR("");
168
169 interface = SCNetworkServiceGetInterface(service);
170 bsdName = SCNetworkInterfaceGetBSDName(interface);
171
172 userDefinedName = __SCNetworkInterfaceGetUserDefinedName(interface);
173 if (_SC_CFEqual(serviceName, userDefinedName)) {
174 userDefinedName = NULL;
175 }
176
177 if (order != NULL) {
178 orderIndex = CFArrayGetFirstIndexOfValue(order,
179 CFRangeMake(0, nOrder),
180 serviceID);
181 }
182 if (orderIndex != kCFNotFound) {
183 SC_log(level, " Service %2ld : %@, %2d (%@%s%@%s%@)",
184 orderIndex + 1,
185 serviceID,
186 __SCNetworkInterfaceOrder(interface), // temp?
187 serviceName,
188 bsdName != NULL ? ", " : "",
189 bsdName != NULL ? bsdName : CFSTR(""),
190 userDefinedName != NULL ? " : " : "",
191 userDefinedName != NULL ? userDefinedName : CFSTR(""));
192 } else {
193 SC_log(level, " Service : %@, %2d (%@%s%@%s%@)",
194 serviceID,
195 __SCNetworkInterfaceOrder(interface), // temp?
196 serviceName,
197 bsdName != NULL ? ", " : "",
198 bsdName != NULL ? bsdName : CFSTR(""),
199 userDefinedName != NULL ? " : " : "",
200 userDefinedName != NULL ? userDefinedName : CFSTR(""));
201 }
202
203 o = CFArrayGetFirstIndexOfValue(orphans, CFRangeMake(0, CFArrayGetCount(orphans)), service);
204 if (o != kCFNotFound) {
205 CFArrayRemoveValueAtIndex(orphans, o);
206 }
207 }
208
209 CFRelease(services);
210 }
211 }
212
213 CFRelease(sets);
214 }
215
216 n = CFArrayGetCount(orphans);
217 if (n > 0) {
218 SC_log(level, " Orphans");
219
220 for (CFIndex i = 0; i < n; i++) {
221 CFStringRef bsdName;
222 SCNetworkInterfaceRef interface;
223 SCNetworkServiceRef service;
224 CFStringRef serviceName;
225 CFStringRef serviceID;
226
227 service = CFArrayGetValueAtIndex(orphans, i);
228 serviceID = SCNetworkServiceGetServiceID(service);
229 serviceName = SCNetworkServiceGetName(service);
230 if (serviceName == NULL) serviceName = CFSTR("");
231
232 interface = SCNetworkServiceGetInterface(service);
233 bsdName = SCNetworkInterfaceGetBSDName(interface);
234
235 SC_log(level, " Service : %@, %2d (%@%s%@)",
236 serviceID,
237 __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)), // temp?
238 serviceName,
239 bsdName != NULL ? ", " : "",
240 bsdName != NULL ? bsdName : CFSTR(""));
241 }
242 }
243 CFRelease(orphans);
244
245 return;
246 }
247
248 void
249 __SCNetworkConfigurationReport(int level, const char *description, SCPreferencesRef prefs, SCPreferencesRef ni_prefs)
250 {
251 logConfiguration_NetworkInterfaces(level, description, ni_prefs);
252 logConfiguration_preferences (level, description, prefs);
253 return;
254 }
255
256
257 #pragma mark -
258 #pragma mark Misc
259
260
261 static Boolean
262 isEffectivelyEmptyConfiguration(CFDictionaryRef config)
263 {
264 Boolean empty = FALSE;
265 CFIndex n;
266
267 n = isA_CFDictionary(config) ? CFDictionaryGetCount(config) : 0;
268 switch (n) {
269 case 0 :
270 // if no keys
271 empty = TRUE;
272 break;
273 case 1 :
274 if (CFDictionaryContainsKey(config, kSCResvInactive)) {
275 // ignore [effectively] empty configuration entities
276 empty = TRUE;
277 }
278 break;
279 default :
280 break;
281 }
282
283 return empty;
284 }
285
286
287 __private_extern__ CFDictionaryRef
288 __SCNetworkConfigurationGetValue(SCPreferencesRef prefs, CFStringRef path)
289 {
290 CFDictionaryRef config;
291
292 config = SCPreferencesPathGetValue(prefs, path);
293 if (isEffectivelyEmptyConfiguration(config)) {
294 // ignore [effectively] empty configuration entities
295 config = NULL;
296 }
297
298 return config;
299 }
300
301
302 __private_extern__ Boolean
303 __SCNetworkConfigurationSetValue(SCPreferencesRef prefs,
304 CFStringRef path,
305 CFDictionaryRef config,
306 Boolean keepInactive)
307 {
308 Boolean changed;
309 CFDictionaryRef curConfig;
310 CFMutableDictionaryRef newConfig = NULL;
311 Boolean ok;
312
313 if ((config != NULL) && !isA_CFDictionary(config)) {
314 _SCErrorSet(kSCStatusInvalidArgument);
315 return FALSE;
316 }
317
318 curConfig = SCPreferencesPathGetValue(prefs, path);
319 curConfig = isA_CFDictionary(curConfig);
320
321 if (config != NULL) {
322 newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
323 }
324
325 if (keepInactive) {
326 if (config == NULL) {
327 newConfig = CFDictionaryCreateMutable(NULL,
328 0,
329 &kCFTypeDictionaryKeyCallBacks,
330 &kCFTypeDictionaryValueCallBacks);
331 }
332
333 if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) {
334 // if currently disabled
335 CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
336 } else {
337 // if currently enabled
338 CFDictionaryRemoveValue(newConfig, kSCResvInactive);
339 }
340 }
341
342 // check if the configuration changed
343 changed = !_SC_CFEqual(curConfig, newConfig);
344
345 // set new configuration
346 if (!changed) {
347 // if no change
348 if (newConfig != NULL) CFRelease(newConfig);
349 ok = TRUE;
350 } else if (newConfig != NULL) {
351 // if new configuration (or we are preserving a disabled state), update the prefs
352 ok = SCPreferencesPathSetValue(prefs, path, newConfig);
353 CFRelease(newConfig);
354 } else {
355 // update the prefs
356 ok = SCPreferencesPathRemoveValue(prefs, path);
357 if (!ok && (SCError() == kSCStatusNoKey)) {
358 ok = TRUE;
359 }
360 }
361
362 return ok;
363 }
364
365
366 __private_extern__ Boolean
367 __getPrefsEnabled(SCPreferencesRef prefs, CFStringRef path)
368 {
369 CFDictionaryRef config;
370
371 config = SCPreferencesPathGetValue(prefs, path);
372 if (isA_CFDictionary(config) && CFDictionaryContainsKey(config, kSCResvInactive)) {
373 return FALSE;
374 }
375
376 return TRUE;
377 }
378
379
380 __private_extern__ Boolean
381 __setPrefsEnabled(SCPreferencesRef prefs,
382 CFStringRef path,
383 Boolean enabled)
384 {
385 Boolean changed;
386 CFDictionaryRef curConfig;
387 CFMutableDictionaryRef newConfig = NULL;
388 Boolean ok = FALSE;
389
390 // preserve current configuration
391 curConfig = SCPreferencesPathGetValue(prefs, path);
392 if (curConfig != NULL) {
393 if (!isA_CFDictionary(curConfig)) {
394 _SCErrorSet(kSCStatusFailed);
395 return FALSE;
396 }
397 newConfig = CFDictionaryCreateMutableCopy(NULL, 0, curConfig);
398
399 if (enabled) {
400 // enable
401 CFDictionaryRemoveValue(newConfig, kSCResvInactive);
402 } else {
403 // disable
404 CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
405 }
406 } else {
407 if (!enabled) {
408 // disable
409 newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
410 CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
411 }
412 }
413
414 // check if the configuration changed
415 changed = !_SC_CFEqual(curConfig, newConfig);
416
417 // set new configuration
418 if (!changed) {
419 // if no change
420 if (newConfig != NULL) CFRelease(newConfig);
421 ok = TRUE;
422 } else if (newConfig != NULL) {
423 // if updated configuration (or we are establishing as disabled)
424
425 ok = SCPreferencesPathSetValue(prefs, path, newConfig);
426 CFRelease(newConfig);
427 } else {
428 ok = SCPreferencesPathRemoveValue(prefs, path);
429 if (!ok && (SCError() == kSCStatusNoKey)) {
430 ok = TRUE;
431 }
432 }
433
434 return ok;
435 }
436
437 #if TARGET_OS_OSX
438 #define SYSTEMCONFIGURATION_RESOURCES_PATH SYSTEMCONFIGURATION_FRAMEWORK_PATH "/Resources"
439 #else
440 #define SYSTEMCONFIGURATION_RESOURCES_PATH SYSTEMCONFIGURATION_FRAMEWORK_PATH
441 #endif // TARGET_OS_OSX
442
443 #define NETWORKCONFIGURATION_RESOURCE_FILE "NetworkConfiguration.plist"
444
445 static CFDictionaryRef
446 __copyTemplates()
447 {
448 CFBundleRef bundle;
449 CFDictionaryRef templates;
450 CFURLRef url;
451
452 bundle = _SC_CFBundleGet();
453 if (bundle == NULL) {
454 return NULL;
455 }
456
457 url = CFBundleCopyResourceURL(bundle, CFSTR("NetworkConfiguration"), CFSTR("plist"), NULL);
458 if (url == NULL) {
459 SC_log(LOG_ERR, "failed to GET resource URL to \"%s\". Trying harder...", NETWORKCONFIGURATION_RESOURCE_FILE);
460 url = CFURLCreateWithFileSystemPath(NULL,
461 CFSTR(SYSTEMCONFIGURATION_RESOURCES_PATH
462 "/"
463 NETWORKCONFIGURATION_RESOURCE_FILE),
464 kCFURLPOSIXPathStyle,
465 TRUE);
466
467 if (url == NULL) {
468 SC_log(LOG_ERR, "failed to CREATE resource URL to \"%s\"", SYSTEMCONFIGURATION_RESOURCES_PATH
469 "/"
470 NETWORKCONFIGURATION_RESOURCE_FILE);
471 return NULL;
472 }
473 }
474
475 templates = _SCCreatePropertyListFromResource(url);
476 CFRelease(url);
477
478 if ((templates != NULL) && !isA_CFDictionary(templates)) {
479 CFRelease(templates);
480 return NULL;
481 }
482
483 return templates;
484 }
485
486
487 __private_extern__ CFDictionaryRef
488 __copyInterfaceTemplate(CFStringRef interfaceType,
489 CFStringRef childInterfaceType)
490 {
491 CFDictionaryRef interface = NULL;
492 CFDictionaryRef interfaces;
493 CFDictionaryRef templates;
494
495 templates = __copyTemplates();
496 if (templates == NULL) {
497 return NULL;
498 }
499
500 interfaces = CFDictionaryGetValue(templates, CFSTR("Interface"));
501 if (!isA_CFDictionary(interfaces)) {
502 CFRelease(templates);
503 return NULL;
504 }
505
506 if (childInterfaceType == NULL) {
507 interface = CFDictionaryGetValue(interfaces, interfaceType);
508 } else {
509 CFStringRef expandedType;
510
511 if (CFStringFind(childInterfaceType, CFSTR("."), 0).location != kCFNotFound) {
512 // if "vendor" type
513 childInterfaceType = CFSTR("*");
514 }
515
516 expandedType = CFStringCreateWithFormat(NULL,
517 NULL,
518 CFSTR("%@-%@"),
519 interfaceType,
520 childInterfaceType);
521 interface = CFDictionaryGetValue(interfaces, expandedType);
522 CFRelease(expandedType);
523 }
524
525 if (isA_CFDictionary(interface) && (CFDictionaryGetCount(interface) > 0)) {
526 CFRetain(interface);
527 } else {
528 interface = NULL;
529 }
530
531 CFRelease(templates);
532
533 return interface;
534 }
535
536
537 __private_extern__ CFDictionaryRef
538 __copyProtocolTemplate(CFStringRef interfaceType,
539 CFStringRef childInterfaceType,
540 CFStringRef protocolType)
541 {
542 CFDictionaryRef interface = NULL;
543 CFDictionaryRef protocol = NULL;
544 CFDictionaryRef protocols;
545 CFDictionaryRef templates;
546
547 templates = __copyTemplates();
548 if (templates == NULL) {
549 return NULL;
550 }
551
552 protocols = CFDictionaryGetValue(templates, CFSTR("Protocol"));
553 if (!isA_CFDictionary(protocols)) {
554 CFRelease(templates);
555 return NULL;
556 }
557
558 if (childInterfaceType == NULL) {
559 interface = CFDictionaryGetValue(protocols, interfaceType);
560 } else {
561 CFStringRef expandedType;
562
563 if (CFStringFind(childInterfaceType, CFSTR("."), 0).location != kCFNotFound) {
564 // if "vendor" type
565 childInterfaceType = CFSTR("*");
566 }
567
568 expandedType = CFStringCreateWithFormat(NULL,
569 NULL,
570 CFSTR("%@-%@"),
571 interfaceType,
572 childInterfaceType);
573 interface = CFDictionaryGetValue(protocols, expandedType);
574 CFRelease(expandedType);
575 }
576
577 if (isA_CFDictionary(interface)) {
578 protocol = CFDictionaryGetValue(interface, protocolType);
579 if (isA_CFDictionary(protocol)) {
580 CFRetain(protocol);
581 } else {
582 protocol = NULL;
583 }
584 }
585
586 CFRelease(templates);
587
588 return protocol;
589 }
590
591
592 __private_extern__ Boolean
593 __createInterface(int s, CFStringRef interface)
594 {
595 struct ifreq ifr;
596
597 memset(&ifr, 0, sizeof(ifr));
598 (void) _SC_cfstring_to_cstring(interface,
599 ifr.ifr_name,
600 sizeof(ifr.ifr_name),
601 kCFStringEncodingASCII);
602
603 if (ioctl(s, SIOCIFCREATE, &ifr) == -1) {
604 SC_log(LOG_NOTICE, "could not create interface \"%@\": %s",
605 interface,
606 strerror(errno));
607 return FALSE;
608 }
609
610 return TRUE;
611 }
612
613
614 __private_extern__ Boolean
615 __destroyInterface(int s, CFStringRef interface)
616 {
617 struct ifreq ifr;
618
619 memset(&ifr, 0, sizeof(ifr));
620 (void) _SC_cfstring_to_cstring(interface,
621 ifr.ifr_name,
622 sizeof(ifr.ifr_name),
623 kCFStringEncodingASCII);
624
625 if (ioctl(s, SIOCIFDESTROY, &ifr) == -1) {
626 SC_log(LOG_NOTICE, "could not destroy interface \"%@\": %s",
627 interface,
628 strerror(errno));
629 return FALSE;
630 }
631
632 return TRUE;
633 }
634
635
636 /*
637 * For rdar://problem/4685223
638 *
639 * To keep MoreSCF happy we need to ensure that the first "Set" and
640 * "NetworkService" have a [less than] unique identifier that can
641 * be parsed as a numeric string.
642 *
643 * Note: this backwards compatibility code must be enabled using the
644 * following command:
645 *
646 * sudo defaults write \
647 * /Library/Preferences/SystemConfiguration/preferences \
648 * MoreSCF \
649 * -bool true
650 */
651 __private_extern__
652 CFStringRef
653 __SCPreferencesPathCreateUniqueChild_WithMoreSCFCompatibility(SCPreferencesRef prefs, CFStringRef prefix)
654 {
655 static int hack = -1;
656 CFStringRef path = NULL;
657
658 if (hack < 0) {
659 CFBooleanRef enable;
660
661 enable = SCPreferencesGetValue(prefs, CFSTR("MoreSCF"));
662 hack = (isA_CFBoolean(enable) && CFBooleanGetValue(enable)) ? 1 : 0;
663 }
664
665 if (hack > 0) {
666 CFDictionaryRef dict;
667 Boolean ok;
668
669 path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), prefix, CFSTR("0"));
670 dict = SCPreferencesPathGetValue(prefs, path);
671 if (dict != NULL) {
672 // if path "0" exists
673 CFRelease(path);
674 return NULL;
675 }
676
677 // unique child with path "0" does not exist, create
678 dict = CFDictionaryCreate(NULL,
679 NULL, NULL, 0,
680 &kCFTypeDictionaryKeyCallBacks,
681 &kCFTypeDictionaryValueCallBacks);
682 ok = SCPreferencesPathSetValue(prefs, path, dict);
683 CFRelease(dict);
684 if (!ok) {
685 // if create failed
686 CFRelease(path);
687 return NULL;
688 }
689 }
690
691 return path;
692 }
693
694
695 static CFDataRef
696 __copy_legacy_password(CFTypeRef password)
697 {
698 if (password == NULL) {
699 return NULL;
700 }
701
702 if (isA_CFData(password)) {
703 CFIndex n;
704
705 n = CFDataGetLength(password);
706 if ((n % sizeof(UniChar)) == 0) {
707 CFStringEncoding encoding;
708 CFStringRef str;
709
710 #if __BIG_ENDIAN__
711 encoding = (*(CFDataGetBytePtr(password) + 1) == 0x00) ? kCFStringEncodingUTF16LE : kCFStringEncodingUTF16BE;
712 #else // __LITTLE_ENDIAN__
713 encoding = (*(CFDataGetBytePtr(password) ) == 0x00) ? kCFStringEncodingUTF16BE : kCFStringEncodingUTF16LE;
714 #endif
715 str = CFStringCreateWithBytes(NULL,
716 (const UInt8 *)CFDataGetBytePtr(password),
717 n,
718 encoding,
719 FALSE);
720 password = CFStringCreateExternalRepresentation(NULL,
721 str,
722 kCFStringEncodingUTF8,
723 0);
724 CFRelease(str);
725 } else {
726 password = NULL;
727 }
728 } else if (isA_CFString(password) && (CFStringGetLength(password) > 0)) {
729 // convert password to CFData
730 password = CFStringCreateExternalRepresentation(NULL,
731 password,
732 kCFStringEncodingUTF8,
733 0);
734 } else {
735 password = NULL;
736 }
737
738 return password;
739 }
740
741
742 __private_extern__
743 Boolean
744 __extract_password(SCPreferencesRef prefs,
745 CFDictionaryRef config,
746 CFStringRef passwordKey,
747 CFStringRef encryptionKey,
748 CFStringRef encryptionKeyChainValue,
749 CFStringRef unique_id,
750 CFDataRef *password)
751 {
752 CFStringRef encryption = NULL;
753 Boolean exists = FALSE;
754
755 // check for keychain password
756 if (config != NULL) {
757 encryption = CFDictionaryGetValue(config, encryptionKey);
758 }
759 if ((encryption == NULL) ||
760 (isA_CFString(encryption) &&
761 CFEqual(encryption, encryptionKeyChainValue))) {
762 // check password
763 if (password != NULL) {
764 if (prefs != NULL) {
765 *password = _SCPreferencesSystemKeychainPasswordItemCopy(prefs, unique_id);
766 } else {
767 *password = _SCSecKeychainPasswordItemCopy(NULL, unique_id);
768 }
769 exists = (*password != NULL);
770 } else {
771 if (prefs != NULL) {
772 exists = _SCPreferencesSystemKeychainPasswordItemExists(prefs, unique_id);
773 } else {
774 exists = _SCSecKeychainPasswordItemExists(NULL, unique_id);
775 }
776 }
777 }
778
779 // as needed, check for in-line password
780 if (!exists && (encryption == NULL) && (config != NULL)) {
781 CFDataRef inline_password;
782
783 inline_password = CFDictionaryGetValue(config, passwordKey);
784 inline_password = __copy_legacy_password(inline_password);
785 if (inline_password != NULL) {
786 exists = TRUE;
787
788 if (password != NULL) {
789 *password = inline_password;
790 } else {
791 CFRelease(inline_password);
792 }
793 }
794 }
795
796 return exists;
797 }
798
799
800 __private_extern__
801 Boolean
802 __remove_password(SCPreferencesRef prefs,
803 CFDictionaryRef config,
804 CFStringRef passwordKey,
805 CFStringRef encryptionKey,
806 CFStringRef encryptionKeyChainValue,
807 CFStringRef unique_id,
808 CFDictionaryRef *newConfig)
809 {
810 CFStringRef encryption = NULL;
811 Boolean ok = FALSE;
812
813 // check for keychain password
814 if (config != NULL) {
815 encryption = CFDictionaryGetValue(config, encryptionKey);
816 }
817 if ((encryption == NULL) ||
818 (isA_CFString(encryption) &&
819 CFEqual(encryption, encryptionKeyChainValue))) {
820 // remove keychain password
821 if (prefs != NULL) {
822 ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, unique_id);
823 } else {
824 ok = _SCSecKeychainPasswordItemRemove(NULL, unique_id);
825 }
826 }
827
828 // as needed, check if we have an in-line password that we can remove
829 if (!ok && (encryption == NULL) && (config != NULL)) {
830 CFDataRef inline_password;
831
832 inline_password = CFDictionaryGetValue(config, passwordKey);
833 inline_password = __copy_legacy_password(inline_password);
834 if (inline_password != NULL) {
835 CFRelease(inline_password);
836 ok = TRUE;
837 }
838 }
839
840 if (newConfig != NULL) {
841 if (ok && (config != NULL)) {
842 CFMutableDictionaryRef temp;
843
844 temp = CFDictionaryCreateMutableCopy(NULL, 0, config);
845 CFDictionaryRemoveValue(temp, passwordKey);
846 CFDictionaryRemoveValue(temp, encryptionKey);
847 *newConfig = (CFDictionaryRef)temp;
848 } else {
849 *newConfig = NULL;
850 }
851 }
852
853 return ok;
854 }
855
856
857 __private_extern__ Boolean
858 __rank_to_str(SCNetworkServicePrimaryRank rank, CFStringRef *rankStr)
859 {
860 switch (rank) {
861 case kSCNetworkServicePrimaryRankDefault :
862 *rankStr = NULL;
863 break;
864 case kSCNetworkServicePrimaryRankFirst :
865 *rankStr = kSCValNetServicePrimaryRankFirst;
866 break;
867 case kSCNetworkServicePrimaryRankLast :
868 *rankStr = kSCValNetServicePrimaryRankLast;
869 break;
870 case kSCNetworkServicePrimaryRankNever :
871 *rankStr = kSCValNetServicePrimaryRankNever;
872 break;
873 case kSCNetworkServicePrimaryRankScoped :
874 *rankStr = kSCValNetServicePrimaryRankScoped;
875 break;
876 default :
877 return FALSE;
878 }
879
880 return TRUE;
881 }
882
883
884 __private_extern__ Boolean
885 __str_to_rank(CFStringRef rankStr, SCNetworkServicePrimaryRank *rank)
886 {
887 if (isA_CFString(rankStr)) {
888 if (CFEqual(rankStr, kSCValNetServicePrimaryRankFirst)) {
889 *rank = kSCNetworkServicePrimaryRankFirst;
890 } else if (CFEqual(rankStr, kSCValNetServicePrimaryRankLast)) {
891 *rank = kSCNetworkServicePrimaryRankLast;
892 } else if (CFEqual(rankStr, kSCValNetServicePrimaryRankNever)) {
893 *rank = kSCNetworkServicePrimaryRankNever;
894 } else if (CFEqual(rankStr, kSCValNetServicePrimaryRankScoped)) {
895 *rank = kSCNetworkServicePrimaryRankScoped;
896 } else {
897 return FALSE;
898 }
899 } else if (rankStr == NULL) {
900 *rank = kSCNetworkServicePrimaryRankDefault;
901 } else {
902 return FALSE;
903 }
904
905 return TRUE;
906 }
907
908
909 #define kSCNetworkConfigurationFlagsBypassSystemInterfaces (1<<0)
910 #define kSCNetworkConfigurationFlagsBypassSystemInterfacesForced (1<<1)
911
912
913 Boolean
914 _SCNetworkConfigurationBypassSystemInterfaces(SCPreferencesRef prefs)
915 {
916 Boolean bypass;
917 uint32_t nc_flags;
918
919 nc_flags = __SCPreferencesGetNetworkConfigurationFlags(prefs);
920 bypass = ((nc_flags & kSCNetworkConfigurationFlagsBypassSystemInterfaces) != 0);
921 if (bypass ||
922 (nc_flags & kSCNetworkConfigurationFlagsBypassSystemInterfacesForced) != 0) {
923 // if bypass flag explicitly requested
924 return bypass;
925 }
926
927 if (!__SCPreferencesUsingDefaultPrefs(prefs)) {
928 // if not using the default prefs (i.e. /L/P/SC/preferences.plist)
929 return TRUE;
930 }
931
932 return FALSE;
933 }
934
935
936 void
937 _SCNetworkConfigurationSetBypassSystemInterfaces(SCPreferencesRef prefs, Boolean shouldBypass)
938 {
939 uint32_t nc_flags;
940
941 nc_flags = __SCPreferencesGetNetworkConfigurationFlags(prefs);
942 if (shouldBypass) {
943 nc_flags |= kSCNetworkConfigurationFlagsBypassSystemInterfaces;
944 } else {
945 nc_flags &= ~kSCNetworkConfigurationFlagsBypassSystemInterfaces;
946 }
947 nc_flags |= kSCNetworkConfigurationFlagsBypassSystemInterfacesForced;
948 __SCPreferencesSetNetworkConfigurationFlags(prefs, nc_flags);
949
950 return;
951 }
952
953