X-Git-Url: https://git.saurik.com/apple/securityd.git/blobdiff_plain/5968d166aac117ec986929b2f8fb9ce7fae2e599..4cd1cad0dea00daa03e1b54fdf2797a02373ad5b:/src/session.cpp diff --git a/src/session.cpp b/src/session.cpp index 42d51c4..b79f683 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -44,6 +44,7 @@ #include "database.h" #include "server.h" #include +#include using namespace CommonCriteria; @@ -63,7 +64,7 @@ const char Session::kRealname[] = "realname"; // Create a Session object from initial parameters (create) // Session::Session(const AuditInfo &audit, Server &server) - : mAudit(audit), mSecurityAgent(NULL), mAuthHost(NULL) + : mAudit(audit), mSecurityAgent(NULL), mAuthHost(NULL), mKeybagState(0) { // link to Server as the global nexus in the object mesh parent(server); @@ -129,14 +130,32 @@ Session &Session::find(pid_t id, bool create) void Session::destroy(SessionId id) { // remove session from session map - StLock _(mSessionLock); - SessionMap::iterator it = mSessions.find(id); - if (it != mSessions.end()) { - RefPointer session = it->second; - assert(session->sessionId() == id); - mSessions.erase(it); - session->kill(); - } + bool unlocked = false; + RefPointer session = NULL; + { + StLock _(mSessionLock); + SessionMap::iterator it = mSessions.find(id); + if (it != mSessions.end()) { + session = it->second; + assert(session->sessionId() == id); + mSessions.erase(it); + + for (SessionMap::iterator kb_it = mSessions.begin(); kb_it != mSessions.end(); kb_it++) { + RefPointer kb_session = kb_it->second; + if (kb_session->originatorUid() == session->originatorUid()) { + if (kb_session->keybagGetState(session_keybag_unlocked)) unlocked = true; + } + } + } + } + + if (session.get()) { + if (!unlocked) { + service_context_t context = session->get_current_service_context(); + service_client_kb_lock(&context); + } + session->kill(); + } } @@ -172,7 +191,66 @@ void Session::kill() // void Session::updateAudit() const { - mAudit.get(mAudit.sessionId()); + CommonCriteria::AuditInfo info; + try { + info.get(mAudit.sessionId()); + } catch (...) { + return; + } + mAudit = info; +} + +void Session::verifyKeyStorePassphrase(int32_t retries) +{ + QueryKeybagPassphrase keybagQuery(*this, retries); + keybagQuery.inferHints(Server::process()); + if (keybagQuery.query() != SecurityAgent::noReason) { + CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED); + } +} + +void Session::changeKeyStorePassphrase() +{ + service_context_t context = get_current_service_context(); + QueryKeybagNewPassphrase keybagQuery(*this); + keybagQuery.inferHints(Server::process()); + CssmAutoData pass(Allocator::standard(Allocator::sensitive)); + CssmAutoData oldPass(Allocator::standard(Allocator::sensitive)); + SecurityAgent::Reason queryReason = keybagQuery.query(oldPass, pass); + if (queryReason == SecurityAgent::noReason) { + service_client_kb_change_secret(&context, oldPass.data(), (int)oldPass.length(), pass.data(), (int)pass.length()); + } else { + CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED); + } +} + +void Session::resetKeyStorePassphrase(const CssmData &passphrase) +{ + service_context_t context = get_current_service_context(); + service_client_kb_reset(&context, passphrase.data(), (int)passphrase.length()); +} + +service_context_t Session::get_current_service_context() +{ + // if this gets called from a timer there is no connection() object. + // need to check for valid connection object and pass the audit token along + service_context_t context = { sessionId(), originatorUid(), {} }; //*Server::connection().auditToken() + return context; +} + +void Session::keybagClearState(int state) +{ + mKeybagState &= ~state; +} + +void Session::keybagSetState(int state) +{ + mKeybagState |= state; +} + +bool Session::keybagGetState(int state) +{ + return mKeybagState & state; } @@ -203,6 +281,8 @@ void Session::invalidateAuthHosts() // void Session::processSystemSleep() { + SecurityAgentXPCQuery::killAllXPCClients(); + StLock _(mSessionLock); for (SessionMap::const_iterator it = mSessions.begin(); it != mSessions.end(); it++) it->second->allReferences(&DbCommon::sleepProcessing); @@ -397,7 +477,7 @@ void Session::setAttributes(SessionAttributeBits bits) { StLock _(*this); updateAudit(); - assert((bits & ~settableAttributes) == 0); +// assert((bits & ~settableAttributes) == 0); mAudit.ai_flags = bits; mAudit.set(); } @@ -411,6 +491,14 @@ void Session::setupAttributes(SessionCreationFlags flags, SessionAttributeBits a MacOSError::throwMe(errSessionAuthorizationDenied); } +uid_t Session::originatorUid() +{ + if (mAudit.uid() == AU_DEFAUDITID) { + StLock _(*this); + updateAudit(); + } + return mAudit.uid(); +} // // Authorization database I/O