]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_authorization/lib/trampolineClient.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / libsecurity_authorization / lib / trampolineClient.cpp
diff --git a/libsecurity_authorization/lib/trampolineClient.cpp b/libsecurity_authorization/lib/trampolineClient.cpp
deleted file mode 100644 (file)
index cfc71a7..0000000
+++ /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 <asl.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <Security/Authorization.h>
-#include <Security/AuthorizationPriv.h>
-#include <Security/SecBase.h>
-#include <security_utilities/endian.h>
-#include <security_utilities/debugging.h>
-
-//
-// 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;
-}