X-Git-Url: https://git.saurik.com/apple/securityd.git/blobdiff_plain/24a291535d44686bc7959c7e398fab040e3e08a7..4cd1cad0dea00daa03e1b54fdf2797a02373ad5b:/src/acls.cpp diff --git a/src/acls.cpp b/src/acls.cpp index aa2524a..2c2cb5b 100644 --- a/src/acls.cpp +++ b/src/acls.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved. + * Copyright (c) 2000-2008 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -30,12 +30,15 @@ #include "server.h" #include "agentquery.h" #include "tokendatabase.h" +#include "acl_keychain.h" // ACL subjects whose Environments we implement #include #include #include +#include +#include // // SecurityServerAcl is virtual @@ -53,17 +56,20 @@ SecurityServerAcl::~SecurityServerAcl() // void SecurityServerAcl::getOwner(AclOwnerPrototype &owner) { + StLock _(aclSequence); ObjectAcl::cssmGetOwner(owner); } void SecurityServerAcl::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls) { + StLock _(aclSequence); ObjectAcl::cssmGetAcl(tag, count, acls); } void SecurityServerAcl::changeAcl(const AclEdit &edit, const AccessCredentials *cred, Database *db) { + StLock _(aclSequence); SecurityServerEnvironment env(*this, db); ObjectAcl::cssmChangeAcl(edit, cred, &env); } @@ -71,6 +77,7 @@ void SecurityServerAcl::changeAcl(const AclEdit &edit, const AccessCredentials * void SecurityServerAcl::changeOwner(const AclOwnerPrototype &newOwner, const AccessCredentials *cred, Database *db) { + StLock _(aclSequence); SecurityServerEnvironment env(*this, db); ObjectAcl::cssmChangeOwner(newOwner, cred, &env); } @@ -82,6 +89,7 @@ void SecurityServerAcl::changeOwner(const AclOwnerPrototype &newOwner, void SecurityServerAcl::validate(AclAuthorization auth, const AccessCredentials *cred, Database *db) { SecurityServerEnvironment env(*this, db); + StLock objectSequence(aclSequence); StLock processSequence(Server::process().aclSequence); ObjectAcl::validate(auth, cred, &env); @@ -94,6 +102,91 @@ void SecurityServerAcl::validate(AclAuthorization auth, const Context &context, } +// +// This helper tries to add the (new) subject given to the ACL +// whose validation is currently proceeding through context. +// This will succeed if the ACL is in standard form, which means +// a ThresholdAclSubject. +// The new subject will be added at the front (so it is checked first +// from now on), and as a side effect we'll notify the client side to +// re-encode the object. +// Returns true if the edit could be done, or false if the ACL wasn't +// standard enough. May throw if the ACL is malformed or otherwise messed up. +// +// This is a self-contained helper that is here merely because it's "about" +// ACLs and has no better home. +// +bool SecurityServerAcl::addToStandardACL(const AclValidationContext &context, AclSubject *subject) +{ + if (SecurityServerEnvironment *env = context.environment()) + if (ThresholdAclSubject *threshold = env->standardSubject(context)) { + unsigned size = threshold->count(); + if (dynamic_cast(threshold->subject(size-1))) { + // looks standard enough + secdebug("acl", "adding new subject %p to from of threshold ACL", subject); + threshold->add(subject, 0); + + // tell the ACL it's been modified + context.acl()->changedAcl(); + + // trigger a special notification code on (otherwise successful) return + Server::connection().overrideReturn(CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT); + return true; + } + } + secdebug("acl", "ACL is not standard form; cannot edit"); + return false; +} + + +// +// Look at the ACL whose validation is currently proceeding through context. +// If it LOOKS like a plausible version of a legacy "dot mac item" ACL. +// We don't have access to the database attributes of the item up here in the +// securityd sky, so we have to apply a heuristic based on which applications (by path) +// are given access to the item. +// So this is strictly a heuristic. The potential downside is that we may inadvertently +// give access to new .Mac authorized Apple (only) applications when the user only intended +// a limited set of extremely popular Apple (only) applications that just happen to all be +// .Mac authorized today. We can live with that. +// +bool SecurityServerAcl::looksLikeLegacyDotMac(const AclValidationContext &context) +{ + static const char * const prototypicalDotMacPath[] = { + "/Applications/Mail.app", + "/Applications/Safari.app", + "/Applications/iSync.app", + "/Applications/System Preferences.app", + "/Applications/iCal.app", + "/Applications/iChat.app", + "/Applications/iTunes.app", + "/Applications/Address Book.app", + "/Applications/iSync.app", + NULL // sentinel + }; + + static const unsigned threshold = 6; + + if (SecurityServerEnvironment *env = context.environment()) { + if (ThresholdAclSubject *list = env->standardSubject(context)) { + unsigned count = list->count(); + unsigned matches = 0; + for (unsigned n = 0; n < count; ++n) { + if (CodeSignatureAclSubject *app = dynamic_cast(list->subject(n))) { + for (const char * const *p = prototypicalDotMacPath; *p; p++) + if (app->path() == *p) + matches++; + } + } + secdebug("codesign", "matched %d of %zd candididates (threshold=%d)", + matches, sizeof(prototypicalDotMacPath) / sizeof(char *) - 1, threshold); + return matches >= threshold; + } + } + return false; +} + + // // External storage interface // @@ -135,10 +228,10 @@ pid_t SecurityServerEnvironment::getpid() const // // CodeSignatureAclSubject personality: take code signature from active Process object // -bool SecurityServerEnvironment::verifyCodeSignature(const CodeSigning::Signature *signature, - const CssmData *comment) +bool SecurityServerEnvironment::verifyCodeSignature(const OSXVerifier &verifier, + const AclValidationContext &context) { - return Server::codeSignatures().verify(Server::process(), signature, comment); + return Server::codeSignatures().verify(Server::process(), verifier, context); } @@ -184,6 +277,15 @@ ObjectAcl *SecurityServerEnvironment::preAuthSource() } +// +// Autonomous ACL editing support +// +ThresholdAclSubject *SecurityServerEnvironment::standardSubject(const AclValidationContext &context) +{ + return dynamic_cast(context.subject()); +} + + // // The default AclSource denies having an ACL at all //