/ securityd / src / agentquery.h
agentquery.h
  1  /*
  2   * Copyright (c) 2000-2005,2007-2010,2012-2013 Apple Inc. All Rights Reserved.
  3   * 
  4   * @APPLE_LICENSE_HEADER_START@
  5   * 
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. Please obtain a copy of the License at
 10   * http://www.opensource.apple.com/apsl/ and read it before using this
 11   * file.
 12   * 
 13   * The Original Code and all software distributed under the License are
 14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 18   * Please see the License for the specific language governing rights and
 19   * limitations under the License.
 20   * 
 21   * @APPLE_LICENSE_HEADER_END@
 22   */
 23  
 24  
 25  //
 26  // passphrases - canonical code to obtain passphrases
 27  //
 28  #ifndef _H_AGENTQUERY
 29  #define _H_AGENTQUERY
 30  
 31  #include <security_cdsa_utilities/AuthorizationData.h>
 32  #include <security_utilities/ccaudit.h> // some queries do their own authentication
 33  #include <Security/AuthorizationPlugin.h>
 34  #include "kcdatabase.h"
 35  #include "authhost.h"
 36  #include "server.h"
 37  #include "session.h"
 38  #include <xpc/xpc.h>
 39  
 40  using Authorization::AuthItemSet;
 41  using Authorization::AuthValueVector;
 42  using Security::OSXCode;
 43  
 44  #define kMaximumAuthorizationTries (10000)
 45  
 46  //
 47  // base for classes talking to com.apple.security.agent and com.apple.security.authhost 
 48  //
 49  class SecurityAgentXPCConnection
 50  {
 51  public:
 52      SecurityAgentXPCConnection(Session &session = Server::session());
 53      virtual ~SecurityAgentXPCConnection();
 54      virtual void activate(bool ignoreUid);
 55      virtual void disconnect()  { };
 56      virtual void terminate();
 57          
 58  protected:
 59      RefPointer<AuthHostInstance> mHostInstance;
 60      Session &mSession;
 61      xpc_connection_t mXPCConnection;
 62      const RefPointer<Connection> mConnection;
 63      audit_token_t *mAuditToken;
 64      uid_t mNobodyUID;
 65  
 66      bool inDarkWake();
 67  
 68  };
 69  
 70  
 71  //
 72  // The main com.apple.security.agent interaction base class
 73  //
 74  class SecurityAgentXPCQuery : public SecurityAgentXPCConnection
 75  {
 76  public:
 77      static void killAllXPCClients();
 78  	
 79      typedef SecurityAgent::Reason Reason;
 80  	
 81  	SecurityAgentXPCQuery(Session &session = Server::session());
 82  	
 83      
 84  	void inferHints(Process &thisProcess);
 85  	void addHint(const char *name, const void *value = NULL, UInt32 valueLen = 0, UInt32 flags = 0);
 86      
 87  	virtual ~SecurityAgentXPCQuery();
 88      
 89  	virtual void disconnect();
 90  	virtual void terminate();
 91  	void create(const char *pluginId, const char *mechanismId);
 92      void invoke();
 93      void setTerminateOnSleep(bool terminateOnSleep) {mTerminateOnSleep = terminateOnSleep;}
 94      bool getTerminateOnSleep() {return mTerminateOnSleep;}
 95      void setInput(const AuthItemSet& inHints, const AuthItemSet& inContext) { mInHints = inHints; mInContext = inContext; }
 96      void checkResult();
 97  
 98  	void readChoice();
 99      
100  	bool allow;
101  	bool remember;
102      
103  protected:
104  	AuthItemSet mClientHints;
105      AuthItemSet mImmutableHints;
106      AuthItemSet mInHints;
107      AuthItemSet mInContext;
108      AuthItemSet mOutHints;
109      AuthItemSet mOutContext;
110      bool mAgentConnected;
111      uint64_t mLastResult;
112      bool mTerminateOnSleep;
113  };
114  
115  //
116  // Specialized for "rogue app" alert queries
117  //
118  class QueryKeychainUse : public SecurityAgentXPCQuery {
119  public:
120      QueryKeychainUse(bool needPass, const Database *db);
121      Reason queryUser (const char* database, const char *description, AclAuthorization action);
122  
123  private:
124      const KeychainDatabase *mPassphraseCheck; // NULL to not check passphrase
125  };
126  
127  
128  //
129  // A query for an existing passphrase
130  //
131  class QueryOld : public SecurityAgentXPCQuery {
132  	static const int maxTries = kMaximumAuthorizationTries;
133  public:
134  	QueryOld(Database &db) : database(db) {setTerminateOnSleep(true);}
135  	
136  	Database &database;
137  	
138  	Reason operator () ();
139  	
140  protected:
141  	Reason query();
142  	virtual Reason accept(CssmManagedData &) = 0;
143  };
144  
145  
146  class QueryUnlock : public QueryOld {
147  public:
148  	QueryUnlock(KeychainDatabase &db) : QueryOld(db) { }
149      Reason retrievePassword(CssmOwnedData &passphrase);
150  	
151  protected:
152  	Reason accept(CssmManagedData &passphrase);
153  };
154  
155  
156  class QueryKeybagPassphrase : public SecurityAgentXPCQuery {
157  public:
158      QueryKeybagPassphrase(Session &session, int32_t retries = kMaximumAuthorizationTries);
159  
160      Reason query();
161      Reason accept(CssmManagedData &passphrase);
162  protected:
163      Session &mSession;
164      service_context_t mContext;
165      int32_t mRetries;
166  };
167  
168  class QueryKeybagNewPassphrase : public QueryKeybagPassphrase {
169  public:
170      QueryKeybagNewPassphrase(Session &session);
171  
172      Reason query(CssmOwnedData &oldPassphrase, CssmOwnedData &passphrase);
173  };
174  
175  //
176  // Repurpose QueryUnlock for PIN prompting
177  // Not very clean - but this stuff is an outdated hack as it is...
178  //
179  class QueryPIN : public QueryOld {
180  public:
181  	QueryPIN(Database &db);
182  	
183  	const CssmData &pin() const { return mPin; }
184  
185  protected:
186  	Reason accept(CssmManagedData &pin);
187  	
188  private:
189  	CssmAutoData mPin;		// PIN obtained
190  };
191  
192  
193  //
194  // A query for a new passphrase
195  //
196  class QueryNewPassphrase : public SecurityAgentXPCQuery {
197  	static const int maxTries = kMaximumAuthorizationTries;
198  public:
199  	QueryNewPassphrase(Database &db, Reason reason) :
200  	    database(db), initialReason(reason),
201  	    mPassphrase(Allocator::standard(Allocator::sensitive)),
202          mOldPassphrase(Allocator::standard(Allocator::sensitive)),
203  	    mPassphraseValid(false) { }
204  
205  	Database &database;
206  	
207  	Reason operator () (CssmOwnedData &oldPassphrase, CssmOwnedData &passphrase);
208  	
209  protected:
210  	Reason query();
211  	virtual Reason accept(CssmManagedData &passphrase, CssmData *oldPassphrase);
212  	
213  private:
214  	Reason initialReason;
215  	CssmAutoData mPassphrase;
216      CssmAutoData mOldPassphrase;
217      bool mPassphraseValid;
218  };
219  
220  
221  //
222  // Generic passphrase query (not associated with a database)
223  //
224  class QueryGenericPassphrase : public SecurityAgentXPCQuery {
225  public:
226      QueryGenericPassphrase()    { }
227      Reason operator () (const CssmData *prompt, bool verify,
228                          string &passphrase);
229      
230  protected:
231      Reason query(const CssmData *prompt, bool verify, string &passphrase);
232  };
233  
234  
235  //
236  // Generic secret query (not associated with a database)
237  //
238  class QueryDBBlobSecret : public SecurityAgentXPCQuery {
239  	static const int maxTries = kMaximumAuthorizationTries;
240  public:
241      QueryDBBlobSecret()    { }
242      Reason operator () (DbHandle *dbHandleArray, uint8 dbHandleArrayCount, DbHandle *dbHandleAuthenticated);
243      
244  protected:
245      Reason query(DbHandle *dbHandleArray, uint8 dbHandleArrayCount, DbHandle *dbHandleAuthenticated);
246  	Reason accept(CssmManagedData &passphrase, DbHandle *dbHandlesToAuthenticate, uint8 dbHandleCount, DbHandle *dbHandleAuthenticated);
247  };
248  
249  // hybrid of confirm-access and generic authentication queries, for
250  // securityd's use; keep the Frankenstein references to yourself
251  // (the alternative is to ask the user to unlock the system keychain,
252  // and you don't want that, do you?)  
253  class QueryKeychainAuth : public SecurityAgentXPCQuery {
254  	static const int maxTries = kMaximumAuthorizationTries;
255  public:
256      QueryKeychainAuth()  { }
257      // "prompt" can be NULL
258      Reason performQuery(const KeychainDatabase&, const char *description, AclAuthorization action, const char *prompt);
259      Reason accept(string &username, string &passphrase);
260  };
261  
262  #endif //_H_AGENTQUERY