X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_authorization/lib/trampolineClient.cpp diff --git a/libsecurity_authorization/lib/trampolineClient.cpp b/libsecurity_authorization/lib/trampolineClient.cpp deleted file mode 100644 index cfc71a79..00000000 --- a/libsecurity_authorization/lib/trampolineClient.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2000-2004 Apple Computer, 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@ - */ - - -// -// trampolineClient - Authorization trampoline client-side implementation -// -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Where is the trampoline itself? -// -#if !defined(TRAMPOLINE) -# define TRAMPOLINE "/usr/libexec/security_authtrampoline" /* fallback */ -#endif - - -// -// A few names for clarity's sake -// -enum { - READ = 0, // read end of standard UNIX pipe - WRITE = 1 // write end of standard UNIX pipe -}; - - -// -// Local (static) functions -// -static const char **argVector(const char *trampoline, - const char *tool, const char *commFd, - char *const *arguments); - - -OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization, - const char *pathToTool, - AuthorizationFlags flags, - char *const *arguments, - FILE **communicationsPipe) -{ - // externalize the authorization - AuthorizationExternalForm extForm; - if (OSStatus err = AuthorizationMakeExternalForm(authorization, &extForm)) - return err; - - return AuthorizationExecuteWithPrivilegesExternalForm(&extForm, pathToTool, flags, arguments, communicationsPipe); -} - -// -// The public client API function. -// -OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExternalForm * extForm, - const char *pathToTool, - AuthorizationFlags flags, - char *const *arguments, - FILE **communicationsPipe) -{ - if (extForm == NULL) - return errAuthorizationInvalidPointer; - - // report the caller to the authorities - aslmsg m = asl_new(ASL_TYPE_MSG); - asl_set(m, "com.apple.message.domain", "com.apple.libsecurity_authorization.AuthorizationExecuteWithPrivileges"); - asl_set(m, "com.apple.message.signature", getprogname()); - asl_log(NULL, m, ASL_LEVEL_NOTICE, "AuthorizationExecuteWithPrivileges!"); - asl_free(m); - - // flags are currently reserved - if (flags != 0) - return errAuthorizationInvalidFlags; - - // create the mailbox file - FILE *mbox = tmpfile(); - if (!mbox) - return errAuthorizationInternal; - if (fwrite(extForm, sizeof(*extForm), 1, mbox) != 1) { - fclose(mbox); - return errAuthorizationInternal; - } - fflush(mbox); - - // compute the argument vector here because we can't allocate memory once we fork. - - // make text representation of the temp-file descriptor - char mboxFdText[20]; - snprintf(mboxFdText, sizeof(mboxFdText), "auth %d", fileno(mbox)); - - // where is the trampoline? -#if defined(NDEBUG) - const char *trampoline = TRAMPOLINE; -#else //!NDEBUG - const char *trampoline = getenv("AUTHORIZATIONTRAMPOLINE"); - if (!trampoline) - trampoline = TRAMPOLINE; -#endif //NDEBUG - - const char **argv = argVector(trampoline, pathToTool, mboxFdText, arguments); - - // make a notifier pipe - int notify[2]; - if (pipe(notify)) { - fclose(mbox); - return errAuthorizationToolExecuteFailure; - } - - // make the communications pipe if requested - int comm[2]; - if (communicationsPipe && socketpair(AF_UNIX, SOCK_STREAM, 0, comm)) { - close(notify[READ]); close(notify[WRITE]); - fclose(mbox); - return errAuthorizationToolExecuteFailure; - } - - OSStatus status = errSecSuccess; - - // do the standard forking tango... - int delay = 1; - for (int n = 5;; n--, delay *= 2) { - switch (fork()) { - case -1: // error - if (errno == EAGAIN) { - // potentially recoverable resource shortage - if (n > 0) { - secdebug("authexec", "resource shortage (EAGAIN), delaying %d seconds", delay); - sleep(delay); - continue; - } - } - secdebug("authexec", "fork failed (errno=%d)", errno); - close(notify[READ]); close(notify[WRITE]); - return errAuthorizationToolExecuteFailure; - - default: { // parent - // close foreign side of pipes - close(notify[WRITE]); - if (communicationsPipe) - close(comm[WRITE]); - - // close mailbox file (child has it open now) - fclose(mbox); - - // get status notification from child - secdebug("authexec", "parent waiting for status"); - ssize_t rc = read(notify[READ], &status, sizeof(status)); - status = n2h(status); - switch (rc) { - default: // weird result of read: post error - secdebug("authexec", "unexpected read return value %ld", long(rc)); - status = errAuthorizationToolEnvironmentError; - // fall through - case sizeof(status): // read succeeded: child reported an error - secdebug("authexec", "parent received status=%d", (int)status); - close(notify[READ]); - if (communicationsPipe) { close(comm[READ]); close(comm[WRITE]); } - goto exit_point; - case 0: // end of file: exec succeeded - close(notify[READ]); - if (communicationsPipe) - *communicationsPipe = fdopen(comm[READ], "r+"); - secdebug("authexec", "parent resumes (no error)"); - status = errSecSuccess; - goto exit_point; - } - } - break; - - case 0: // child - // close foreign side of pipes - close(notify[READ]); - if (communicationsPipe) - close(comm[READ]); - - // fd 1 (stdout) holds the notify write end - dup2(notify[WRITE], 1); - close(notify[WRITE]); - - // fd 0 (stdin) holds either the comm-link write-end or /dev/null - if (communicationsPipe) { - dup2(comm[WRITE], 0); - close(comm[WRITE]); - } else { - close(0); - open("/dev/null", O_RDWR); - } - - // okay, execute the trampoline - if (argv) - execv(trampoline, (char *const*)argv); - - // execute failed - tell the parent - { - OSStatus error = errAuthorizationToolExecuteFailure; - error = h2n(error); - write(1, &error, sizeof(error)); - _exit(1); - } - } - } - -exit_point: - free(argv); - return status; -} - - -// -// Build an argv vector -// -static const char **argVector(const char *trampoline, const char *pathToTool, - const char *mboxFdText, char *const *arguments) -{ - int length = 0; - if (arguments) { - for (char *const *p = arguments; *p; p++) - length++; - } - if (const char **args = (const char **)malloc(sizeof(const char *) * (length + 4))) { - args[0] = trampoline; - args[1] = pathToTool; - args[2] = mboxFdText; - if (arguments) - for (int n = 0; arguments[n]; n++) - args[n + 3] = arguments[n]; - args[length + 3] = NULL; - return args; - } - return NULL; -}