1 /* Copyright (c) 2012-2013 Apple Inc. All Rights Reserved. */
9 #include "authd_private.h"
10 #include "connection.h"
12 #include <Security/Authorization.h>
15 #include <xpc/private.h>
16 #include <dispatch/dispatch.h>
21 #include <malloc/malloc.h>
25 security_auth_peer_event_handler(xpc_connection_t connection
, xpc_object_t event
)
27 __block OSStatus status
= errAuthorizationDenied
;
29 connection_t conn
= (connection_t
)xpc_connection_get_context(connection
);
30 require_action(conn
!= NULL
, done
, LOGE("xpc[%i]: process context not found", xpc_connection_get_pid(connection
)));
34 xpc_type_t type
= xpc_get_type(event
);
36 if (type
== XPC_TYPE_ERROR
) {
37 if (event
== XPC_ERROR_CONNECTION_INVALID
) {
38 // The client process on the other end of the connection has either
39 // crashed or cancelled the connection. After receiving this error,
40 // the connection is in an invalid state, and you do not need to
41 // call xpc_connection_cancel(). Just tear down any associated state
43 LOGV("xpc[%i]: client disconnected", xpc_connection_get_pid(connection
));
44 connection_destroy_agents(conn
);
45 } else if (event
== XPC_ERROR_TERMINATION_IMMINENT
) {
46 // Handle per-connection termination cleanup.
47 LOGD("xpc[%i]: per-connection termination", xpc_connection_get_pid(connection
));
50 assert(type
== XPC_TYPE_DICTIONARY
);
52 xpc_object_t reply
= xpc_dictionary_create_reply(event
);
53 require(reply
!= NULL
, done
);
55 uint64_t auth_type
= xpc_dictionary_get_uint64(event
, AUTH_XPC_TYPE
);
56 LOGV("xpc[%i]: received message type=%llu", connection_get_pid(conn
), auth_type
);
59 case AUTHORIZATION_CREATE
:
60 status
= authorization_create(conn
,event
,reply
);
62 case AUTHORIZATION_CREATE_WITH_AUDIT_TOKEN
:
63 status
= authorization_create_with_audit_token(conn
,event
,reply
);
65 case AUTHORIZATION_FREE
:
66 status
= authorization_free(conn
,event
,reply
);
68 case AUTHORIZATION_COPY_RIGHTS
:
69 status
= authorization_copy_rights(conn
,event
,reply
);
71 case AUTHORIZATION_COPY_INFO
:
72 status
= authorization_copy_info(conn
,event
,reply
);
74 case AUTHORIZATION_MAKE_EXTERNAL_FORM
:
75 status
= authorization_make_external_form(conn
,event
,reply
);
77 case AUTHORIZATION_CREATE_FROM_EXTERNAL_FORM
:
78 status
= authorization_create_from_external_form(conn
,event
,reply
);
80 case AUTHORIZATION_RIGHT_GET
:
81 status
= authorization_right_get(conn
,event
,reply
);
83 case AUTHORIZATION_RIGHT_SET
:
84 status
= authorization_right_set(conn
,event
,reply
);
86 case AUTHORIZATION_RIGHT_REMOVE
:
87 status
= authorization_right_remove(conn
,event
,reply
);
89 case SESSION_SET_USER_PREFERENCES
:
90 status
= session_set_user_preferences(conn
,event
,reply
);
92 case AUTHORIZATION_DISMISS
:
93 connection_destroy_agents(conn
);
94 status
= errAuthorizationSuccess
;
96 case AUTHORIZATION_ENABLE_SMARTCARD
:
97 status
= authorization_enable_smartcard(conn
,event
,reply
);
99 case AUTHORIZATION_SETUP
:
101 mach_port_t bootstrap
= xpc_dictionary_copy_mach_send(event
, AUTH_XPC_BOOTSTRAP
);
102 if (!process_set_bootstrap(connection_get_process(conn
), bootstrap
)) {
103 if (bootstrap
!= MACH_PORT_NULL
) {
104 mach_port_deallocate(mach_task_self(), bootstrap
);
108 status
= errAuthorizationSuccess
;
111 case AUTHORIZATION_DEV
:
119 xpc_dictionary_set_int64(reply
, AUTH_XPC_STATUS
, status
);
120 xpc_connection_send_message(connection
, reply
);
129 connection_finalizer(void * conn
)
131 LOGD("xpc[%i]: connection_finalizer", connection_get_pid(conn
));
132 server_unregister_connection(conn
);
135 // malloc_printf("-=-=-=- connection_finalizer() -=-=-=-\n");
136 // malloc_zone_print(malloc_default_zone(), false);
141 security_auth_event_handler(xpc_connection_t xpc_conn
)
143 connection_t conn
= server_register_connection(xpc_conn
);
146 xpc_connection_set_context(xpc_conn
, conn
);
147 xpc_connection_set_finalizer_f(xpc_conn
, connection_finalizer
);
149 xpc_connection_set_event_handler(xpc_conn
, ^(xpc_object_t event
) {
150 xpc_retain(xpc_conn
);
152 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0), ^{
153 security_auth_peer_event_handler(xpc_conn
, event
);
155 xpc_release(xpc_conn
);
158 xpc_connection_resume(xpc_conn
);
161 LOGE("xpc[%i]: failed to register connection", xpc_connection_get_pid(xpc_conn
));
162 xpc_connection_cancel(xpc_conn
);
166 static void sandbox(const char *tmpdir
)
169 const char *sandbox_params
[] = {"TMP_DIR", tmpdir
, NULL
};
172 rc
= sandbox_init_with_parameters(SECURITY_AUTH_NAME
, SANDBOX_NAMED
, sandbox_params
, &errorbuf
);
174 LOGE("server: sandbox_init failed %s (%i)", errorbuf
, rc
);
175 sandbox_free_error(errorbuf
);
182 int main(int argc AUTH_UNUSED
, const char *argv
[] AUTH_UNUSED
)
185 // malloc_printf("-=-=-=- main() -=-=-=-\n");
186 // malloc_zone_print(malloc_default_zone(), false);
191 // <rdar://problem/20900280> authd needs to provide a writeable temp dir for SQLite
192 // <rdar://problem/21223798> Insecure temporary directory in authd (/tmp/authd)
193 char darwin_tmp
[PATH_MAX
];
194 size_t len
= confstr(_CS_DARWIN_USER_TEMP_DIR
, darwin_tmp
, sizeof(darwin_tmp
));
195 if (len
== 0 || len
>= PATH_MAX
) {
196 LOGE("Invalid _CS_DARWIN_USER_TEMP_DIR");
197 return errAuthorizationInternal
;
200 char *real_tmp
= realpath(darwin_tmp
, NULL
);
201 if (real_tmp
== NULL
) {
202 LOGE("realpath( %s ) FAILED", darwin_tmp
);
203 return errAuthorizationInternal
;
206 setenv("SQLITE_TMPDIR", real_tmp
, 1);
210 if (server_init() != errAuthorizationSuccess
) {
211 LOGE("auth: server_init() failed");
212 return errAuthorizationInternal
;
216 // malloc_printf("-=-=-=- server_init() -=-=-=-\n");
217 // malloc_zone_print(malloc_default_zone(), false);
220 xpc_main(security_auth_event_handler
);