2 * Copyright (c) 2000-2004,2008-2009 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 // passphrases - canonical code to obtain passphrases
31 #include <security_agent_client/agentclient.h>
32 #include <security_cdsa_utilities/AuthorizationData.h>
33 #include <security_utilities/ccaudit.h> // some queries do their own authentication
34 #include <Security/AuthorizationPlugin.h>
35 #include "kcdatabase.h"
36 #include "AuthorizationEngine.h"
42 using Authorization::AuthItemSet
;
43 using Authorization::AuthValueVector
;
44 using Security::OSXCode
;
47 // base for classes talking to SecurityAgent and authorizationhost
49 class SecurityAgentConnection
: public SecurityAgent::Client
,
50 public SecurityAgentConnectionInterface
53 SecurityAgentConnection(const AuthHostType type
= securityAgent
, Session
&session
= Server::session());
54 virtual ~SecurityAgentConnection();
55 virtual void activate();
56 virtual void reconnect();
57 virtual void disconnect() { };
58 virtual void terminate();
60 AuthHostType
hostType() { return mAuthHostType
; }
63 AuthHostType mAuthHostType
;
64 RefPointer
<AuthHostInstance
> mHostInstance
;
66 const RefPointer
<Connection
> mConnection
;
67 audit_token_t
*mAuditToken
;
71 // base for classes talking to com.apple.security.agent and com.apple.security.authhost
73 class SecurityAgentXPCConnection
: public SecurityAgentConnectionInterface
76 SecurityAgentXPCConnection(const AuthHostType type
= securityAgent
, Session
&session
= Server::session());
77 virtual ~SecurityAgentXPCConnection();
78 virtual void activate(bool ignoreUid
);
79 virtual void reconnect();
80 virtual void disconnect() { };
81 virtual void terminate();
83 AuthHostType
hostType() { return mAuthHostType
; }
86 AuthHostType mAuthHostType
;
87 RefPointer
<AuthHostInstance
> mHostInstance
;
89 xpc_connection_t mXPCConnection
;
90 xpc_connection_t mXPCStubConnection
;
91 const RefPointer
<Connection
> mConnection
;
92 audit_token_t
*mAuditToken
;
100 // The main SecurityAgent/authorizationhost interaction base class
102 class SecurityAgentQuery
: public SecurityAgentConnection
105 typedef SecurityAgent::Reason Reason
;
107 SecurityAgentQuery(const AuthHostType type
= securityAgent
, Session
&session
= Server::session());
110 void inferHints(Process
&thisProcess
);
111 void addHint(const char *name
, const void *value
= NULL
, UInt32 valueLen
= 0, UInt32 flags
= 0);
113 virtual ~SecurityAgentQuery();
115 virtual void disconnect();
116 virtual void terminate();
117 void create(const char *pluginId
, const char *mechanismId
, const SessionId inSessionId
);
125 AuthItemSet mClientHints
;
129 // The main com.apple.security.agent/com.apple.security.authhost interaction base class
131 class SecurityAgentXPCQuery
: public SecurityAgentXPCConnection
134 static void killAllXPCClients();
136 typedef SecurityAgent::Reason Reason
;
138 SecurityAgentXPCQuery(const AuthHostType type
= securityAgent
, Session
&session
= Server::session());
141 void inferHints(Process
&thisProcess
);
142 void addHint(const char *name
, const void *value
= NULL
, UInt32 valueLen
= 0, UInt32 flags
= 0);
144 virtual ~SecurityAgentXPCQuery();
146 virtual void disconnect();
147 virtual void terminate();
148 void create(const char *pluginId
, const char *mechanismId
, const SessionId inSessionId
);
150 void setTerminateOnSleep(bool terminateOnSleep
) {mTerminateOnSleep
= terminateOnSleep
;}
151 bool getTerminateOnSleep() {return mTerminateOnSleep
;}
152 void setInput(const AuthItemSet
& inHints
, const AuthItemSet
& inContext
) { mInHints
= inHints
; mInContext
= inContext
; }
161 AuthItemSet mClientHints
;
162 AuthItemSet mImmutableHints
;
163 AuthItemSet mInHints
;
164 AuthItemSet mInContext
;
165 AuthItemSet mOutHints
;
166 AuthItemSet mOutContext
;
167 bool mAgentConnected
;
168 uint64_t mLastResult
;
169 bool mTerminateOnSleep
;
173 // Specialized for "rogue app" alert queries
175 class QueryKeychainUse
: public SecurityAgentXPCQuery
{
177 QueryKeychainUse(bool needPass
, const Database
*db
);
178 Reason
queryUser (const char* database
, const char *description
, AclAuthorization action
);
181 const KeychainDatabase
*mPassphraseCheck
; // NULL to not check passphrase
186 // Specialized for code signature adjustment queries
188 class QueryCodeCheck
: public SecurityAgentXPCQuery
{
190 bool operator () (const char *aclPath
);
195 // A query for an existing passphrase
197 class QueryOld
: public SecurityAgentXPCQuery
{
198 static const int maxTries
= kMaximumAuthorizationTries
;
200 QueryOld(Database
&db
) : database(db
) {setTerminateOnSleep(true);}
204 Reason
operator () ();
208 virtual Reason
accept(CssmManagedData
&) = 0;
212 class QueryUnlock
: public QueryOld
{
214 QueryUnlock(KeychainDatabase
&db
) : QueryOld(db
) { }
215 Reason
retrievePassword(CssmOwnedData
&passphrase
);
218 Reason
accept(CssmManagedData
&passphrase
);
222 class QueryKeybagPassphrase
: public SecurityAgentXPCQuery
{
224 QueryKeybagPassphrase(Session
&session
, int32_t retries
= kMaximumAuthorizationTries
);
227 Reason
accept(CssmManagedData
&passphrase
);
230 service_context_t mContext
;
234 class QueryKeybagNewPassphrase
: public QueryKeybagPassphrase
{
236 QueryKeybagNewPassphrase(Session
&session
);
238 Reason
query(CssmOwnedData
&oldPassphrase
, CssmOwnedData
&passphrase
);
242 // Repurpose QueryUnlock for PIN prompting
243 // Not very clean - but this stuff is an outdated hack as it is...
245 class QueryPIN
: public QueryOld
{
247 QueryPIN(Database
&db
);
249 const CssmData
&pin() const { return mPin
; }
252 Reason
accept(CssmManagedData
&pin
);
255 CssmAutoData mPin
; // PIN obtained
260 // A query for a new passphrase
262 class QueryNewPassphrase
: public SecurityAgentXPCQuery
{
263 static const int maxTries
= kMaximumAuthorizationTries
;
265 QueryNewPassphrase(Database
&db
, Reason reason
) :
266 database(db
), initialReason(reason
),
267 mPassphrase(Allocator::standard(Allocator::sensitive
)),
268 mOldPassphrase(Allocator::standard(Allocator::sensitive
)),
269 mPassphraseValid(false) { }
273 Reason
operator () (CssmOwnedData
&oldPassphrase
, CssmOwnedData
&passphrase
);
277 virtual Reason
accept(CssmManagedData
&passphrase
, CssmData
*oldPassphrase
);
280 Reason initialReason
;
281 CssmAutoData mPassphrase
;
282 CssmAutoData mOldPassphrase
;
283 bool mPassphraseValid
;
288 // Generic passphrase query (not associated with a database)
290 class QueryGenericPassphrase
: public SecurityAgentXPCQuery
{
292 QueryGenericPassphrase() { }
293 Reason
operator () (const CssmData
*prompt
, bool verify
,
297 Reason
query(const CssmData
*prompt
, bool verify
, string
&passphrase
);
302 // Generic secret query (not associated with a database)
304 class QueryDBBlobSecret
: public SecurityAgentXPCQuery
{
305 static const int maxTries
= kMaximumAuthorizationTries
;
307 QueryDBBlobSecret() { }
308 Reason
operator () (DbHandle
*dbHandleArray
, uint8 dbHandleArrayCount
, DbHandle
*dbHandleAuthenticated
);
311 Reason
query(DbHandle
*dbHandleArray
, uint8 dbHandleArrayCount
, DbHandle
*dbHandleAuthenticated
);
312 Reason
accept(CssmManagedData
&passphrase
, DbHandle
*dbHandlesToAuthenticate
, uint8 dbHandleCount
, DbHandle
*dbHandleAuthenticated
);
315 class QueryInvokeMechanism
: public SecurityAgentQuery
, public RefCount
{
317 QueryInvokeMechanism(const AuthHostType type
, Session
&session
);
318 void initialize(const string
&inPluginId
, const string
&inMechanismId
, const AuthValueVector
&arguments
, const SessionId inSessionId
= 0);
319 void run(const AuthValueVector
&inArguments
, AuthItemSet
&inHints
, AuthItemSet
&inContext
, AuthorizationResult
*outResult
);
321 bool operator () (const string
&inPluginId
, const string
&inMechanismId
, const Authorization::AuthValueVector
&inArguments
, AuthItemSet
&inHints
, AuthItemSet
&inContext
, AuthorizationResult
*outResult
);
322 void terminateAgent();
323 //~QueryInvokeMechanism();
325 AuthValueVector mArguments
;
328 // hybrid of confirm-access and generic authentication queries, for
329 // securityd's use; keep the Frankenstein references to yourself
330 // (the alternative is to ask the user to unlock the system keychain,
331 // and you don't want that, do you?)
332 class QueryKeychainAuth
: public SecurityAgentXPCQuery
{
333 static const int maxTries
= kMaximumAuthorizationTries
;
335 QueryKeychainAuth() { }
336 // "prompt" can be NULL
337 Reason
operator () (const char *database
, const char *description
, AclAuthorization action
, const char *prompt
);
338 Reason
accept(string
&username
, string
&passphrase
);
341 #endif //_H_AGENTQUERY