2 * Copyright (c) 2000-2005,2007-2010,2012-2013 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_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"
40 using Authorization::AuthItemSet
;
41 using Authorization::AuthValueVector
;
42 using Security::OSXCode
;
44 #define kMaximumAuthorizationTries (10000)
47 // base for classes talking to com.apple.security.agent and com.apple.security.authhost
49 class SecurityAgentXPCConnection
52 SecurityAgentXPCConnection(Session
&session
= Server::session());
53 virtual ~SecurityAgentXPCConnection();
54 virtual void activate(bool ignoreUid
);
55 virtual void disconnect() { };
56 virtual void terminate();
59 RefPointer
<AuthHostInstance
> mHostInstance
;
61 xpc_connection_t mXPCConnection
;
62 const RefPointer
<Connection
> mConnection
;
63 audit_token_t
*mAuditToken
;
72 // The main com.apple.security.agent interaction base class
74 class SecurityAgentXPCQuery
: public SecurityAgentXPCConnection
77 static void killAllXPCClients();
79 typedef SecurityAgent::Reason Reason
;
81 SecurityAgentXPCQuery(Session
&session
= Server::session());
84 void inferHints(Process
&thisProcess
);
85 void addHint(const char *name
, const void *value
= NULL
, UInt32 valueLen
= 0, UInt32 flags
= 0);
87 virtual ~SecurityAgentXPCQuery();
89 virtual void disconnect();
90 virtual void terminate();
91 void create(const char *pluginId
, const char *mechanismId
);
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
; }
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
;
116 // Specialized for "rogue app" alert queries
118 class QueryKeychainUse
: public SecurityAgentXPCQuery
{
120 QueryKeychainUse(bool needPass
, const Database
*db
);
121 Reason
queryUser (const char* database
, const char *description
, AclAuthorization action
);
124 const KeychainDatabase
*mPassphraseCheck
; // NULL to not check passphrase
129 // A query for an existing passphrase
131 class QueryOld
: public SecurityAgentXPCQuery
{
132 static const int maxTries
= kMaximumAuthorizationTries
;
134 QueryOld(Database
&db
) : database(db
) {setTerminateOnSleep(true);}
138 Reason
operator () ();
142 virtual Reason
accept(CssmManagedData
&) = 0;
146 class QueryUnlock
: public QueryOld
{
148 QueryUnlock(KeychainDatabase
&db
) : QueryOld(db
) { }
149 Reason
retrievePassword(CssmOwnedData
&passphrase
);
152 Reason
accept(CssmManagedData
&passphrase
);
156 class QueryKeybagPassphrase
: public SecurityAgentXPCQuery
{
158 QueryKeybagPassphrase(Session
&session
, int32_t retries
= kMaximumAuthorizationTries
);
161 Reason
accept(CssmManagedData
&passphrase
);
164 service_context_t mContext
;
168 class QueryKeybagNewPassphrase
: public QueryKeybagPassphrase
{
170 QueryKeybagNewPassphrase(Session
&session
);
172 Reason
query(CssmOwnedData
&oldPassphrase
, CssmOwnedData
&passphrase
);
176 // Repurpose QueryUnlock for PIN prompting
177 // Not very clean - but this stuff is an outdated hack as it is...
179 class QueryPIN
: public QueryOld
{
181 QueryPIN(Database
&db
);
183 const CssmData
&pin() const { return mPin
; }
186 Reason
accept(CssmManagedData
&pin
);
189 CssmAutoData mPin
; // PIN obtained
194 // A query for a new passphrase
196 class QueryNewPassphrase
: public SecurityAgentXPCQuery
{
197 static const int maxTries
= kMaximumAuthorizationTries
;
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) { }
207 Reason
operator () (CssmOwnedData
&oldPassphrase
, CssmOwnedData
&passphrase
);
211 virtual Reason
accept(CssmManagedData
&passphrase
, CssmData
*oldPassphrase
);
214 Reason initialReason
;
215 CssmAutoData mPassphrase
;
216 CssmAutoData mOldPassphrase
;
217 bool mPassphraseValid
;
222 // Generic passphrase query (not associated with a database)
224 class QueryGenericPassphrase
: public SecurityAgentXPCQuery
{
226 QueryGenericPassphrase() { }
227 Reason
operator () (const CssmData
*prompt
, bool verify
,
231 Reason
query(const CssmData
*prompt
, bool verify
, string
&passphrase
);
236 // Generic secret query (not associated with a database)
238 class QueryDBBlobSecret
: public SecurityAgentXPCQuery
{
239 static const int maxTries
= kMaximumAuthorizationTries
;
241 QueryDBBlobSecret() { }
242 Reason
operator () (DbHandle
*dbHandleArray
, uint8 dbHandleArrayCount
, DbHandle
*dbHandleAuthenticated
);
245 Reason
query(DbHandle
*dbHandleArray
, uint8 dbHandleArrayCount
, DbHandle
*dbHandleAuthenticated
);
246 Reason
accept(CssmManagedData
&passphrase
, DbHandle
*dbHandlesToAuthenticate
, uint8 dbHandleCount
, DbHandle
*dbHandleAuthenticated
);
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
;
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
);
262 #endif //_H_AGENTQUERY