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"
41 using Authorization::AuthItemSet
;
42 using Authorization::AuthValueVector
;
43 using Security::OSXCode
;
46 // base for classes talking to SecurityAgent and authorizationhost
48 class SecurityAgentConnection
: public SecurityAgent::Client
,
49 public SecurityAgentConnectionInterface
52 SecurityAgentConnection(const AuthHostType type
= securityAgent
, Session
&session
= Server::session());
53 virtual ~SecurityAgentConnection();
54 virtual void activate();
55 virtual void reconnect();
56 virtual void disconnect() { };
57 virtual void terminate();
59 AuthHostType
hostType() { return mAuthHostType
; }
62 AuthHostType mAuthHostType
;
63 RefPointer
<AuthHostInstance
> mHostInstance
;
65 const RefPointer
<Connection
> mConnection
;
66 audit_token_t
*mAuditToken
;
70 // Special wrapper around SecurityAgent::Client transaction interfaces.
71 // Not currently used because this was intended to support
72 // SecurityAgent's/authorizationhost's use of Foundation's enable/disable-sudden-
73 // termination APIs, but the latter don't work for non-direct children of
74 // launchd. Kept around because securityd might need its own child-transaction
77 class SecurityAgentTransaction
: public SecurityAgentConnection
80 SecurityAgentTransaction(const AuthHostType type
= securityAgent
, Session
&session
= Server::session(), bool startNow
= true);
81 ~SecurityAgentTransaction();
85 bool started() { return mStarted
; }
92 // The main SecurityAgent/authorizationhost interaction base class
94 class SecurityAgentQuery
: public SecurityAgentConnection
97 typedef SecurityAgent::Reason Reason
;
99 SecurityAgentQuery(const AuthHostType type
= securityAgent
, Session
&session
= Server::session());
102 void inferHints(Process
&thisProcess
);
103 void addHint(const char *name
, const void *value
= NULL
, UInt32 valueLen
= 0, UInt32 flags
= 0);
105 virtual ~SecurityAgentQuery();
107 virtual void disconnect();
108 virtual void terminate();
109 void create(const char *pluginId
, const char *mechanismId
, const SessionId inSessionId
);
117 AuthItemSet mClientHints
;
121 // Specialized for "rogue app" alert queries
123 class QueryKeychainUse
: public SecurityAgentQuery
{
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 SecurityAgentQuery
{
138 bool operator () (const char *aclPath
);
143 // A query for an existing passphrase
145 class QueryOld
: public SecurityAgentQuery
{
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
) { }
165 Reason
accept(CssmManagedData
&passphrase
);
170 // Repurpose QueryUnlock for PIN prompting
171 // Not very clean - but this stuff is an outdated hack as it is...
173 class QueryPIN
: public QueryOld
{
175 QueryPIN(Database
&db
);
177 const CssmData
&pin() const { return mPin
; }
180 Reason
accept(CssmManagedData
&pin
);
183 CssmAutoData mPin
; // PIN obtained
188 // A query for a new passphrase
190 class QueryNewPassphrase
: public SecurityAgentQuery
{
191 static const int maxTries
= kMaximumAuthorizationTries
;
193 QueryNewPassphrase(Database
&db
, Reason reason
) :
194 database(db
), initialReason(reason
),
195 mPassphrase(Allocator::standard(Allocator::sensitive
)),
196 mPassphraseValid(false) { }
200 Reason
operator () (CssmOwnedData
&passphrase
);
204 virtual Reason
accept(CssmManagedData
&passphrase
, CssmData
*oldPassphrase
);
207 Reason initialReason
;
208 CssmAutoData mPassphrase
;
209 bool mPassphraseValid
;
214 // Generic passphrase query (not associated with a database)
216 class QueryGenericPassphrase
: public SecurityAgentQuery
{
218 QueryGenericPassphrase() { }
219 Reason
operator () (const CssmData
*prompt
, bool verify
,
223 Reason
query(const CssmData
*prompt
, bool verify
, string
&passphrase
);
228 // Generic secret query (not associated with a database)
230 class QueryDBBlobSecret
: public SecurityAgentQuery
{
231 static const int maxTries
= kMaximumAuthorizationTries
;
233 QueryDBBlobSecret() { }
234 Reason
operator () (DbHandle
*dbHandleArray
, uint8 dbHandleArrayCount
, DbHandle
*dbHandleAuthenticated
);
237 Reason
query(DbHandle
*dbHandleArray
, uint8 dbHandleArrayCount
, DbHandle
*dbHandleAuthenticated
);
238 Reason
accept(CssmManagedData
&passphrase
, DbHandle
*dbHandlesToAuthenticate
, uint8 dbHandleCount
, DbHandle
*dbHandleAuthenticated
);
241 class QueryInvokeMechanism
: public SecurityAgentQuery
, public RefCount
{
243 QueryInvokeMechanism(const AuthHostType type
, Session
&session
);
244 void initialize(const string
&inPluginId
, const string
&inMechanismId
, const AuthValueVector
&arguments
, const SessionId inSessionId
= 0);
245 void run(const AuthValueVector
&inArguments
, AuthItemSet
&inHints
, AuthItemSet
&inContext
, AuthorizationResult
*outResult
);
247 bool operator () (const string
&inPluginId
, const string
&inMechanismId
, const Authorization::AuthValueVector
&inArguments
, AuthItemSet
&inHints
, AuthItemSet
&inContext
, AuthorizationResult
*outResult
);
248 void terminateAgent();
249 //~QueryInvokeMechanism();
251 AuthValueVector mArguments
;
254 // hybrid of confirm-access and generic authentication queries, for
255 // securityd's use; keep the Frankenstein references to yourself
256 // (the alternative is to ask the user to unlock the system keychain,
257 // and you don't want that, do you?)
258 class QueryKeychainAuth
: public SecurityAgentQuery
{
259 static const int maxTries
= kMaximumAuthorizationTries
;
261 QueryKeychainAuth() { }
262 // "prompt" can be NULL
263 Reason
operator () (const char *database
, const char *description
, AclAuthorization action
, const char *prompt
);
264 Reason
accept(string
&username
, string
&passphrase
);
267 #endif //_H_AGENTQUERY