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 SecurityAgentConnectionInterface
51 SecurityAgentConnection(const AuthHostType type
= securityAgent
, Session
&session
= Server::session());
52 virtual ~SecurityAgentConnection();
53 virtual void activate();
54 virtual void reconnect();
55 virtual void disconnect() { };
56 virtual void terminate();
58 AuthHostType
hostType() { return mAuthHostType
; }
61 AuthHostType mAuthHostType
;
62 RefPointer
<AuthHostInstance
> mHostInstance
;
64 const RefPointer
<Connection
> mConnection
;
65 audit_token_t
*mAuditToken
;
69 // Special wrapper around SecurityAgent::Client transaction interfaces.
70 // Not currently used because this was intended to support
71 // SecurityAgent's/authorizationhost's use of Foundation's enable/disable-sudden-
72 // termination APIs, but the latter don't work for non-direct children of
73 // launchd. Kept around because securityd might need its own child-transaction
76 class SecurityAgentTransaction
: public SecurityAgentConnection
79 SecurityAgentTransaction(const AuthHostType type
= securityAgent
, Session
&session
= Server::session(), bool startNow
= true);
80 ~SecurityAgentTransaction();
84 bool started() { return mStarted
; }
91 // The main SecurityAgent/authorizationhost interaction base class
93 class SecurityAgentQuery
: public SecurityAgent::Client
,
94 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 activate();
108 virtual void reconnect();
109 virtual void disconnect();
110 virtual void terminate();
111 void create(const char *pluginId
, const char *mechanismId
, const SessionId inSessionId
);
119 AuthItemSet mClientHints
;
123 // Specialized for "rogue app" alert queries
125 class QueryKeychainUse
: public SecurityAgentQuery
{
127 QueryKeychainUse(bool needPass
, const Database
*db
);
128 Reason
queryUser (const char* database
, const char *description
, AclAuthorization action
);
131 const KeychainDatabase
*mPassphraseCheck
; // NULL to not check passphrase
136 // Specialized for code signature adjustment queries
138 class QueryCodeCheck
: public SecurityAgentQuery
{
140 bool operator () (const char *aclPath
);
145 // A query for an existing passphrase
147 class QueryOld
: public SecurityAgentQuery
{
148 static const int maxTries
= kMaximumAuthorizationTries
;
150 QueryOld(Database
&db
) : database(db
) { }
154 Reason
operator () ();
158 virtual Reason
accept(CssmManagedData
&) = 0;
162 class QueryUnlock
: public QueryOld
{
164 QueryUnlock(KeychainDatabase
&db
) : QueryOld(db
) { }
167 Reason
accept(CssmManagedData
&passphrase
);
172 // Repurpose QueryUnlock for PIN prompting
173 // Not very clean - but this stuff is an outdated hack as it is...
175 class QueryPIN
: public QueryOld
{
177 QueryPIN(Database
&db
);
179 const CssmData
&pin() const { return mPin
; }
182 Reason
accept(CssmManagedData
&pin
);
185 CssmAutoData mPin
; // PIN obtained
190 // A query for a new passphrase
192 class QueryNewPassphrase
: public SecurityAgentQuery
{
193 static const int maxTries
= 7;
195 QueryNewPassphrase(Database
&db
, Reason reason
) :
196 database(db
), initialReason(reason
),
197 mPassphrase(Allocator::standard(Allocator::sensitive
)),
198 mPassphraseValid(false) { }
202 Reason
operator () (CssmOwnedData
&passphrase
);
206 virtual Reason
accept(CssmManagedData
&passphrase
, CssmData
*oldPassphrase
);
209 Reason initialReason
;
210 CssmAutoData mPassphrase
;
211 bool mPassphraseValid
;
216 // Generic passphrase query (not associated with a database)
218 class QueryGenericPassphrase
: public SecurityAgentQuery
{
220 QueryGenericPassphrase() { }
221 Reason
operator () (const char *prompt
, bool verify
,
225 Reason
query(const char *prompt
, bool verify
, string
&passphrase
);
230 // Generic secret query (not associated with a database)
232 class QueryDBBlobSecret
: public SecurityAgentQuery
{
233 static const int maxTries
= kMaximumAuthorizationTries
;
235 QueryDBBlobSecret() { }
236 Reason
operator () (DbHandle
*dbHandleArray
, uint8 dbHandleArrayCount
, DbHandle
*dbHandleAuthenticated
);
239 Reason
query(DbHandle
*dbHandleArray
, uint8 dbHandleArrayCount
, DbHandle
*dbHandleAuthenticated
);
240 Reason
accept(CssmManagedData
&passphrase
, DbHandle
*dbHandlesToAuthenticate
, uint8 dbHandleCount
, DbHandle
*dbHandleAuthenticated
);
243 class QueryInvokeMechanism
: public SecurityAgentQuery
, public RefCount
{
245 QueryInvokeMechanism(const AuthHostType type
, Session
&session
);
246 void initialize(const string
&inPluginId
, const string
&inMechanismId
, const AuthValueVector
&arguments
, const SessionId inSessionId
= 0);
247 void run(const AuthValueVector
&inArguments
, AuthItemSet
&inHints
, AuthItemSet
&inContext
, AuthorizationResult
*outResult
);
249 bool operator () (const string
&inPluginId
, const string
&inMechanismId
, const Authorization::AuthValueVector
&inArguments
, AuthItemSet
&inHints
, AuthItemSet
&inContext
, AuthorizationResult
*outResult
);
250 void terminateAgent();
251 //~QueryInvokeMechanism();
253 AuthValueVector mArguments
;
256 // hybrid of confirm-access and generic authentication queries, for
257 // securityd's use; keep the Frankenstein references to yourself
258 // (the alternative is to ask the user to unlock the system keychain,
259 // and you don't want that, do you?)
260 class QueryKeychainAuth
: public SecurityAgentQuery
{
261 static const int maxTries
= kMaximumAuthorizationTries
;
263 QueryKeychainAuth() { }
264 // "prompt" can be NULL
265 Reason
operator () (const char *database
, const char *description
, AclAuthorization action
, const char *prompt
);
266 Reason
accept(string
&username
, string
&passphrase
);
269 #endif //_H_AGENTQUERY