X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/SecurityTests/cspxutils/acltool/aclUtils.cpp?ds=inline diff --git a/SecurityTests/cspxutils/acltool/aclUtils.cpp b/SecurityTests/cspxutils/acltool/aclUtils.cpp deleted file mode 100644 index 5e0b727a..00000000 --- a/SecurityTests/cspxutils/acltool/aclUtils.cpp +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 2004-2006 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@ - */ - -/* - * aclUtils.cpp - ACL utility functions, copied from the SecurityTool project. - */ - -#include "aclUtils.h" -#include -#include - -/* Read a line from stdin into buffer as a null terminated string. If buffer is - non NULL use at most buffer_size bytes and return a pointer to buffer. Otherwise - return a newly malloced buffer. - if EOF is read this function returns NULL. */ -char * -readline(char *buffer, int buffer_size) -{ - int ix = 0, bytes_malloced = 0; - - if (!buffer) - { - bytes_malloced = 64; - buffer = (char *)malloc(bytes_malloced); - buffer_size = bytes_malloced; - } - - for (;;++ix) - { - int ch; - - if (ix == buffer_size - 1) - { - if (!bytes_malloced) - break; - bytes_malloced += bytes_malloced; - buffer = (char *)realloc(buffer, bytes_malloced); - buffer_size = bytes_malloced; - } - - ch = getchar(); - if (ch == EOF) - { - if (bytes_malloced) - free(buffer); - return NULL; - } - if (ch == '\n') - break; - buffer[ix] = ch; - } - - /* 0 terminate buffer. */ - buffer[ix] = '\0'; - - return buffer; -} - -void -print_buffer_hex(FILE *stream, UInt32 length, const void *data) -{ - unsigned i; - const unsigned char *cp = (const unsigned char *)data; - - printf("\n "); - for(i=0; i= ' ' && ch <= '~' && ch != '\\') - { - fputc(ch, stream); - } - else - { - fputc('\\', stream); - fputc('0' + ((ch >> 6) & 7), stream); - fputc('0' + ((ch >> 3) & 7), stream); - fputc('0' + ((ch >> 0) & 7), stream); - } - } -} - -void -print_buffer(FILE *stream, UInt32 length, const void *data) -{ - uint8 *p = (uint8 *) data; - Boolean ascii = TRUE; // unless we determine otherwise - UInt32 ix; - for (ix = 0; ix < length; ++ix) { - int ch = *p++; - if ((ch < ' ') || (ch > '~')) { - if((ch == 0) && (ix == (length - 1))) { - /* ignore trailing null */ - length--; - break; - } - ascii = FALSE; - break; - } - } - - if (ascii) { - fputc('"', stream); - print_buffer_ascii(stream, length, data); - fputc('"', stream); - } - else { - print_buffer_hex(stream, length, data); - } -} - -void -print_cfdata(FILE *stream, CFDataRef data) -{ - if (data) - return print_buffer(stream, CFDataGetLength(data), CFDataGetBytePtr(data)); - else - fprintf(stream, ""); -} - -void -print_cfstring(FILE *stream, CFStringRef string) -{ - if (!string) - fprintf(stream, ""); - else - { - const char *utf8 = CFStringGetCStringPtr(string, kCFStringEncodingUTF8); - if (utf8) - fprintf(stream, "%s", utf8); - else - { - CFRange rangeToProcess = CFRangeMake(0, CFStringGetLength(string)); - while (rangeToProcess.length > 0) - { - UInt8 localBuffer[256]; - CFIndex usedBufferLength; - CFIndex numChars = CFStringGetBytes(string, rangeToProcess, - kCFStringEncodingUTF8, '?', FALSE, localBuffer, - sizeof(localBuffer), &usedBufferLength); - if (numChars == 0) - break; // Failed to convert anything... - - fprintf(stream, "%.*s", (int)usedBufferLength, localBuffer); - rangeToProcess.location += numChars; - rangeToProcess.length -= numChars; - } - } - } -} - - -int -print_access(FILE *stream, SecAccessRef access, Boolean interactive) -{ - CFArrayRef aclList = NULL; - CFIndex aclix, aclCount; - int result = 0; - OSStatus status; - - status = SecAccessCopyACLList(access, &aclList); - if (status) - { - cssmPerror("SecAccessCopyACLList", status); - result = 1; - goto loser; - } - - aclCount = CFArrayGetCount(aclList); - fprintf(stream, "access: %lu entries\n", aclCount); - for (aclix = 0; aclix < aclCount; ++aclix) - { - CFArrayRef applicationList = NULL; - CFStringRef description = NULL; - CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR promptSelector = {}; - CFIndex appix, appCount; - - SecACLRef acl = (SecACLRef)CFArrayGetValueAtIndex(aclList, aclix); - CSSM_ACL_AUTHORIZATION_TAG tags[64]; // Pick some upper limit - uint32 tagix, tagCount = sizeof(tags) / sizeof(*tags); - status = SecACLGetAuthorizations(acl, tags, &tagCount); - if (status) - { - cssmPerror("SecACLGetAuthorizations", status); - result = 1; - goto loser; - } - - fprintf(stream, " entry %lu:\n authorizations (%lu):", aclix, (unsigned long)tagCount); - for (tagix = 0; tagix < tagCount; ++tagix) - { - CSSM_ACL_AUTHORIZATION_TAG tag = tags[tagix]; - switch (tag) - { - case CSSM_ACL_AUTHORIZATION_ANY: - fputs(" any", stream); - break; - case CSSM_ACL_AUTHORIZATION_LOGIN: - fputs(" login", stream); - break; - case CSSM_ACL_AUTHORIZATION_GENKEY: - fputs(" genkey", stream); - break; - case CSSM_ACL_AUTHORIZATION_DELETE: - fputs(" delete", stream); - break; - case CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED: - fputs(" export_wrapped", stream); - break; - case CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR: - fputs(" export_clear", stream); - break; - case CSSM_ACL_AUTHORIZATION_IMPORT_WRAPPED: - fputs(" import_wrapped", stream); - break; - case CSSM_ACL_AUTHORIZATION_IMPORT_CLEAR: - fputs(" import_clear", stream); - break; - case CSSM_ACL_AUTHORIZATION_SIGN: - fputs(" sign", stream); - break; - case CSSM_ACL_AUTHORIZATION_ENCRYPT: - fputs(" encrypt", stream); - break; - case CSSM_ACL_AUTHORIZATION_DECRYPT: - fputs(" decrypt", stream); - break; - case CSSM_ACL_AUTHORIZATION_MAC: - fputs(" mac", stream); - break; - case CSSM_ACL_AUTHORIZATION_DERIVE: - fputs(" derive", stream); - break; - case CSSM_ACL_AUTHORIZATION_DBS_CREATE: - fputs(" dbs_create", stream); - break; - case CSSM_ACL_AUTHORIZATION_DBS_DELETE: - fputs(" dbs_delete", stream); - break; - case CSSM_ACL_AUTHORIZATION_DB_READ: - fputs(" db_read", stream); - break; - case CSSM_ACL_AUTHORIZATION_DB_INSERT: - fputs(" db_insert", stream); - break; - case CSSM_ACL_AUTHORIZATION_DB_MODIFY: - fputs(" db_modify", stream); - break; - case CSSM_ACL_AUTHORIZATION_DB_DELETE: - fputs(" db_delete", stream); - break; - case CSSM_ACL_AUTHORIZATION_CHANGE_ACL: - fputs(" change_acl", stream); - break; - case CSSM_ACL_AUTHORIZATION_CHANGE_OWNER: - fputs(" change_owner", stream); - break; - default: - fprintf(stream, " tag=%lu", (unsigned long)tag); - break; - } - } - fputc('\n', stream); - - status = SecACLCopySimpleContents(acl, &applicationList, &description, &promptSelector); - if (status) - { - cssmPerror("SecACLCopySimpleContents", status); - continue; - } - - if (promptSelector.flags & CSSM_ACL_KEYCHAIN_PROMPT_REQUIRE_PASSPHRASE) - fputs(" require-password\n", stream); - else - fputs(" don't-require-password\n", stream); - - fputs(" description: ", stream); - print_cfstring(stream, description); - fputc('\n', stream); - - if (applicationList) - { - appCount = CFArrayGetCount(applicationList); - fprintf(stream, " applications (%lu):\n", appCount); - } - else - { - appCount = 0; - fprintf(stream, " applications: \n"); - } - - for (appix = 0; appix < appCount; ++appix) - { - const UInt8* bytes; - SecTrustedApplicationRef app = (SecTrustedApplicationRef)CFArrayGetValueAtIndex(applicationList, appix); - CFDataRef data = NULL; - fprintf(stream, " %lu: ", appix); - status = SecTrustedApplicationCopyData(app, &data); - if (status) - { - cssmPerror("SecTrustedApplicationCopyData", status); - continue; - } - - bytes = CFDataGetBytePtr(data); - if (bytes && bytes[0] == 0x2f) { - fprintf(stream, "%s", (const char *)bytes); - if ((status = SecTrustedApplicationValidateWithPath(app, (const char *)bytes)) == noErr) { - fprintf(stream, " (OK)"); - } else { - fprintf(stream, " (status %ld)", status); - } - fprintf(stream, "\n"); - } else { - print_cfdata(stream, data); - fputc('\n', stream); - } - if (data) - CFRelease(data); - } - - - if (interactive) - { - char buffer[10] = {}; - if(applicationList != NULL) { - fprintf(stderr, "NULL out this application list? "); - if (readline(buffer, sizeof(buffer)) && buffer[0] == 'y') - { - /* - * This makes the ops in this entry wide-open, no dialog or confirmation - * other than requiring the keychain be open. - */ - fprintf(stderr, "setting app list to NULL\n"); - status = SecACLSetSimpleContents(acl, NULL, description, &promptSelector); - if (status) - { - cssmPerror("SecACLSetSimpleContents", status); - continue; - } - } - else { - fprintf(stderr, "Set this application list to empty array? "); - if (readline(buffer, sizeof(buffer)) && buffer[0] == 'y') - { - /* - * This means "always get confirmation, from all apps". - */ - fprintf(stderr, "setting app list to empty array\n"); - status = SecACLSetSimpleContents(acl, - CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks), - description, &promptSelector); - if (status) - { - cssmPerror("SecACLSetSimpleContents", status); - continue; - } - } - } - } - else { - fprintf(stderr, "Remove this acl? "); - if (readline(buffer, sizeof(buffer)) && buffer[0] == 'y') - { - /* - * This make ths ops in this entry completely inaccessible. - */ - fprintf(stderr, "removing acl\n"); - status = SecACLRemove(acl); - if (status) - { - cssmPerror("SecACLRemove", status); - continue; - } - } - } - } - if (description) - CFRelease(description); - if (applicationList) - CFRelease(applicationList); - - } - -loser: - if (aclList) - CFRelease(aclList); - - return result; -} - -/* Simluate what StickyRecord is trying to do.... */ - -/* - * Given an Access object: - * -- extract the ACL for the specified CSSM_ACL_AUTHORIZATION_TAG. We expect there - * to exactly one of these - if the form of a default ACL changes we'll have to - * revisit this. - * -- set the ACL's app list to the provided CFArray, which may be NULL (meaning - * "any app can access this, no problem"), an empty array (meaning "always - * prompt"), or an actual app list. - * -- set or clear the PROMPT_REQUIRE_PASSPHRASE bit per the requirePassphrase - * argument - */ -static OSStatus srUpdateAcl( - SecAccessRef accessRef, - CSSM_ACL_AUTHORIZATION_TAG whichAcl, // e.g. CSSM_ACL_AUTHORIZATION_DECRYPT - CFArrayRef appArray, - bool requirePassphrase) -{ - OSStatus ortn; - CFArrayRef aclList = NULL; - - ortn = SecAccessCopySelectedACLList(accessRef, whichAcl, &aclList); - if(ortn) { - cssmPerror("SecAccessCopySelectedACLList", ortn); - return ortn; - } - - if(CFArrayGetCount(aclList) != 1) { - printf("StickyRecord::updateAcl - unexpected ACL list count (%d)", - (int)CFArrayGetCount(aclList)); - return internalComponentErr; - } - SecACLRef acl = (SecACLRef)CFArrayGetValueAtIndex(aclList, 0); - - CFArrayRef applicationList = NULL; - CFStringRef description = NULL; - CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR promptSelector = {}; - ortn = SecACLCopySimpleContents(acl, &applicationList, &description, &promptSelector); - if(ortn) { - cssmPerror("SecACLCopySimpleContents", ortn); - return ortn; - } - if(applicationList != NULL) { - CFRelease(applicationList); - } - if(requirePassphrase) { - promptSelector.flags |= CSSM_ACL_KEYCHAIN_PROMPT_REQUIRE_PASSPHRASE; - } - else { - promptSelector.flags &= ~CSSM_ACL_KEYCHAIN_PROMPT_REQUIRE_PASSPHRASE; - } - /* update */ - ortn = SecACLSetSimpleContents(acl, appArray, description, &promptSelector); - - /* we got this from SecACLCopySimpleContents - release it regardless */ - if(description != NULL) { - CFRelease(description); - } - if(ortn) { - cssmPerror("SecACLSetSimpleContents", ortn); - } - if(aclList != NULL) { - CFRelease(aclList); - } - return ortn; -} - -OSStatus stickyRecordUpdateAcl( - SecAccessRef accessRef) -{ - OSStatus ortn; - - printf("...updating ACL to simulate a StickyRecord\n"); - - /* First: decrypt. Wide open (NULL app list), !REQUIRE_PASSPHRASE. */ - ortn = srUpdateAcl(accessRef, CSSM_ACL_AUTHORIZATION_DECRYPT, NULL, false); - if(ortn) { - return ortn; - } - - /* encrypt: always ask (empty app list, require passphrase */ - CFArrayRef nullArray = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); - return srUpdateAcl(accessRef, CSSM_ACL_AUTHORIZATION_ENCRYPT, nullArray, true); - -}