X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/authd/authtoken.c?ds=sidebyside diff --git a/authd/authtoken.c b/authd/authtoken.c deleted file mode 100644 index fe495354..00000000 --- a/authd/authtoken.c +++ /dev/null @@ -1,515 +0,0 @@ -/* Copyright (c) 2012 Apple Inc. All rights reserved. */ - -#include "authtoken.h" -#include "authd_private.h" -#include "process.h" -#include "authitems.h" -#include "debugging.h" -#include "authutilities.h" -#include "server.h" - -#include -#include -#include -#include - -static Boolean AuthTokenEqualCallBack(const void *value1, const void *value2) -{ - return (*(uint64_t*)value1) == (*(uint64_t*)value2); -} - -static CFHashCode AuthTokenHashCallBack(const void *value) -{ -// CFHashCode hash; -// AuthorizationBlob* blob = (AuthorizationBlob*)value; -// hash = blob->data[1]; -// hash <<= 32; -// hash |= blob->data[0]; -// return hash; - //quick 64 bit aligned version - return *((CFHashCode*)((AuthorizationBlob*)value)->data); -} - -const CFDictionaryKeyCallBacks kAuthTokenKeyCallBacks = { - .version = 0, - .retain = NULL, - .release = NULL, - .copyDescription = NULL, - .equal = &AuthTokenEqualCallBack, - .hash = &AuthTokenHashCallBack -}; - -struct _auth_token_s { - __AUTH_BASE_STRUCT_HEADER__; - - AuthorizationBlob blob; - auth_token_state_t state; - audit_info_s auditInfo; - dispatch_queue_t dispatch_queue; - - CFMutableSetRef processes; - - session_t session; - process_t creator; // weak reference, used for entitlement checking - mach_port_t creator_bootstrap_port; - - auth_items_t context; - - CFMutableSetRef credentials; - CFMutableSetRef authorized_rights; - - bool least_privileged; - bool appleSigned; - - bool sandboxed; - char * code_url; - - credential_t credential; -}; - -static void -_auth_token_finalize(CFTypeRef value) -{ - auth_token_t auth = (auth_token_t)value; - LOGV("authtoken: deallocated %p", auth); - - dispatch_barrier_sync(auth->dispatch_queue, ^{}); - - dispatch_release(auth->dispatch_queue); - CFReleaseSafe(auth->session); - CFReleaseSafe(auth->processes); - CFReleaseSafe(auth->context); - CFReleaseSafe(auth->credentials); - CFReleaseSafe(auth->authorized_rights); - free_safe(auth->code_url); - CFReleaseSafe(auth->credential); - - if (auth->creator_bootstrap_port != MACH_PORT_NULL) { - mach_port_deallocate(mach_task_self(), auth->creator_bootstrap_port); - } -} - -static Boolean -_auth_token_equal(CFTypeRef value1, CFTypeRef value2) -{ - auth_token_t auth1 = (auth_token_t)value1; - auth_token_t auth2 = (auth_token_t)value2; - - return memcmp(&auth1->blob, &auth2->blob, sizeof(AuthorizationBlob)) == 0; -} - -static CFStringRef -_auth_token_copy_description(CFTypeRef value) -{ - auth_token_t auth = (auth_token_t)value; - return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("auth_token: %p, uid=%i, pid=%i, processes=%li least_privileged=%i"), - auth, auth->auditInfo.euid, auth->auditInfo.pid, CFSetGetCount(auth->processes), auth->least_privileged); -} - -static CFHashCode -_auth_token_hash(CFTypeRef value) -{ - auth_token_t auth = (auth_token_t)value; - return *(CFHashCode*)&auth->blob; -} - -AUTH_TYPE_INSTANCE(auth_token, - .init = NULL, - .copy = NULL, - .finalize = _auth_token_finalize, - .equal = _auth_token_equal, - .hash = _auth_token_hash, - .copyFormattingDesc = NULL, - .copyDebugDesc = _auth_token_copy_description - ); - -static CFTypeID auth_token_get_type_id() { - static CFTypeID type_id = _kCFRuntimeNotATypeID; - static dispatch_once_t onceToken; - - dispatch_once(&onceToken, ^{ - type_id = _CFRuntimeRegisterClass(&_auth_type_auth_token); - }); - - return type_id; -} - -static auth_token_t -_auth_token_create(const audit_info_s * auditInfo, bool operateAsLeastPrivileged) -{ -#if __LLP64__ - __Check_Compile_Time(sizeof(CFHashCode) == sizeof(AuthorizationBlob)); -#endif - - auth_token_t auth = (auth_token_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, auth_token_get_type_id(), AUTH_CLASS_SIZE(auth_token), NULL); - require(auth != NULL, done); - - if (CCRandomCopyBytes(kCCRandomDefault, auth->blob.data, sizeof(auth->blob.data)) != kCCSuccess) { - LOGE("authtoken[%i]: failed to generate blob", auditInfo->pid); - CFReleaseNull(auth); - goto done; - } - - auth->context = auth_items_create(); - auth->auditInfo = *auditInfo; - auth->least_privileged = operateAsLeastPrivileged; - - auth->dispatch_queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - check(auth->dispatch_queue != NULL); - - auth->credentials = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks); - auth->authorized_rights = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks); - auth->processes = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL); - auth->creator_bootstrap_port = MACH_PORT_NULL; - - if (sandbox_check(auth->auditInfo.pid, "authorization-right-obtain", SANDBOX_CHECK_NO_REPORT) != 0) - auth->sandboxed = true; - else - auth->sandboxed = false; - -#if DEBUG - CFHashCode code = AuthTokenHashCallBack(&auth->blob); - if (memcmp(&code, auth->blob.data, sizeof(auth->blob.data)) != 0) { - LOGD("authtoken[%i]: blob = %x%01x", auth->auditInfo.pid, auth->blob.data[1], auth->blob.data[0]); - LOGD("authtoken[%i]: hash = %lx", auth->auditInfo.pid, code); - assert(false); - } -#endif - -done: - return auth; -} - -auth_token_t -auth_token_create(process_t proc, bool operateAsLeastPrivileged) -{ - auth_token_t auth = NULL; - require(proc != NULL, done); - - auth = _auth_token_create(process_get_audit_info(proc), operateAsLeastPrivileged); - require(auth != NULL, done); - - auth->creator = proc; - auth->session = (session_t)CFRetain(process_get_session(proc)); - auth->code_url = _copy_string(process_get_code_url(proc)); - auth->appleSigned = process_apple_signed(proc); - auth->creator_bootstrap_port = process_get_bootstrap(proc); - // This line grabs a reference to the send right to the bootstrap (our right to send to the bootstrap) - // This makes it critical to use the same call in reverse as we are only getting a ref to one right, - // but deallocate will free a ref to all 5 rights. - if (auth->creator_bootstrap_port != MACH_PORT_NULL) { - kern_return_t error_code = mach_port_mod_refs(mach_task_self(), auth->creator_bootstrap_port, MACH_PORT_RIGHT_SEND, 1); - if (error_code != KERN_SUCCESS) { - // If no reference to the mach port right can be obtained, we don't hold the copy, so mark it NULL again! - auth->creator_bootstrap_port = MACH_PORT_NULL; - } - } - - LOGV("authtoken[%i]: created %p", auth->auditInfo.pid, auth); - -done: - return auth; -} - -auth_token_t -auth_token_create_with_audit_info(const audit_info_s* info, bool operateAsLeastPrivileged) -{ - OSStatus status = errSecSuccess; - SecCodeRef code_Ref = NULL; - CFURLRef code_url = NULL; - - auth_token_t auth = NULL; - require(info != NULL, done); - - auth = _auth_token_create(info, operateAsLeastPrivileged); - require(auth != NULL, done); - - auth->session = server_find_copy_session(info->asid, true); - if (auth->session == NULL) { - LOGV("authtoken[%i]: failed to create session", auth->auditInfo.pid); - CFReleaseNull(auth); - goto done; - } - - CFMutableDictionaryRef codeDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFNumberRef codePid = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &auth->auditInfo.pid); - CFDictionarySetValue(codeDict, kSecGuestAttributePid, codePid); - status = SecCodeCopyGuestWithAttributes(NULL, codeDict, kSecCSDefaultFlags, &code_Ref); - CFReleaseSafe(codeDict); - CFReleaseSafe(codePid); - - if (status) { - LOGV("authtoken[%i]: failed to create code ref (%i)", auth->auditInfo.pid, status); - CFReleaseNull(auth); - goto done; - } - - if (SecCodeCopyPath(code_Ref, kSecCSDefaultFlags, &code_url) == errSecSuccess) { - auth->code_url = calloc(1u, PATH_MAX+1); - if (auth->code_url) { - CFURLGetFileSystemRepresentation(code_url, true, (UInt8*)auth->code_url, PATH_MAX); - } - } - - LOGV("authtoken[%i]: created %p for %s", auth->auditInfo.pid, auth, auth->code_url); - -done: - CFReleaseSafe(code_Ref); - CFReleaseSafe(code_url); - return auth; -} - -bool -auth_token_get_sandboxed(auth_token_t auth) -{ - return auth->sandboxed; -} - -const char * -auth_token_get_code_url(auth_token_t auth) -{ - return auth->code_url; -} - -const void * -auth_token_get_key(auth_token_t auth) -{ - return &auth->blob; -} - -auth_items_t -auth_token_get_context(auth_token_t auth) -{ - return auth->context; -} - -bool -auth_token_least_privileged(auth_token_t auth) -{ - return auth->least_privileged; -} - -uid_t -auth_token_get_uid(auth_token_t auth) -{ - return auth ? auth->auditInfo.euid : (uid_t)-2; -} - -pid_t -auth_token_get_pid(auth_token_t auth) -{ - return auth ? auth->auditInfo.pid : -1; -} - -session_t -auth_token_get_session(auth_token_t auth) -{ - return auth->session; -} - -const AuthorizationBlob * -auth_token_get_blob(auth_token_t auth) -{ - return &auth->blob; -} - -const audit_info_s * -auth_token_get_audit_info(auth_token_t auth) -{ - return &auth->auditInfo; -} - -mach_port_t -auth_token_get_creator_bootstrap(auth_token_t auth) -{ - return auth->creator_bootstrap_port; -} - -CFIndex -auth_token_add_process(auth_token_t auth, process_t proc) -{ - __block CFIndex count = 0; - dispatch_sync(auth->dispatch_queue, ^{ - CFSetAddValue(auth->processes, proc); - count = CFSetGetCount(auth->processes); - }); - return count; -} - -CFIndex -auth_token_remove_process(auth_token_t auth, process_t proc) -{ - __block CFIndex count = 0; - dispatch_sync(auth->dispatch_queue, ^{ - if (auth->creator == proc) { - auth->creator = NULL; - } - CFSetRemoveValue(auth->processes, proc); - count = CFSetGetCount(auth->processes); - }); - return count; -} - -CFIndex -auth_token_get_process_count(auth_token_t auth) -{ - __block CFIndex count = 0; - dispatch_sync(auth->dispatch_queue, ^{ - count = CFSetGetCount(auth->processes); - }); - return count; -} - -void -auth_token_set_credential(auth_token_t auth, credential_t cred) -{ - dispatch_sync(auth->dispatch_queue, ^{ - CFSetSetValue(auth->credentials, cred); - }); -} - -bool -auth_token_credentials_iterate(auth_token_t auth, credential_iterator_t iter) -{ - __block bool result = false; - - dispatch_sync(auth->dispatch_queue, ^{ - CFIndex count = CFSetGetCount(auth->credentials); - CFTypeRef values[count]; - CFSetGetValues(auth->credentials, values); - for (CFIndex i = 0; i < count; i++) { - credential_t cred = (credential_t)values[i]; - result = iter(cred); - if (!result) { - break; - } - } - }); - - return result; -} - -void -auth_token_set_right(auth_token_t auth, credential_t right) -{ - dispatch_sync(auth->dispatch_queue, ^{ - CFSetSetValue(auth->authorized_rights, right); - }); -} - -bool -auth_token_rights_iterate(auth_token_t auth, credential_iterator_t iter) -{ - __block bool result = false; - - dispatch_sync(auth->dispatch_queue, ^{ - CFIndex count = CFSetGetCount(auth->authorized_rights); - CFTypeRef values[count]; - CFSetGetValues(auth->authorized_rights, values); - for (CFIndex i = 0; i < count; i++) { - credential_t right = (credential_t)values[i]; - result = iter(right); - if (!result) { - break; - } - } - }); - - return result; -} - -CFTypeRef -auth_token_copy_entitlement_value(auth_token_t auth, const char * entitlement) -{ - __block CFTypeRef value = NULL; - dispatch_sync(auth->dispatch_queue, ^{ - if (auth->creator) { - value = process_copy_entitlement_value(auth->creator, entitlement); - } - }); - - return value; -} - -bool -auth_token_has_entitlement(auth_token_t auth, const char * entitlement) -{ - __block bool entitled = false; - - dispatch_sync(auth->dispatch_queue, ^{ - if (auth->creator) { - entitled = process_has_entitlement(auth->creator, entitlement); - } - }); - - return entitled; -} - -bool -auth_token_has_entitlement_for_right(auth_token_t auth, const char * right) -{ - __block bool entitled = false; - - dispatch_sync(auth->dispatch_queue, ^{ - if (auth->creator) { - entitled = process_has_entitlement_for_right(auth->creator, right); - } - }); - - return entitled; -} - -credential_t -auth_token_get_credential(auth_token_t auth) -{ - dispatch_sync(auth->dispatch_queue, ^{ - if (auth->credential == NULL) { - auth->credential = credential_create(auth->auditInfo.euid); - } - }); - - return auth->credential; -} - -bool -auth_token_apple_signed(auth_token_t auth) -{ - return auth->appleSigned; -} - -bool auth_token_is_creator(auth_token_t auth, process_t proc) -{ - __block bool creator = false; - if (proc) { - dispatch_sync(auth->dispatch_queue, ^{ - if (auth->creator == proc) { - creator = true; - } - }); - } - return creator; -} - -void auth_token_set_state(auth_token_t auth, auth_token_state_t state) -{ - auth->state |= state; -} - -void auth_token_clear_state(auth_token_t auth, auth_token_state_t state) -{ - auth->state &= ~state; -} - -auth_token_state_t auth_token_get_state(auth_token_t auth) -{ - return auth->state; -} - -bool auth_token_check_state(auth_token_t auth, auth_token_state_t state) -{ - if (state) { - return (auth->state & state) != 0; - } else { - return auth->state == 0; - } -}