X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/914fc88e61be54aed6b18205ff2775b48793a3b6..866f8763175ff60e4fa455b92b5eb660a12fe6c7:/OSX/sec/ipc/server_security_helpers.c diff --git a/OSX/sec/ipc/server_security_helpers.c b/OSX/sec/ipc/server_security_helpers.c new file mode 100644 index 00000000..a982bbb1 --- /dev/null +++ b/OSX/sec/ipc/server_security_helpers.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2017 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 + +#include "server_security_helpers.h" +#include "server_entitlement_helpers.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __has_include() && TARGET_HAS_KEYSTORE +#include +#define HAVE_MOBILE_KEYBAG_SUPPORT 1 +#endif + +#if HAVE_MOBILE_KEYBAG_SUPPORT && TARGET_OS_EMBEDDED +static bool +device_is_multiuser(void) +{ + static dispatch_once_t once; + static bool result; + + dispatch_once(&once, ^{ + CFDictionaryRef deviceMode = MKBUserTypeDeviceMode(NULL, NULL); + CFTypeRef value = NULL; + + if (deviceMode && CFDictionaryGetValueIfPresent(deviceMode, kMKBDeviceModeKey, &value) && CFEqual(value, kMKBDeviceModeMultiUser)) { + result = true; + } + CFReleaseNull(deviceMode); + }); + + return result; +} +#endif /* HAVE_MOBILE_KEYBAG_SUPPORT && TARGET_OS_EMBEDDED */ + +void fill_security_client(SecurityClient * client, const uid_t uid, audit_token_t auditToken) { + if(!client) { + return; + } + + client->uid = uid; + +#if HAVE_MOBILE_KEYBAG_SUPPORT && TARGET_OS_EMBEDDED + + if (device_is_multiuser()) { + CFErrorRef error = NULL; + + client->inMultiUser = true; + client->activeUser = MKBForegroundUserSessionID(&error); + if (client->activeUser == -1 || client->activeUser == 0) { + assert(0); + client->activeUser = 0; + } + + /* + * If we are a edu mode user, and its not the active user, + * then the request is coming from inside the syncbubble. + * + * otherwise we are going to execute the request as the + * active user. + */ + + if (client->uid > 501 && (uid_t)client->activeUser != client->uid) { + secinfo("serverxpc", "securityd client: sync bubble user"); + client->musr = SecMUSRCreateSyncBubbleUserUUID(client->uid); + client->keybag = KEYBAG_DEVICE; + } else { + secinfo("serverxpc", "securityd client: active user"); + client->musr = SecMUSRCreateActiveUserUUID(client->activeUser); + client->uid = (uid_t)client->activeUser; + client->keybag = KEYBAG_DEVICE; + } + } +#endif + + client->task = SecTaskCreateWithAuditToken(kCFAllocatorDefault, auditToken); + +#if TARGET_OS_IPHONE + pthread_setspecific(taskThreadKey, client->task); +#endif + + client->accessGroups = SecTaskCopyAccessGroups(client->task); + +#if TARGET_OS_IPHONE + client->allowSystemKeychain = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementPrivateSystemKeychain); + client->isNetworkExtension = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementPrivateNetworkExtension); + client->canAccessNetworkExtensionAccessGroups = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementNetworkExtensionAccessGroups); +#endif +#if HAVE_MOBILE_KEYBAG_SUPPORT && TARGET_OS_EMBEDDED + if (client->inMultiUser) { + client->allowSyncBubbleKeychain = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementPrivateKeychainSyncBubble); + } +#endif +} +