1/* 2 * Copyright (c) 2014 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#include "authorize.h" 25#include "device.h" 26 27#include <libproc.h> 28#include <xpc/private.h> 29#include <IOKit/IOKitLib.h> 30 31static void __MessageCallback( xpc_connection_t connection, xpc_object_t message, pid_t processID, uint64_t authorizationID ) 32{ 33 xpc_type_t type; 34 35 type = xpc_get_type( message ); 36 37 if ( type == XPC_TYPE_DICTIONARY ) 38 { 39 uint64_t options; 40 uint64_t serviceID; 41 io_service_t service; 42 IOReturn status; 43 xpc_object_t reply; 44 45 options = xpc_dictionary_get_uint64( message, "options" ); 46 serviceID = xpc_dictionary_get_uint64( message, "service" ); 47 48 service = IOServiceGetMatchingService( kIOMasterPortDefault, IORegistryEntryIDMatching( serviceID ) ); 49 50 if ( service ) 51 { 52 if ( _DeviceIsValid( service ) ) 53 { 54 status = _Authorize( service, options, processID, authorizationID ); 55 } 56 else 57 { 58 status = kIOReturnUnsupported; 59 } 60 61 IOObjectRelease( service ); 62 } 63 else 64 { 65 status = kIOReturnBadArgument; 66 } 67 68 reply = xpc_dictionary_create_reply( message ); 69 70 if ( reply ) 71 { 72 xpc_dictionary_set_uint64( reply, "status", status ); 73 74 xpc_connection_send_message( connection, reply ); 75 } 76 } 77} 78 79static void __ConnectionCallback( xpc_connection_t connection ) 80{ 81 pid_t processID; 82 83 processID = xpc_connection_get_pid( connection ); 84 85 if ( processID ) 86 { 87 struct proc_uniqidentifierinfo authorizationID = { }; 88 89 proc_pidinfo( processID, PROC_PIDUNIQIDENTIFIERINFO, 0, &authorizationID, sizeof( authorizationID ) ); 90 91 if ( authorizationID.p_uniqueid ) 92 { 93 xpc_connection_set_event_handler( connection, ^( xpc_object_t message ) 94 { 95 __MessageCallback( connection, message, processID, authorizationID.p_uniqueid ); 96 } ); 97 98 xpc_connection_resume( connection ); 99 100 return; 101 } 102 } 103 104 xpc_connection_cancel( connection ); 105} 106 107int main( int argc __unused, const char * argv[ ] __unused ) 108{ 109 xpc_main( __ConnectionCallback ); 110 111 return 0; 112} 113