+++ /dev/null
-/*
- * Copyright (c) 2007-2009 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 <stdbool.h>
-#include <sys/queue.h>
-#include <syslog.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Security/SecItem.h>
-#include <Security/SecBasePriv.h>
-#include <Security/SecInternal.h>
-
-#include <utilities/debugging.h>
-#include <utilities/SecCFError.h>
-#include <utilities/SecXPCError.h>
-#include <utilities/SecCFWrappers.h>
-#include <utilities/SecDispatchRelease.h>
-#include <utilities/SecDb.h> // TODO Fixme this gets us SecError().
-#include "securityd_client.h"
-#include "SecuritydXPC.h"
-
-struct securityd *gSecurityd;
-
-//
-// MARK: XPC IPC.
-//
-
-/* Hardcoded Access Groups for the server itself */
-static CFArrayRef SecServerCopyAccessGroups(void) {
- return CFArrayCreateForCFTypes(kCFAllocatorDefault,
-#if NO_SERVER
- CFSTR("test"),
- CFSTR("apple"),
- CFSTR("lockdown-identities"),
-#else
- CFSTR("sync"),
-#endif
- CFSTR("com.apple.security.sos"),
- NULL);
-}
-
-CFArrayRef SecAccessGroupsGetCurrent(void) {
- static CFArrayRef gSecServerAccessGroups;
- static dispatch_once_t only_do_this_once;
- dispatch_once(&only_do_this_once, ^{
- gSecServerAccessGroups = SecServerCopyAccessGroups();
- assert(gSecServerAccessGroups);
- });
- return gSecServerAccessGroups;
-}
-
-static xpc_connection_t securityd_create_connection(const char *name) {
- if (!name)
- name = kSecuritydXPCServiceName;
- xpc_connection_t connection;
- connection = xpc_connection_create_mach_service(name, NULL, 0);
- xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
- const char *description = xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION);
- secnotice("xpc", "got event: %s", description);
- });
- xpc_connection_resume(connection);
- return connection;
-}
-
-static xpc_connection_t sSecuritydConnection;
-
-static xpc_connection_t securityd_connection(void) {
- static dispatch_once_t once;
- dispatch_once(&once, ^{
- sSecuritydConnection = securityd_create_connection(NULL);
- });
- return sSecuritydConnection;
-}
-
-// NOTE: This is not thread safe, but this SPI is for testing only.
-void SecServerSetMachServiceName(const char *name) {
- // Make sure sSecXPCServer.queue exists.
- securityd_connection();
-
- xpc_connection_t oldConection = sSecuritydConnection;
- sSecuritydConnection = securityd_create_connection(name);
- if (oldConection)
- xpc_release(oldConection);
-}
-
-xpc_object_t
-securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error)
-{
- xpc_object_t reply = NULL;
- xpc_connection_t connection = securityd_connection();
-
- for (int try = 1; try <= 2; ++try) {
- reply = xpc_connection_send_message_with_reply_sync(connection, message);
- if (try == 1 && reply == XPC_ERROR_CONNECTION_INTERRUPTED) {
- xpc_release(reply);
- } else {
- break;
- }
- }
-
- if (xpc_get_type(reply) == XPC_TYPE_ERROR) {
- CFIndex code = 0;
- if (reply == XPC_ERROR_CONNECTION_INTERRUPTED || reply == XPC_ERROR_CONNECTION_INVALID)
- code = kSecXPCErrorConnectionFailed;
- else if (reply == XPC_ERROR_TERMINATION_IMMINENT)
- code = kSecXPCErrorUnknown;
- else
- code = kSecXPCErrorUnknown;
-
- char *conn_desc = xpc_copy_description(connection);
- const char *description = xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION);
- SecCFCreateErrorWithFormat(code, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("%s: %s"), conn_desc, description);
- free(conn_desc);
- xpc_release(reply);
- reply = NULL;
- }
-
- return reply;
-}
-
-xpc_object_t securityd_create_message(enum SecXPCOperation op, CFErrorRef* error)
-{
- xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
- if (message) {
- xpc_dictionary_set_uint64(message, kSecXPCKeyOperation, op);
- } else {
- SecCFCreateError(kSecXPCErrorConnectionFailed, sSecXPCErrorDomain,
- CFSTR("xpc_dictionary_create returned NULL"), NULL, error);
- }
- return message;
-}
-
-// Return true if there is no error in message, return false and set *error if there is.
-bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error) {
- xpc_object_t xpc_error = xpc_dictionary_get_value(message, kSecXPCKeyError);
- if (xpc_error == NULL)
- return true;
-
- if (error) {
- *error = SecCreateCFErrorWithXPCObject(xpc_error);
- }
- return false;
-}
-
-bool securityd_send_sync_and_do(enum SecXPCOperation op, CFErrorRef *error,
- bool (^add_to_message)(xpc_object_t message, CFErrorRef* error),
- bool (^handle_response)(xpc_object_t response, CFErrorRef* error)) {
- xpc_object_t message = securityd_create_message(op, error);
- bool ok = false;
- if (message) {
- if (!add_to_message || add_to_message(message, error)) {
- xpc_object_t response = securityd_message_with_reply_sync(message, error);
- if (response) {
- if (securityd_message_no_error(response, error)) {
- ok = (!handle_response || handle_response(response, error));
- }
- xpc_release(response);
- }
- }
- xpc_release(message);
- }
-
- return ok;
-}
-
-
-/* vi:set ts=4 sw=4 et: */