X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5c19dc3ae3bd8e40a9c028b0deddd50ff337692c..07691282a056c4efea71e1e505527601e8cc166b:/OSX/libsecurity_keychain/lib/ACL.cpp diff --git a/OSX/libsecurity_keychain/lib/ACL.cpp b/OSX/libsecurity_keychain/lib/ACL.cpp index 9b655a69..3c328bf4 100644 --- a/OSX/libsecurity_keychain/lib/ACL.cpp +++ b/OSX/libsecurity_keychain/lib/ACL.cpp @@ -57,12 +57,12 @@ const CSSM_ACL_HANDLE ACL::ownerHandle; // // Create an ACL object from the result of a CSSM ACL query // -ACL::ACL(Access &acc, const AclEntryInfo &info, Allocator &alloc) - : allocator(alloc), access(acc), mState(unchanged), mSubjectForm(NULL), mMutex(Mutex::recursive) +ACL::ACL(const AclEntryInfo &info, Allocator &alloc) + : allocator(alloc), mState(unchanged), mSubjectForm(NULL), mIntegrity(alloc), mMutex(Mutex::recursive) { // parse the subject parse(info.proto().subject()); - + // fill in AclEntryInfo layer information const AclEntryPrototype &proto = info.proto(); mAuthorizations = proto.authorization(); @@ -73,8 +73,9 @@ ACL::ACL(Access &acc, const AclEntryInfo &info, Allocator &alloc) mCssmHandle = info.handle(); } -ACL::ACL(Access &acc, const AclOwnerPrototype &owner, Allocator &alloc) - : allocator(alloc), access(acc), mState(unchanged), mSubjectForm(NULL), mMutex(Mutex::recursive) + +ACL::ACL(const AclOwnerPrototype &owner, Allocator &alloc) + : allocator(alloc), mState(unchanged), mSubjectForm(NULL), mIntegrity(alloc), mMutex(Mutex::recursive) { // parse subject parse(owner.subject()); @@ -95,8 +96,8 @@ ACL::ACL(Access &acc, const AclOwnerPrototype &owner, Allocator &alloc) // To generate a "standard" form of ANY, use the appListForm constructor below, // then change its form to allowAnyForm. // -ACL::ACL(Access &acc, Allocator &alloc) - : allocator(alloc), access(acc), mSubjectForm(NULL), mMutex(Mutex::recursive) +ACL::ACL(Allocator &alloc) + : allocator(alloc), mSubjectForm(NULL), mIntegrity(alloc), mMutex(Mutex::recursive) { mState = inserted; // new mForm = allowAllForm; // everybody @@ -115,9 +116,9 @@ ACL::ACL(Access &acc, Allocator &alloc) // Create a new ACL in standard form. // As created, it authorizes all activities. // -ACL::ACL(Access &acc, string description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR &promptSelector, +ACL::ACL(string description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR &promptSelector, Allocator &alloc) - : allocator(alloc), access(acc), mSubjectForm(NULL), mMutex(Mutex::recursive) + : allocator(alloc), mSubjectForm(NULL), mIntegrity(alloc), mMutex(Mutex::recursive) { mState = inserted; // new mForm = appListForm; @@ -132,6 +133,26 @@ ACL::ACL(Access &acc, string description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTO } +// +// Create an "integrity" ACL +// +ACL::ACL(const CssmData &digest, Allocator &alloc) +: allocator(alloc), mSubjectForm(NULL), mIntegrity(alloc, digest), mMutex(Mutex::recursive) +{ + mState = inserted; // new + mForm = integrityForm; + mAuthorizations.insert(CSSM_ACL_AUTHORIZATION_INTEGRITY); + mEntryTag = CSSM_APPLE_ACL_TAG_INTEGRITY; + mDelegate = false; + + //mPromptDescription stays empty + //mPromptSelector stays empty + + // randomize the CSSM handle + UniformRandomBlobs().random(mCssmHandle); +} + + // // Destroy an ACL // @@ -153,6 +174,28 @@ bool ACL::authorizes(AclAuthorization right) || mAuthorizations.empty(); } +// +// Does this ACL have a specific authorization for a particular right? +// +bool ACL::authorizesSpecifically(AclAuthorization right) +{ + StLock_(mMutex); + return mAuthorizations.find(right) != mAuthorizations.end(); +} + +void ACL::setIntegrity(const CssmData& digest) { + if(mForm != integrityForm) { + secnotice("integrity", "acl has incorrect form: %d", mForm); + CssmError::throwMe(CSSMERR_CSP_INVALID_ACL_SUBJECT_VALUE); + } + + mIntegrity = digest; + modify(); +} + +const CssmData& ACL::integrity() { + return mIntegrity.get(); +} // // Add an application to the trusted-app list of this ACL. @@ -187,7 +230,7 @@ void ACL::modify() { StLock_(mMutex); if (mState == unchanged) { - secdebug("SecAccess", "ACL %p marked modified", this); + secinfo("SecAccess", "ACL %p marked modified", this); mState = modified; } } @@ -205,6 +248,7 @@ void ACL::remove() StLock_(mMutex); mAppList.clear(); mForm = invalidForm; + secinfo("SecAccess", "ACL %p marked deleted", this); mState = deleted; } @@ -264,12 +308,12 @@ void ACL::setAccess(AclBearer &target, bool update, if (isOwner()) { switch (action) { case unchanged: - secdebug("SecAccess", "ACL %p owner unchanged", this); + secinfo("SecAccess", "ACL %p owner unchanged", this); return; case inserted: // means modify the initial owner case modified: { - secdebug("SecAccess", "ACL %p owner modified", this); + secinfo("SecAccess", "ACL %p owner modified", this); makeSubject(); assert(mSubjectForm); AclOwnerPrototype proto(*mSubjectForm, mDelegate); @@ -285,10 +329,10 @@ void ACL::setAccess(AclBearer &target, bool update, // simple cases switch (action) { case unchanged: // ignore - secdebug("SecAccess", "ACL %p handle 0x%lx unchanged", this, entryHandle()); + secinfo("SecAccess", "ACL %p handle 0x%lx unchanged", this, entryHandle()); return; case deleted: // delete - secdebug("SecAccess", "ACL %p handle 0x%lx deleted", this, entryHandle()); + secinfo("SecAccess", "ACL %p handle 0x%lx deleted", this, entryHandle()); target.deleteAcl(entryHandle(), cred); return; default: @@ -305,12 +349,14 @@ void ACL::setAccess(AclBearer &target, bool update, AclEntryInput input(proto); switch (action) { case inserted: // insert - secdebug("SecAccess", "ACL %p inserted", this); + secinfo("SecAccess", "ACL %p inserted", this); target.addAcl(input, cred); + mState = unchanged; break; case modified: // update - secdebug("SecAccess", "ACL %p handle 0x%lx modified", this, entryHandle()); + secinfo("SecAccess", "ACL %p handle 0x%lx modified", this, entryHandle()); target.changeAcl(entryHandle(), input, cred); + mState = unchanged; break; default: assert(false); @@ -330,11 +376,13 @@ void ACL::parse(const TypedList &subject) case CSSM_ACL_SUBJECT_TYPE_ANY: // subsume an "any" as a standard form mForm = allowAllForm; + secinfo("SecAccess", "parsed an allowAllForm (%d) (%d)", subject.type(), mForm); return; case CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT: // pure keychain prompt - interpret as applist form with no apps parsePrompt(subject); mForm = appListForm; + secinfo("SecAccess", "parsed a Keychain Prompt (%d) as an appListForm (%d)", subject.type(), mForm); return; case CSSM_ACL_SUBJECT_TYPE_THRESHOLD: { @@ -353,22 +401,32 @@ void ACL::parse(const TypedList &subject) TypedList &first = subject[3]; if (first.type() == CSSM_ACL_SUBJECT_TYPE_ANY) { mForm = allowAllForm; + secinfo("SecAccess", "parsed a Threshhold (%d) as an allowAllForm (%d)", subject.type(), mForm); return; } // parse other (code signing) elements - for (uint32 n = 0; n < count - 1; n++) - mAppList.push_back(new TrustedApplication(TypedList(subject[n + 3].list()))); + for (uint32 n = 0; n < count - 1; n++) { + mAppList.push_back(new TrustedApplication(TypedList(subject[n + 3].list()))); + secinfo("SecAccess", "found an application: %s", mAppList.back()->path()); + } } mForm = appListForm; + secinfo("SecAccess", "parsed a Threshhold (%d) as an appListForm (%d)", subject.type(), mForm); return; - default: + case CSSM_ACL_SUBJECT_TYPE_PARTITION: + mForm = integrityForm; + mIntegrity.copy(subject.last()->data()); + secinfo("SecAccess", "parsed a Partition (%d) as an integrityForm (%d)", subject.type(), mForm); + return; + default: + secinfo("SecAccess", "didn't find a type for %d, marking custom (%d)", subject.type(), mForm); mForm = customForm; mSubjectForm = chunkCopy(&subject); return; } } catch (const ParseError &) { - secdebug("SecAccess", "acl compile failed; marking custom"); + secinfo("SecAccess", "acl compile failed for type (%d); marking custom", subject.type()); mForm = customForm; mSubjectForm = chunkCopy(&subject); mAppList.clear(); @@ -408,6 +466,7 @@ void ACL::makeSubject() new(allocator) ListElement(allocator, mPromptDescription)); *mSubjectForm += new(allocator) ListElement(prompt); } + secinfo("SecAccess", "made an allowAllForm (%d) into a subjectForm (%d)", mForm, mSubjectForm->type()); return; case appListForm: { // threshold(1 of n+1) of { app1, ..., appn, PROMPT } @@ -424,10 +483,19 @@ void ACL::makeSubject() new(allocator) ListElement(allocator, mPromptDescription)); *mSubjectForm += new(allocator) ListElement(prompt); } + secinfo("SecAccess", "made an appListForm (%d) into a subjectForm (%d)", mForm, mSubjectForm->type()); return; + case integrityForm: + chunkFree(mSubjectForm, allocator); + mSubjectForm = new(allocator) TypedList(allocator, CSSM_ACL_SUBJECT_TYPE_PARTITION, + new(allocator) ListElement(allocator, mIntegrity)); + secinfo("SecAccess", "made an integrityForm (%d) into a subjectForm (%d)", mForm, mSubjectForm->type()); + return; case customForm: assert(mSubjectForm); // already set; keep it + secinfo("SecAccess", "have a customForm (%d), already have a subjectForm (%d)", mForm, mSubjectForm->type()); return; + default: assert(false); // unexpected }