]> git.saurik.com Git - apple/security.git/blobdiff - securityd/src/agentquery.h
Security-57031.1.35.tar.gz
[apple/security.git] / securityd / src / agentquery.h
diff --git a/securityd/src/agentquery.h b/securityd/src/agentquery.h
new file mode 100644 (file)
index 0000000..b0cc167
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2000-2005,2007-2010,2012-2013 Apple 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@
+ */
+
+
+//
+// passphrases - canonical code to obtain passphrases
+//
+#ifndef _H_AGENTQUERY
+#define _H_AGENTQUERY
+
+#include <security_agent_client/agentclient.h>
+#include <security_cdsa_utilities/AuthorizationData.h>
+#include <security_utilities/ccaudit.h> // some queries do their own authentication
+#include <Security/AuthorizationPlugin.h>
+#include "kcdatabase.h"
+#include "AuthorizationEngine.h"
+#include "authhost.h"
+#include "server.h"
+#include "session.h"
+#include <xpc/xpc.h>
+
+using Authorization::AuthItemSet;
+using Authorization::AuthValueVector;
+using Security::OSXCode;
+
+//
+// base for classes talking to SecurityAgent and authorizationhost
+//
+class SecurityAgentConnection : public SecurityAgent::Client,
+public SecurityAgentConnectionInterface
+{
+public:
+    SecurityAgentConnection(const AuthHostType type = securityAgent, Session &session = Server::session());
+    virtual ~SecurityAgentConnection();
+    virtual void activate();
+    virtual void reconnect();
+    virtual void disconnect()  { };
+    virtual void terminate();
+    
+    AuthHostType hostType()  { return mAuthHostType; }
+    
+protected:
+    AuthHostType mAuthHostType;
+    RefPointer<AuthHostInstance> mHostInstance;
+    Port mPort;
+    const RefPointer<Connection> mConnection;
+    audit_token_t *mAuditToken;
+};
+
+//
+// base for classes talking to com.apple.security.agent and com.apple.security.authhost 
+//
+class SecurityAgentXPCConnection : public SecurityAgentConnectionInterface
+{
+public:
+    SecurityAgentXPCConnection(const AuthHostType type = securityAgent, Session &session = Server::session());
+    virtual ~SecurityAgentXPCConnection();
+    virtual void activate(bool ignoreUid);
+    virtual void reconnect();
+    virtual void disconnect()  { };
+    virtual void terminate();
+    
+    AuthHostType hostType()  { return mAuthHostType; }
+    
+protected:
+    AuthHostType mAuthHostType;
+    RefPointer<AuthHostInstance> mHostInstance;
+    Session &mSession;
+    xpc_connection_t mXPCConnection;
+    xpc_connection_t mXPCStubConnection;
+    const RefPointer<Connection> mConnection;
+    audit_token_t *mAuditToken;
+    uid_t mNobodyUID;
+
+    bool inDarkWake();
+
+};
+
+//
+// The main SecurityAgent/authorizationhost interaction base class
+//
+class SecurityAgentQuery : public SecurityAgentConnection
+{
+public:
+       typedef SecurityAgent::Reason Reason;
+       
+       SecurityAgentQuery(const AuthHostType type = securityAgent, Session &session = Server::session());
+       
+    
+       void inferHints(Process &thisProcess);
+       void addHint(const char *name, const void *value = NULL, UInt32 valueLen = 0, UInt32 flags = 0);
+    
+       virtual ~SecurityAgentQuery();
+    
+       virtual void disconnect();
+       virtual void terminate();
+       void create(const char *pluginId, const char *mechanismId, const SessionId inSessionId);
+    
+       void readChoice();
+    
+       bool allow;
+       bool remember;
+    
+protected:
+       AuthItemSet mClientHints;
+};
+
+//
+// The main com.apple.security.agent/com.apple.security.authhost interaction base class
+//
+class SecurityAgentXPCQuery : public SecurityAgentXPCConnection
+{
+public:
+    static void killAllXPCClients();
+       
+    typedef SecurityAgent::Reason Reason;
+       
+       SecurityAgentXPCQuery(const AuthHostType type = securityAgent, Session &session = Server::session());
+       
+    
+       void inferHints(Process &thisProcess);
+       void addHint(const char *name, const void *value = NULL, UInt32 valueLen = 0, UInt32 flags = 0);
+    
+       virtual ~SecurityAgentXPCQuery();
+    
+       virtual void disconnect();
+       virtual void terminate();
+       void create(const char *pluginId, const char *mechanismId, const SessionId inSessionId);
+    OSStatus invoke();
+    void setTerminateOnSleep(bool terminateOnSleep) {mTerminateOnSleep = terminateOnSleep;}
+    bool getTerminateOnSleep() {return mTerminateOnSleep;}
+    void setInput(const AuthItemSet& inHints, const AuthItemSet& inContext) { mInHints = inHints; mInContext = inContext; }
+    void checkResult();
+
+       void readChoice();
+    
+       bool allow;
+       bool remember;
+    
+protected:
+       AuthItemSet mClientHints;
+    AuthItemSet mImmutableHints;
+    AuthItemSet mInHints;
+    AuthItemSet mInContext;
+    AuthItemSet mOutHints;
+    AuthItemSet mOutContext;
+    bool mAgentConnected;
+    uint64_t mLastResult;
+    bool mTerminateOnSleep;
+};
+
+//
+// Specialized for "rogue app" alert queries
+//
+class QueryKeychainUse : public SecurityAgentXPCQuery {
+public:
+    QueryKeychainUse(bool needPass, const Database *db);
+    Reason queryUser (const char* database, const char *description, AclAuthorization action);
+
+private:
+    const KeychainDatabase *mPassphraseCheck; // NULL to not check passphrase
+};
+
+
+//
+// Specialized for code signature adjustment queries
+//
+class QueryCodeCheck : public SecurityAgentXPCQuery {
+public:
+    bool operator () (const char *aclPath);
+};
+
+
+//
+// A query for an existing passphrase
+//
+class QueryOld : public SecurityAgentXPCQuery {
+       static const int maxTries = kMaximumAuthorizationTries;
+public:
+       QueryOld(Database &db) : database(db) {setTerminateOnSleep(true);}
+       
+       Database &database;
+       
+       Reason operator () ();
+       
+protected:
+       Reason query();
+       virtual Reason accept(CssmManagedData &) = 0;
+};
+
+
+class QueryUnlock : public QueryOld {
+public:
+       QueryUnlock(KeychainDatabase &db) : QueryOld(db) { }
+    Reason retrievePassword(CssmOwnedData &passphrase);
+       
+protected:
+       Reason accept(CssmManagedData &passphrase);
+};
+
+
+class QueryKeybagPassphrase : public SecurityAgentXPCQuery {
+public:
+    QueryKeybagPassphrase(Session &session, int32_t retries = kMaximumAuthorizationTries);
+
+    Reason query();
+    Reason accept(CssmManagedData &passphrase);
+protected:
+    Session &mSession;
+    service_context_t mContext;
+    int32_t mRetries;
+};
+
+class QueryKeybagNewPassphrase : public QueryKeybagPassphrase {
+public:
+    QueryKeybagNewPassphrase(Session &session);
+
+    Reason query(CssmOwnedData &oldPassphrase, CssmOwnedData &passphrase);
+};
+
+//
+// Repurpose QueryUnlock for PIN prompting
+// Not very clean - but this stuff is an outdated hack as it is...
+//
+class QueryPIN : public QueryOld {
+public:
+       QueryPIN(Database &db);
+       
+       const CssmData &pin() const { return mPin; }
+
+protected:
+       Reason accept(CssmManagedData &pin);
+       
+private:
+       CssmAutoData mPin;              // PIN obtained
+};
+
+
+//
+// A query for a new passphrase
+//
+class QueryNewPassphrase : public SecurityAgentXPCQuery {
+       static const int maxTries = kMaximumAuthorizationTries;
+public:
+       QueryNewPassphrase(Database &db, Reason reason) :
+           database(db), initialReason(reason),
+           mPassphrase(Allocator::standard(Allocator::sensitive)),
+        mOldPassphrase(Allocator::standard(Allocator::sensitive)),
+           mPassphraseValid(false) { }
+
+       Database &database;
+       
+       Reason operator () (CssmOwnedData &oldPassphrase, CssmOwnedData &passphrase);
+       
+protected:
+       Reason query();
+       virtual Reason accept(CssmManagedData &passphrase, CssmData *oldPassphrase);
+       
+private:
+       Reason initialReason;
+       CssmAutoData mPassphrase;
+    CssmAutoData mOldPassphrase;
+    bool mPassphraseValid;
+};
+
+
+//
+// Generic passphrase query (not associated with a database)
+//
+class QueryGenericPassphrase : public SecurityAgentXPCQuery {
+public:
+    QueryGenericPassphrase()    { }
+    Reason operator () (const CssmData *prompt, bool verify,
+                        string &passphrase);
+    
+protected:
+    Reason query(const CssmData *prompt, bool verify, string &passphrase);
+};
+
+
+//
+// Generic secret query (not associated with a database)
+//
+class QueryDBBlobSecret : public SecurityAgentXPCQuery {
+       static const int maxTries = kMaximumAuthorizationTries;
+public:
+    QueryDBBlobSecret()    { }
+    Reason operator () (DbHandle *dbHandleArray, uint8 dbHandleArrayCount, DbHandle *dbHandleAuthenticated);
+    
+protected:
+    Reason query(DbHandle *dbHandleArray, uint8 dbHandleArrayCount, DbHandle *dbHandleAuthenticated);
+       Reason accept(CssmManagedData &passphrase, DbHandle *dbHandlesToAuthenticate, uint8 dbHandleCount, DbHandle *dbHandleAuthenticated);
+};
+
+class QueryInvokeMechanism : public SecurityAgentQuery, public RefCount {
+public:
+       QueryInvokeMechanism(const AuthHostType type, Session &session);
+    void initialize(const string &inPluginId, const string &inMechanismId, const AuthValueVector &arguments, const SessionId inSessionId = 0);
+    void run(const AuthValueVector &inArguments, AuthItemSet &inHints, AuthItemSet &inContext, AuthorizationResult *outResult);
+
+    bool operator () (const string &inPluginId, const string &inMechanismId, const Authorization::AuthValueVector &inArguments, AuthItemSet &inHints, AuthItemSet &inContext, AuthorizationResult *outResult);
+    void terminateAgent();
+    //~QueryInvokeMechanism();
+
+    AuthValueVector mArguments;
+};
+
+// hybrid of confirm-access and generic authentication queries, for
+// securityd's use; keep the Frankenstein references to yourself
+// (the alternative is to ask the user to unlock the system keychain,
+// and you don't want that, do you?)  
+class QueryKeychainAuth : public SecurityAgentXPCQuery {
+       static const int maxTries = kMaximumAuthorizationTries;
+public:
+    QueryKeychainAuth()  { }
+    // "prompt" can be NULL
+    Reason operator () (const char *database, const char *description, AclAuthorization action, const char *prompt);
+    Reason accept(string &username, string &passphrase);
+};
+
+#endif //_H_AGENTQUERY