Bool Id_AuthSet(void const *buf, // IN size_t size) // IN { AuthorizationRef newProcAuth; AuthorizationExternalForm const *ext = (AuthorizationExternalForm const *)buf; if (!buf || size != sizeof *ext) { Warning("%s: Invalid argument.\n", __func__); return FALSE; } ASSERT(!Atomic_ReadPtr(&procAuth)); if (AuthorizationCreateFromExternalForm(ext, &newProcAuth) != errAuthorizationSuccess) { Warning("AuthorizationCreateFromExternalForm failed.\n"); return FALSE; } if (Atomic_ReadIfEqualWritePtr(&procAuth, NULL, newProcAuth)) { /* * This is meant to be called very early on in the life of the * process. If someone else has snuck in an authorization, * we're toast. */ NOT_IMPLEMENTED(); } return TRUE; }
int main(int argc, char **argv) { char mypath[MAXPATHLEN]; unsigned long mypath_size= sizeof(mypath); OSStatus status; AuthorizationRef auth; int bytesRead; BrokerCtlCommand command; if (_NSGetExecutablePath(mypath, &mypath_size) < 0) { DEBUG("could not get my path"); exit(BrokerCtlCommandInternalError); } AuthorizationExternalForm extAuth; // read bytestream with Auth data if (read(0, &extAuth, sizeof(extAuth)) != sizeof(extAuth)) exit(BrokerCtlCommandInternalError); // bytestream --*poof*--> auth if (AuthorizationCreateFromExternalForm(&extAuth, &auth)) exit(BrokerCtlCommandInternalError); // if we're not being ran as root, spawn a copy that will make us suid root if (geteuid() != 0) { printf("I'm not suided\n"); exit(-1); } /* Read a command object from stdin. */ bytesRead = read(0, &command, sizeof(BrokerCtlCommand)); if (bytesRead == sizeof(BrokerCtlCommand)) { const char *rightName = rightNameForCommand(&command); AuthorizationItem right = { rightName, 0, NULL, 0 } ; AuthorizationRights rights = { 1, &right }; AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights; if (status = AuthorizationCopyRights(auth, &rights, kAuthorizationEmptyEnvironment, flags, NULL)) { DEBUG("failed authorization in helper: %ld.\n", status); exit(BrokerCtlCommandAuthFailed); } /* Peform the requested command */ if (!performCommand(&command)) exit(BrokerCtlCommandOperationFailed); } else { exit(BrokerCtlCommandChildError); } return BrokerCtlCommandSuccess; }
inline Bool16 OSXAuthenticate(StrPtrLen *keyStrPtr) { #if __MacOSX__ // Authorization: AuthRef QWxhZGRpbjpvcGVuIHNlc2FtZQ== Bool16 result = false; if (keyStrPtr == NULL || keyStrPtr->Len == 0) return result; char *encodedKey = keyStrPtr->GetAsCString(); OSCharArrayDeleter encodedKeyDeleter(encodedKey); char *decodedKey = NEW char[Base64decode_len(encodedKey) + 1]; OSCharArrayDeleter decodedKeyDeleter(decodedKey); (void) Base64decode(decodedKey, encodedKey); AuthorizationExternalForm *receivedExtFormPtr = (AuthorizationExternalForm *) decodedKey; AuthorizationRef receivedAuthorization; OSStatus status = AuthorizationCreateFromExternalForm(receivedExtFormPtr, &receivedAuthorization); if (status != errAuthorizationSuccess) return result; status = AuthorizationCopyRights(receivedAuthorization, &sRightSet, kAuthorizationEmptyEnvironment, kAuthorizationFlagExtendRights , NULL); if (status == errAuthorizationSuccess) { result = true; } AuthorizationFree(receivedAuthorization, kAuthorizationFlagDestroyRights); return result; #else return false; #endif }
STATIC Boolean authorization_is_valid(const void * auth_data, int auth_data_length) { AuthorizationExternalForm * auth_ext_p; AuthorizationRef authorization; AuthorizationFlags flags; AuthorizationItem item; AuthorizationRights rights; OSStatus status; if (auth_data == NULL || auth_data_length != sizeof(auth_ext_p->bytes)) { syslog(LOG_ERR, "eapolcfg_auth: authorization NULL/invalid size"); return (FALSE); } auth_ext_p = (AuthorizationExternalForm *)auth_data; status = AuthorizationCreateFromExternalForm(auth_ext_p, &authorization); if (status != errAuthorizationSuccess) { syslog(LOG_ERR, "eapolcfg_auth: authorization is invalid (%d)", (int)status); return (FALSE); } rights.count = 1; rights.items = &item; item.name = "system.preferences"; item.value = NULL; item.valueLength = 0; item.flags = 0; flags = kAuthorizationFlagDefaults; flags |= kAuthorizationFlagExtendRights; flags |= kAuthorizationFlagInteractionAllowed; status = AuthorizationCopyRights(authorization, &rights, kAuthorizationEmptyEnvironment, flags, NULL); AuthorizationFree(authorization, kAuthorizationFlagDefaults); return (status == errAuthorizationSuccess); }
// // Perform update authorization processing. // Throws an exception if authorization is denied. // static void authorizeUpdate(SecAssessmentFlags flags, CFDictionaryRef context) { AuthorizationRef authorization = NULL; if (context) if (CFTypeRef authkey = CFDictionaryGetValue(context, kSecAssessmentUpdateKeyAuthorization)) if (CFGetTypeID(authkey) == CFDataGetTypeID()) { CFDataRef authdata = CFDataRef(authkey); MacOSError::check(AuthorizationCreateFromExternalForm((AuthorizationExternalForm *)CFDataGetBytePtr(authdata), &authorization)); } if (authorization == NULL) MacOSError::check(AuthorizationCreate(NULL, NULL, kAuthorizationFlagDefaults, &authorization)); AuthorizationItem right[] = { { "com.apple.security.assessment.update", 0, NULL, 0 } }; AuthorizationRights rights = { sizeof(right) / sizeof(right[0]), right }; MacOSError::check(AuthorizationCopyRights(authorization, &rights, NULL, kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed, NULL)); MacOSError::check(AuthorizationFree(authorization, kAuthorizationFlagDefaults)); }
static AuthorizationRef IdAuthCreateWithFork(void) { int fds[2] = { -1, -1, }; pid_t child; AuthorizationRef auth = NULL; struct { Bool success; AuthorizationExternalForm ext; } data; uint8 buf; /* * XXX One more Apple bug related to thread credentials: * AuthorizationCreate() incorrectly uses process instead of thread * credentials. So for this code to properly work in the VMX for * example, we must do this elaborate fork/handshake dance. Fortunately * this function is only called once very early when a process starts. */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { Warning("%s: socketpair() failed.\n", __func__); goto out; } child = fork(); if (child < 0) { Warning("%s: fork() failed.\n", __func__); goto out; } if (child) { size_t rcvd; int status; pid_t result; // Parent: use fds[0] // Wait until the child has created its process ref to the auth session. for (rcvd = 0; rcvd < sizeof data; ) { ssize_t actual; actual = read(fds[0], (void *)&data + rcvd, sizeof data - rcvd); ASSERT(actual <= sizeof data - rcvd); if (actual < 0) { ASSERT(errno == EPIPE); Warning("%s: parent read() failed because child died.\n", __func__); data.success = FALSE; break; } rcvd += actual; } if (data.success) { if (AuthorizationCreateFromExternalForm(&data.ext, &auth) != errAuthorizationSuccess) { Warning("%s: parent AuthorizationCreateFromExternalForm() " "failed.\n", __func__); } } // Tell the child it can now destroy its process ref to the auth session. write(fds[0], &buf, sizeof buf); // Reap the child, looping if we get interrupted by a signal. do { result = waitpid(child, &status, 0); } while (result == -1 && errno == EINTR); ASSERT_NOT_IMPLEMENTED(result == child); } else { // Child: use fds[1] data.success = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth) == errAuthorizationSuccess; if (data.success) { data.success = AuthorizationMakeExternalForm(auth, &data.ext) == errAuthorizationSuccess; if (!data.success) { Warning("%s: child AuthorizationMakeExternalForm() failed.\n", __func__); } } else { Warning("%s: child AuthorizationCreate() failed.\n", __func__); } // Tell the parent it can now create a process ref to the auth session. if (write(fds[1], &data, sizeof data) == sizeof data) { /* * Wait until the child can destroy its process ref to the auth * session. */ for (;;) { ssize_t actual = read(fds[1], &buf, sizeof buf); ASSERT(actual <= sizeof buf); if (actual) { break; } } } /* * This implicitly: * o Destroys the child process ref to the Authorization session. * o Closes fds[0] and fds[1] */ exit(0); } out: close(fds[0]); close(fds[1]); return auth; }
int main(int argc, char *argv[]) { OSStatus status; AuthorizationRef auth; char *path; struct stat statbuf; char *typeAsString; AuthorizationExternalForm extAuth; // Is this process running as root? if (geteuid() != 0) { fprintf(stderr, "Not running as root\n"); exit(-1); } // Was there one argument? if (argc != 2) { fprintf(stderr, "Usage: remove_statter <dir>\n"); exit(-1); } // Get the path path = argv[1]; // Read the Authorization "byte blob" from our input pipe. if (fread(&extAuth, sizeof(extAuth), 1, stdin) != 1) { fprintf(stderr, "Unable to read authorization\n"); exit(-1); } // Restore the externalized Authorization back to an AuthorizationRef if (AuthorizationCreateFromExternalForm(&extAuth, &auth)) { fprintf(stderr, "Unable to parse authorization data\n"); exit(-1); } // Create the rights structure AuthorizationItem right = { RIGHT, 0, NULL, 0 }; AuthorizationRights rights = { 1, &right }; AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagExtendRights; fprintf(stderr, "Tool authorizing right %s for command.\n", RIGHT); // Check the authorization if (status = AuthorizationCopyRights(auth, &rights, kAuthorizationEmptyEnvironment, flags, NULL)) { fprintf(stderr, "Tool failed authorization: %ld.\n", status); exit(-1); } // Stat the path if (stat(path, &statbuf)) { fprintf(stderr, "Unable to stat %s", path); exit(-1); } // Write out stat info if (S_ISDIR(statbuf.st_mode)) typeAsString = "NSFileTypeDirectory"; else typeAsString = "NSFileTypeRegular"; fprintf(stdout, "%s\n%lu", typeAsString, (unsigned long)statbuf.st_size); fclose(stdout); // Terminate exit(0); }
/* * Function: saveInterfaceEAPOLConfiguration * Purpose: * Save the SCNetworkInterface EAPOL information for System and LoginWindow * modes. * * Iterate over the changed SCNetworkInterfaceRef list cfg->sc_changed_if, * and for each interface, grab the EAPOL extended information from * cfg->sc_prefs. Then set the corresponding value in the new * freshly created SCPreferencesRef. * * All this done to avoid a writer getting Stale Object errors * when it has its own SCPreferencesRef object that it manipulates while * having an EAPOLClientConfigurationRef open. */ STATIC Boolean saveInterfaceEAPOLConfiguration(EAPOLClientConfigurationRef cfg, Boolean * changed_p) { AuthorizationExternalForm * auth_ext_p; int count; int i; SCPreferencesRef prefs = NULL; Boolean ret = FALSE; *changed_p = FALSE; if (cfg->sc_changed_if == NULL) { return (TRUE); } auth_ext_p = EAPOLClientConfigurationGetAuthorizationExternalForm(cfg); if (auth_ext_p != NULL) { AuthorizationRef auth; OSStatus status; status = AuthorizationCreateFromExternalForm(auth_ext_p, &auth); if (status != errAuthorizationSuccess) { EAPLOG(LOG_ERR, "EAPOLClientConfiguration: can't allocate Authorization, %d", (int)status); goto done; } prefs = SCPreferencesCreateWithAuthorization(NULL, kPrefsName, NULL, auth); AuthorizationFree(auth, kAuthorizationFlagDefaults); } else { prefs = SCPreferencesCreate(NULL, kPrefsName, NULL); } count = CFArrayGetCount(cfg->sc_changed_if); for (i = 0; i < count; i++) { CFDictionaryRef dict; CFStringRef if_name; SCNetworkInterfaceRef net_if; net_if = (SCNetworkInterfaceRef) CFArrayGetValueAtIndex(cfg->sc_changed_if, i); if_name = SCNetworkInterfaceGetBSDName(net_if); if (if_name == NULL) { /* should not happen */ EAPLOG(LOG_ERR, "EAPOLClientConfiguration: missing BSD name"); continue; } dict = SCNetworkInterfaceGetExtendedConfiguration(net_if, kEAPOL); /* find the same interface in the saving prefs */ if (set_eapol_configuration(prefs, if_name, dict) == FALSE) { continue; } } ret = SCPreferencesCommitChanges(prefs); if (ret == FALSE) { EAPLOG(LOG_NOTICE, "EAPOLClientConfigurationSave SCPreferencesCommitChanges" " failed %s", SCErrorString(SCError())); goto done; } SCPreferencesApplyChanges(prefs); *changed_p = TRUE; done: my_CFRelease(&cfg->sc_changed_if); my_CFRelease(&prefs); return (ret); }