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"
35 #include "AuthorizationEngine.h"
41 using Authorization::AuthItemSet
;
42 using Authorization::AuthValueVector
;
43 using Security::OSXCode
;
45 const uint64_t kMaximumAuthorizationTries
= 10000;
48 // base for classes talking to com.apple.security.agent and com.apple.security.authhost
50 class SecurityAgentXPCConnection
: public SecurityAgentConnectionInterface
53 SecurityAgentXPCConnection(const AuthHostType type
= securityAgent
, Session
&session
= Server::session());
54 virtual ~SecurityAgentXPCConnection();
55 virtual void activate(bool ignoreUid
);
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 xpc_connection_t mXPCConnection
;
67 const RefPointer
<Connection
> mConnection
;
68 audit_token_t
*mAuditToken
;
77 // The main com.apple.security.agent/com.apple.security.authhost interaction base class
79 class SecurityAgentXPCQuery
: public SecurityAgentXPCConnection
82 static void killAllXPCClients();
84 typedef SecurityAgent::Reason Reason
;
86 SecurityAgentXPCQuery(const AuthHostType type
= securityAgent
, Session
&session
= Server::session());
89 void inferHints(Process
&thisProcess
);
90 void addHint(const char *name
, const void *value
= NULL
, UInt32 valueLen
= 0, UInt32 flags
= 0);
92 virtual ~SecurityAgentXPCQuery();
94 virtual void disconnect();
95 virtual void terminate();
96 void create(const char *pluginId
, const char *mechanismId
);
98 void setTerminateOnSleep(bool terminateOnSleep
) {mTerminateOnSleep
= terminateOnSleep
;}
99 bool getTerminateOnSleep() {return mTerminateOnSleep
;}
100 void setInput(const AuthItemSet
& inHints
, const AuthItemSet
& inContext
) { mInHints
= inHints
; mInContext
= inContext
; }
109 AuthItemSet mClientHints
;
110 AuthItemSet mImmutableHints
;
111 AuthItemSet mInHints
;
112 AuthItemSet mInContext
;
113 AuthItemSet mOutHints
;
114 AuthItemSet mOutContext
;
115 bool mAgentConnected
;
116 uint64_t mLastResult
;
117 bool mTerminateOnSleep
;
121 // Specialized for "rogue app" alert queries
123 class QueryKeychainUse
: public SecurityAgentXPCQuery
{
125 QueryKeychainUse(bool needPass
, const Database
*db
);
126 Reason
queryUser (const char* database
, const char *description
, AclAuthorization action
);
129 const KeychainDatabase
*mPassphraseCheck
; // NULL to not check passphrase
134 // Specialized for code signature adjustment queries
136 class QueryCodeCheck
: public SecurityAgentXPCQuery
{
138 bool operator () (const char *aclPath
);
143 // A query for an existing passphrase
145 class QueryOld
: public SecurityAgentXPCQuery
{
146 static const int maxTries
= kMaximumAuthorizationTries
;
148 QueryOld(Database
&db
) : database(db
) {setTerminateOnSleep(true);}
152 Reason
operator () ();
156 virtual Reason
accept(CssmManagedData
&) = 0;
160 class QueryUnlock
: public QueryOld
{
162 QueryUnlock(KeychainDatabase
&db
) : QueryOld(db
) { }
163 Reason
retrievePassword(CssmOwnedData
&passphrase
);
166 Reason
accept(CssmManagedData
&passphrase
);
170 class QueryKeybagPassphrase
: public SecurityAgentXPCQuery
{
172 QueryKeybagPassphrase(Session
&session
, int32_t retries
= kMaximumAuthorizationTries
);
175 Reason
accept(CssmManagedData
&passphrase
);
178 service_context_t mContext
;
182 class QueryKeybagNewPassphrase
: public QueryKeybagPassphrase
{
184 QueryKeybagNewPassphrase(Session
&session
);
186 Reason
query(CssmOwnedData
&oldPassphrase
, CssmOwnedData
&passphrase
);
190 // Repurpose QueryUnlock for PIN prompting
191 // Not very clean - but this stuff is an outdated hack as it is...
193 class QueryPIN
: public QueryOld
{
195 QueryPIN(Database
&db
);
197 const CssmData
&pin() const { return mPin
; }
200 Reason
accept(CssmManagedData
&pin
);
203 CssmAutoData mPin
; // PIN obtained
208 // A query for a new passphrase
210 class QueryNewPassphrase
: public SecurityAgentXPCQuery
{
211 static const int maxTries
= kMaximumAuthorizationTries
;
213 QueryNewPassphrase(Database
&db
, Reason reason
) :
214 database(db
), initialReason(reason
),
215 mPassphrase(Allocator::standard(Allocator::sensitive
)),
216 mOldPassphrase(Allocator::standard(Allocator::sensitive
)),
217 mPassphraseValid(false) { }
221 Reason
operator () (CssmOwnedData
&oldPassphrase
, CssmOwnedData
&passphrase
);
225 virtual Reason
accept(CssmManagedData
&passphrase
, CssmData
*oldPassphrase
);
228 Reason initialReason
;
229 CssmAutoData mPassphrase
;
230 CssmAutoData mOldPassphrase
;
231 bool mPassphraseValid
;
236 // Generic passphrase query (not associated with a database)
238 class QueryGenericPassphrase
: public SecurityAgentXPCQuery
{
240 QueryGenericPassphrase() { }
241 Reason
operator () (const CssmData
*prompt
, bool verify
,
245 Reason
query(const CssmData
*prompt
, bool verify
, string
&passphrase
);
250 // Generic secret query (not associated with a database)
252 class QueryDBBlobSecret
: public SecurityAgentXPCQuery
{
253 static const int maxTries
= kMaximumAuthorizationTries
;
255 QueryDBBlobSecret() { }
256 Reason
operator () (DbHandle
*dbHandleArray
, uint8 dbHandleArrayCount
, DbHandle
*dbHandleAuthenticated
);
259 Reason
query(DbHandle
*dbHandleArray
, uint8 dbHandleArrayCount
, DbHandle
*dbHandleAuthenticated
);
260 Reason
accept(CssmManagedData
&passphrase
, DbHandle
*dbHandlesToAuthenticate
, uint8 dbHandleCount
, DbHandle
*dbHandleAuthenticated
);
263 // hybrid of confirm-access and generic authentication queries, for
264 // securityd's use; keep the Frankenstein references to yourself
265 // (the alternative is to ask the user to unlock the system keychain,
266 // and you don't want that, do you?)
267 class QueryKeychainAuth
: public SecurityAgentXPCQuery
{
268 static const int maxTries
= kMaximumAuthorizationTries
;
270 QueryKeychainAuth() { }
271 // "prompt" can be NULL
272 Reason
operator () (const char *database
, const char *description
, AclAuthorization action
, const char *prompt
);
273 Reason
accept(string
&username
, string
&passphrase
);
276 #endif //_H_AGENTQUERY