this repo has no description
at fixPythonPipStalling 673 lines 17 kB view raw
1/* 2 * Copyright (c) 2004-2007, 2009, 2010-2013, 2015-2018 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 "SCPreferencesInternal.h" 33#include "SCNetworkConfigurationInternal.h" 34 35#include <sys/ioctl.h> 36#include <net/if.h> 37 38 39__private_extern__ os_log_t 40__log_SCNetworkConfiguration(void) 41{ 42 static os_log_t log = NULL; 43 44 if (log == NULL) { 45 log = os_log_create("com.apple.SystemConfiguration", "SCNetworkConfiguration"); 46 } 47 48 return log; 49} 50 51 52__private_extern__ CFDictionaryRef 53__getPrefsConfiguration(SCPreferencesRef prefs, CFStringRef path) 54{ 55 CFDictionaryRef config; 56 CFIndex n; 57 58 config = SCPreferencesPathGetValue(prefs, path); 59 60 n = isA_CFDictionary(config) ? CFDictionaryGetCount(config) : 0; 61 switch (n) { 62 case 0 : 63 // ignore empty configuration entities 64 config = NULL; 65 break; 66 case 1 : 67 if (CFDictionaryContainsKey(config, kSCResvInactive)) { 68 // ignore [effectively] empty configuration entities 69 config = NULL; 70 } 71 break; 72 default : 73 break; 74 } 75 76 return config; 77} 78 79 80__private_extern__ Boolean 81__setPrefsConfiguration(SCPreferencesRef prefs, 82 CFStringRef path, 83 CFDictionaryRef config, 84 Boolean keepInactive) 85{ 86 CFDictionaryRef curConfig; 87 CFMutableDictionaryRef newConfig = NULL; 88 Boolean ok; 89 90 if ((config != NULL) && !isA_CFDictionary(config)) { 91 _SCErrorSet(kSCStatusInvalidArgument); 92 return FALSE; 93 } 94 95 curConfig = SCPreferencesPathGetValue(prefs, path); 96 97 if (config != NULL) { 98 newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); 99 } 100 101 if (keepInactive) { 102 if (config == NULL) { 103 newConfig = CFDictionaryCreateMutable(NULL, 104 0, 105 &kCFTypeDictionaryKeyCallBacks, 106 &kCFTypeDictionaryValueCallBacks); 107 } 108 109 if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) { 110 // if currently disabled 111 CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); 112 } else { 113 // if currently enabled 114 CFDictionaryRemoveValue(newConfig, kSCResvInactive); 115 } 116 } 117 118 // set new configuration 119 if (_SC_CFEqual(curConfig, newConfig)) { 120 // if no change 121 if (newConfig != NULL) CFRelease(newConfig); 122 ok = TRUE; 123 } else if (newConfig != NULL) { 124 // if new configuration (or we are preserving a disabled state) 125 ok = SCPreferencesPathSetValue(prefs, path, newConfig); 126 CFRelease(newConfig); 127 } else { 128 ok = SCPreferencesPathRemoveValue(prefs, path); 129 if (!ok && (SCError() == kSCStatusNoKey)) { 130 ok = TRUE; 131 } 132 } 133 134 return ok; 135} 136 137 138__private_extern__ Boolean 139__getPrefsEnabled(SCPreferencesRef prefs, CFStringRef path) 140{ 141 CFDictionaryRef config; 142 143 config = SCPreferencesPathGetValue(prefs, path); 144 if (isA_CFDictionary(config) && CFDictionaryContainsKey(config, kSCResvInactive)) { 145 return FALSE; 146 } 147 148 return TRUE; 149} 150 151 152__private_extern__ Boolean 153__setPrefsEnabled(SCPreferencesRef prefs, 154 CFStringRef path, 155 Boolean enabled) 156{ 157 CFDictionaryRef curConfig; 158 CFMutableDictionaryRef newConfig = NULL; 159 Boolean ok = FALSE; 160 161 // preserve current configuration 162 curConfig = SCPreferencesPathGetValue(prefs, path); 163 if (curConfig != NULL) { 164 if (!isA_CFDictionary(curConfig)) { 165 _SCErrorSet(kSCStatusFailed); 166 return FALSE; 167 } 168 newConfig = CFDictionaryCreateMutableCopy(NULL, 0, curConfig); 169 170 if (enabled) { 171 // enable 172 CFDictionaryRemoveValue(newConfig, kSCResvInactive); 173 } else { 174 // disable 175 CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); 176 } 177 } else { 178 if (!enabled) { 179 // disable 180 newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 181 CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); 182 } 183 } 184 185 // set new configuration 186 if (_SC_CFEqual(curConfig, newConfig)) { 187 // if no change 188 if (newConfig != NULL) CFRelease(newConfig); 189 ok = TRUE; 190 } else if (newConfig != NULL) { 191 // if updated configuration (or we are establishing as disabled) 192 ok = SCPreferencesPathSetValue(prefs, path, newConfig); 193 CFRelease(newConfig); 194 } else { 195 ok = SCPreferencesPathRemoveValue(prefs, path); 196 if (!ok && (SCError() == kSCStatusNoKey)) { 197 ok = TRUE; 198 } 199 } 200 201 return ok; 202} 203 204#if TARGET_OS_OSX 205#define SYSTEMCONFIGURATION_RESOURCES_PATH SYSTEMCONFIGURATION_FRAMEWORK_PATH "/Resources" 206#else 207#define SYSTEMCONFIGURATION_RESOURCES_PATH SYSTEMCONFIGURATION_FRAMEWORK_PATH 208#endif // TARGET_OS_OSX 209 210#define NETWORKCONFIGURATION_RESOURCE_FILE "NetworkConfiguration.plist" 211 212static CFDictionaryRef 213__copyTemplates() 214{ 215 CFBundleRef bundle; 216 CFDictionaryRef templates; 217 CFURLRef url; 218 219 bundle = _SC_CFBundleGet(); 220 if (bundle == NULL) { 221 return NULL; 222 } 223 224 url = CFBundleCopyResourceURL(bundle, CFSTR("NetworkConfiguration"), CFSTR("plist"), NULL); 225 if (url == NULL) { 226 SC_log(LOG_ERR, "failed to GET resource URL to \"%s\". Trying harder...", NETWORKCONFIGURATION_RESOURCE_FILE); 227 url = CFURLCreateWithFileSystemPath(NULL, 228 CFSTR(SYSTEMCONFIGURATION_RESOURCES_PATH 229 "/" 230 NETWORKCONFIGURATION_RESOURCE_FILE), 231 kCFURLPOSIXPathStyle, 232 TRUE); 233 234 if (url == NULL) { 235 SC_log(LOG_ERR, "failed to CREATE resource URL to \"%s\"", SYSTEMCONFIGURATION_RESOURCES_PATH 236 "/" 237 NETWORKCONFIGURATION_RESOURCE_FILE); 238 return NULL; 239 } 240 } 241 242 templates = _SCCreatePropertyListFromResource(url); 243 CFRelease(url); 244 245 if ((templates != NULL) && !isA_CFDictionary(templates)) { 246 CFRelease(templates); 247 return NULL; 248 } 249 250 return templates; 251} 252 253 254__private_extern__ CFDictionaryRef 255__copyInterfaceTemplate(CFStringRef interfaceType, 256 CFStringRef childInterfaceType) 257{ 258 CFDictionaryRef interface = NULL; 259 CFDictionaryRef interfaces; 260 CFDictionaryRef templates; 261 262 templates = __copyTemplates(); 263 if (templates == NULL) { 264 return NULL; 265 } 266 267 interfaces = CFDictionaryGetValue(templates, CFSTR("Interface")); 268 if (!isA_CFDictionary(interfaces)) { 269 CFRelease(templates); 270 return NULL; 271 } 272 273 if (childInterfaceType == NULL) { 274 interface = CFDictionaryGetValue(interfaces, interfaceType); 275 } else { 276 CFStringRef expandedType; 277 278 if (CFStringFind(childInterfaceType, CFSTR("."), 0).location != kCFNotFound) { 279 // if "vendor" type 280 childInterfaceType = CFSTR("*"); 281 } 282 283 expandedType = CFStringCreateWithFormat(NULL, 284 NULL, 285 CFSTR("%@-%@"), 286 interfaceType, 287 childInterfaceType); 288 interface = CFDictionaryGetValue(interfaces, expandedType); 289 CFRelease(expandedType); 290 } 291 292 if (isA_CFDictionary(interface) && (CFDictionaryGetCount(interface) > 0)) { 293 CFRetain(interface); 294 } else { 295 interface = NULL; 296 } 297 298 CFRelease(templates); 299 300 return interface; 301} 302 303 304__private_extern__ CFDictionaryRef 305__copyProtocolTemplate(CFStringRef interfaceType, 306 CFStringRef childInterfaceType, 307 CFStringRef protocolType) 308{ 309 CFDictionaryRef interface = NULL; 310 CFDictionaryRef protocol = NULL; 311 CFDictionaryRef protocols; 312 CFDictionaryRef templates; 313 314 templates = __copyTemplates(); 315 if (templates == NULL) { 316 return NULL; 317 } 318 319 protocols = CFDictionaryGetValue(templates, CFSTR("Protocol")); 320 if (!isA_CFDictionary(protocols)) { 321 CFRelease(templates); 322 return NULL; 323 } 324 325 if (childInterfaceType == NULL) { 326 interface = CFDictionaryGetValue(protocols, interfaceType); 327 } else { 328 CFStringRef expandedType; 329 330 if (CFStringFind(childInterfaceType, CFSTR("."), 0).location != kCFNotFound) { 331 // if "vendor" type 332 childInterfaceType = CFSTR("*"); 333 } 334 335 expandedType = CFStringCreateWithFormat(NULL, 336 NULL, 337 CFSTR("%@-%@"), 338 interfaceType, 339 childInterfaceType); 340 interface = CFDictionaryGetValue(protocols, expandedType); 341 CFRelease(expandedType); 342 } 343 344 if (isA_CFDictionary(interface)) { 345 protocol = CFDictionaryGetValue(interface, protocolType); 346 if (isA_CFDictionary(protocol)) { 347 CFRetain(protocol); 348 } else { 349 protocol = NULL; 350 } 351 } 352 353 CFRelease(templates); 354 355 return protocol; 356} 357 358 359__private_extern__ Boolean 360__createInterface(int s, CFStringRef interface) 361{ 362 struct ifreq ifr; 363 364 memset(&ifr, 0, sizeof(ifr)); 365 (void) _SC_cfstring_to_cstring(interface, 366 ifr.ifr_name, 367 sizeof(ifr.ifr_name), 368 kCFStringEncodingASCII); 369 370 if (ioctl(s, SIOCIFCREATE, &ifr) == -1) { 371 SC_log(LOG_NOTICE, "could not create interface \"%@\": %s", 372 interface, 373 strerror(errno)); 374 return FALSE; 375 } 376 377 return TRUE; 378} 379 380 381__private_extern__ Boolean 382__destroyInterface(int s, CFStringRef interface) 383{ 384 struct ifreq ifr; 385 386 memset(&ifr, 0, sizeof(ifr)); 387 (void) _SC_cfstring_to_cstring(interface, 388 ifr.ifr_name, 389 sizeof(ifr.ifr_name), 390 kCFStringEncodingASCII); 391 392 if (ioctl(s, SIOCIFDESTROY, &ifr) == -1) { 393 SC_log(LOG_NOTICE, "could not destroy interface \"%@\": %s", 394 interface, 395 strerror(errno)); 396 return FALSE; 397 } 398 399 return TRUE; 400} 401 402 403/* 404 * For rdar://problem/4685223 405 * 406 * To keep MoreSCF happy we need to ensure that the first "Set" and 407 * "NetworkService" have a [less than] unique identifier that can 408 * be parsed as a numeric string. 409 * 410 * Note: this backwards compatibility code must be enabled using the 411 * following command: 412 * 413 * sudo defaults write \ 414 * /Library/Preferences/SystemConfiguration/preferences \ 415 * MoreSCF \ 416 * -bool true 417 */ 418__private_extern__ 419CFStringRef 420__SCPreferencesPathCreateUniqueChild_WithMoreSCFCompatibility(SCPreferencesRef prefs, CFStringRef prefix) 421{ 422 static int hack = -1; 423 CFStringRef path = NULL; 424 425 if (hack < 0) { 426 CFBooleanRef enable; 427 428 enable = SCPreferencesGetValue(prefs, CFSTR("MoreSCF")); 429 hack = (isA_CFBoolean(enable) && CFBooleanGetValue(enable)) ? 1 : 0; 430 } 431 432 if (hack > 0) { 433 CFDictionaryRef dict; 434 Boolean ok; 435 436 path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), prefix, CFSTR("0")); 437 dict = SCPreferencesPathGetValue(prefs, path); 438 if (dict != NULL) { 439 // if path "0" exists 440 CFRelease(path); 441 return NULL; 442 } 443 444 // unique child with path "0" does not exist, create 445 dict = CFDictionaryCreate(NULL, 446 NULL, NULL, 0, 447 &kCFTypeDictionaryKeyCallBacks, 448 &kCFTypeDictionaryValueCallBacks); 449 ok = SCPreferencesPathSetValue(prefs, path, dict); 450 CFRelease(dict); 451 if (!ok) { 452 // if create failed 453 CFRelease(path); 454 return NULL; 455 } 456 } 457 458 return path; 459} 460 461 462static CFDataRef 463__copy_legacy_password(CFTypeRef password) 464{ 465 if (password == NULL) { 466 return NULL; 467 } 468 469 if (isA_CFData(password)) { 470 CFIndex n; 471 472 n = CFDataGetLength(password); 473 if ((n % sizeof(UniChar)) == 0) { 474 CFStringEncoding encoding; 475 CFStringRef str; 476 477#if __BIG_ENDIAN__ 478 encoding = (*(CFDataGetBytePtr(password) + 1) == 0x00) ? kCFStringEncodingUTF16LE : kCFStringEncodingUTF16BE; 479#else // __LITTLE_ENDIAN__ 480 encoding = (*(CFDataGetBytePtr(password) ) == 0x00) ? kCFStringEncodingUTF16BE : kCFStringEncodingUTF16LE; 481#endif 482 str = CFStringCreateWithBytes(NULL, 483 (const UInt8 *)CFDataGetBytePtr(password), 484 n, 485 encoding, 486 FALSE); 487 password = CFStringCreateExternalRepresentation(NULL, 488 str, 489 kCFStringEncodingUTF8, 490 0); 491 CFRelease(str); 492 } else { 493 password = NULL; 494 } 495 } else if (isA_CFString(password) && (CFStringGetLength(password) > 0)) { 496 // convert password to CFData 497 password = CFStringCreateExternalRepresentation(NULL, 498 password, 499 kCFStringEncodingUTF8, 500 0); 501 } else { 502 password = NULL; 503 } 504 505 return password; 506} 507 508 509__private_extern__ 510Boolean 511__extract_password(SCPreferencesRef prefs, 512 CFDictionaryRef config, 513 CFStringRef passwordKey, 514 CFStringRef encryptionKey, 515 CFStringRef encryptionKeyChainValue, 516 CFStringRef unique_id, 517 CFDataRef *password) 518{ 519 CFStringRef encryption = NULL; 520 Boolean exists = FALSE; 521 522 // check for keychain password 523 if (config != NULL) { 524 encryption = CFDictionaryGetValue(config, encryptionKey); 525 } 526 if ((encryption == NULL) || 527 (isA_CFString(encryption) && 528 CFEqual(encryption, encryptionKeyChainValue))) { 529 // check password 530 if (password != NULL) { 531 if (prefs != NULL) { 532 *password = _SCPreferencesSystemKeychainPasswordItemCopy(prefs, unique_id); 533 } else { 534 *password = _SCSecKeychainPasswordItemCopy(NULL, unique_id); 535 } 536 exists = (*password != NULL); 537 } else { 538 if (prefs != NULL) { 539 exists = _SCPreferencesSystemKeychainPasswordItemExists(prefs, unique_id); 540 } else { 541 exists = _SCSecKeychainPasswordItemExists(NULL, unique_id); 542 } 543 } 544 } 545 546 // as needed, check for in-line password 547 if (!exists && (encryption == NULL) && (config != NULL)) { 548 CFDataRef inline_password; 549 550 inline_password = CFDictionaryGetValue(config, passwordKey); 551 inline_password = __copy_legacy_password(inline_password); 552 if (inline_password != NULL) { 553 exists = TRUE; 554 555 if (password != NULL) { 556 *password = inline_password; 557 } else { 558 CFRelease(inline_password); 559 } 560 } 561 } 562 563 return exists; 564} 565 566 567__private_extern__ 568Boolean 569__remove_password(SCPreferencesRef prefs, 570 CFDictionaryRef config, 571 CFStringRef passwordKey, 572 CFStringRef encryptionKey, 573 CFStringRef encryptionKeyChainValue, 574 CFStringRef unique_id, 575 CFDictionaryRef *newConfig) 576{ 577 CFStringRef encryption = NULL; 578 Boolean ok = FALSE; 579 580 // check for keychain password 581 if (config != NULL) { 582 encryption = CFDictionaryGetValue(config, encryptionKey); 583 } 584 if ((encryption == NULL) || 585 (isA_CFString(encryption) && 586 CFEqual(encryption, encryptionKeyChainValue))) { 587 // remove keychain password 588 if (prefs != NULL) { 589 ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, unique_id); 590 } else { 591 ok = _SCSecKeychainPasswordItemRemove(NULL, unique_id); 592 } 593 } 594 595 // as needed, check if we have an in-line password that we can remove 596 if (!ok && (encryption == NULL) && (config != NULL)) { 597 CFDataRef inline_password; 598 599 inline_password = CFDictionaryGetValue(config, passwordKey); 600 inline_password = __copy_legacy_password(inline_password); 601 if (inline_password != NULL) { 602 CFRelease(inline_password); 603 ok = TRUE; 604 } 605 } 606 607 if (newConfig != NULL) { 608 if (ok && (config != NULL)) { 609 CFMutableDictionaryRef temp; 610 611 temp = CFDictionaryCreateMutableCopy(NULL, 0, config); 612 CFDictionaryRemoveValue(temp, passwordKey); 613 CFDictionaryRemoveValue(temp, encryptionKey); 614 *newConfig = (CFDictionaryRef)temp; 615 } else { 616 *newConfig = NULL; 617 } 618 } 619 620 return ok; 621} 622 623 624__private_extern__ Boolean 625__rank_to_str(SCNetworkServicePrimaryRank rank, CFStringRef *rankStr) 626{ 627 switch (rank) { 628 case kSCNetworkServicePrimaryRankDefault : 629 *rankStr = NULL; 630 break; 631 case kSCNetworkServicePrimaryRankFirst : 632 *rankStr = kSCValNetServicePrimaryRankFirst; 633 break; 634 case kSCNetworkServicePrimaryRankLast : 635 *rankStr = kSCValNetServicePrimaryRankLast; 636 break; 637 case kSCNetworkServicePrimaryRankNever : 638 *rankStr = kSCValNetServicePrimaryRankNever; 639 break; 640 case kSCNetworkServicePrimaryRankScoped : 641 *rankStr = kSCValNetServicePrimaryRankScoped; 642 break; 643 default : 644 return FALSE; 645 } 646 647 return TRUE; 648} 649 650 651__private_extern__ Boolean 652__str_to_rank(CFStringRef rankStr, SCNetworkServicePrimaryRank *rank) 653{ 654 if (isA_CFString(rankStr)) { 655 if (CFEqual(rankStr, kSCValNetServicePrimaryRankFirst)) { 656 *rank = kSCNetworkServicePrimaryRankFirst; 657 } else if (CFEqual(rankStr, kSCValNetServicePrimaryRankLast)) { 658 *rank = kSCNetworkServicePrimaryRankLast; 659 } else if (CFEqual(rankStr, kSCValNetServicePrimaryRankNever)) { 660 *rank = kSCNetworkServicePrimaryRankNever; 661 } else if (CFEqual(rankStr, kSCValNetServicePrimaryRankScoped)) { 662 *rank = kSCNetworkServicePrimaryRankScoped; 663 } else { 664 return FALSE; 665 } 666 } else if (rankStr == NULL) { 667 *rank = kSCNetworkServicePrimaryRankDefault; 668 } else { 669 return FALSE; 670 } 671 672 return TRUE; 673}