]>
Commit | Line | Data |
---|---|---|
d8f41ccd A |
1 | /* |
2 | * Copyright (c) 2000-2005,2007-2010,2012-2013 Apple Inc. All Rights Reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
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 | |
11 | * file. | |
12 | * | |
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. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | ||
25 | // | |
26 | // passphrases - canonical code to obtain passphrases | |
27 | // | |
28 | #ifndef _H_AGENTQUERY | |
29 | #define _H_AGENTQUERY | |
30 | ||
d8f41ccd A |
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" | |
d8f41ccd A |
35 | #include "authhost.h" |
36 | #include "server.h" | |
37 | #include "session.h" | |
38 | #include <xpc/xpc.h> | |
39 | ||
40 | using Authorization::AuthItemSet; | |
41 | using Authorization::AuthValueVector; | |
42 | using Security::OSXCode; | |
43 | ||
6b200bc3 | 44 | #define kMaximumAuthorizationTries (10000) |
d8f41ccd A |
45 | |
46 | // | |
47 | // base for classes talking to com.apple.security.agent and com.apple.security.authhost | |
48 | // | |
fa7225c8 | 49 | class SecurityAgentXPCConnection |
d8f41ccd A |
50 | { |
51 | public: | |
fa7225c8 | 52 | SecurityAgentXPCConnection(Session &session = Server::session()); |
d8f41ccd A |
53 | virtual ~SecurityAgentXPCConnection(); |
54 | virtual void activate(bool ignoreUid); | |
d8f41ccd A |
55 | virtual void disconnect() { }; |
56 | virtual void terminate(); | |
fa7225c8 | 57 | |
d8f41ccd | 58 | protected: |
d8f41ccd A |
59 | RefPointer<AuthHostInstance> mHostInstance; |
60 | Session &mSession; | |
61 | xpc_connection_t mXPCConnection; | |
d8f41ccd A |
62 | const RefPointer<Connection> mConnection; |
63 | audit_token_t *mAuditToken; | |
64 | uid_t mNobodyUID; | |
65 | ||
66 | bool inDarkWake(); | |
67 | ||
68 | }; | |
69 | ||
d8f41ccd A |
70 | |
71 | // | |
fa7225c8 | 72 | // The main com.apple.security.agent interaction base class |
d8f41ccd A |
73 | // |
74 | class SecurityAgentXPCQuery : public SecurityAgentXPCConnection | |
75 | { | |
76 | public: | |
77 | static void killAllXPCClients(); | |
78 | ||
79 | typedef SecurityAgent::Reason Reason; | |
80 | ||
fa7225c8 | 81 | SecurityAgentXPCQuery(Session &session = Server::session()); |
d8f41ccd A |
82 | |
83 | ||
84 | void inferHints(Process &thisProcess); | |
85 | void addHint(const char *name, const void *value = NULL, UInt32 valueLen = 0, UInt32 flags = 0); | |
86 | ||
87 | virtual ~SecurityAgentXPCQuery(); | |
88 | ||
89 | virtual void disconnect(); | |
90 | virtual void terminate(); | |
5c19dc3a | 91 | void create(const char *pluginId, const char *mechanismId); |
866f8763 | 92 | void invoke(); |
d8f41ccd A |
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; } | |
96 | void checkResult(); | |
97 | ||
98 | void readChoice(); | |
99 | ||
100 | bool allow; | |
101 | bool remember; | |
102 | ||
103 | protected: | |
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; | |
113 | }; | |
114 | ||
115 | // | |
116 | // Specialized for "rogue app" alert queries | |
117 | // | |
118 | class QueryKeychainUse : public SecurityAgentXPCQuery { | |
119 | public: | |
120 | QueryKeychainUse(bool needPass, const Database *db); | |
121 | Reason queryUser (const char* database, const char *description, AclAuthorization action); | |
122 | ||
123 | private: | |
124 | const KeychainDatabase *mPassphraseCheck; // NULL to not check passphrase | |
125 | }; | |
126 | ||
127 | ||
d8f41ccd A |
128 | // |
129 | // A query for an existing passphrase | |
130 | // | |
131 | class QueryOld : public SecurityAgentXPCQuery { | |
132 | static const int maxTries = kMaximumAuthorizationTries; | |
133 | public: | |
134 | QueryOld(Database &db) : database(db) {setTerminateOnSleep(true);} | |
135 | ||
136 | Database &database; | |
137 | ||
138 | Reason operator () (); | |
139 | ||
140 | protected: | |
141 | Reason query(); | |
142 | virtual Reason accept(CssmManagedData &) = 0; | |
143 | }; | |
144 | ||
145 | ||
146 | class QueryUnlock : public QueryOld { | |
147 | public: | |
148 | QueryUnlock(KeychainDatabase &db) : QueryOld(db) { } | |
149 | Reason retrievePassword(CssmOwnedData &passphrase); | |
150 | ||
151 | protected: | |
152 | Reason accept(CssmManagedData &passphrase); | |
153 | }; | |
154 | ||
155 | ||
156 | class QueryKeybagPassphrase : public SecurityAgentXPCQuery { | |
157 | public: | |
158 | QueryKeybagPassphrase(Session &session, int32_t retries = kMaximumAuthorizationTries); | |
159 | ||
160 | Reason query(); | |
161 | Reason accept(CssmManagedData &passphrase); | |
162 | protected: | |
163 | Session &mSession; | |
164 | service_context_t mContext; | |
165 | int32_t mRetries; | |
166 | }; | |
167 | ||
168 | class QueryKeybagNewPassphrase : public QueryKeybagPassphrase { | |
169 | public: | |
170 | QueryKeybagNewPassphrase(Session &session); | |
171 | ||
172 | Reason query(CssmOwnedData &oldPassphrase, CssmOwnedData &passphrase); | |
173 | }; | |
174 | ||
175 | // | |
176 | // Repurpose QueryUnlock for PIN prompting | |
177 | // Not very clean - but this stuff is an outdated hack as it is... | |
178 | // | |
179 | class QueryPIN : public QueryOld { | |
180 | public: | |
181 | QueryPIN(Database &db); | |
182 | ||
183 | const CssmData &pin() const { return mPin; } | |
184 | ||
185 | protected: | |
186 | Reason accept(CssmManagedData &pin); | |
187 | ||
188 | private: | |
189 | CssmAutoData mPin; // PIN obtained | |
190 | }; | |
191 | ||
192 | ||
193 | // | |
194 | // A query for a new passphrase | |
195 | // | |
196 | class QueryNewPassphrase : public SecurityAgentXPCQuery { | |
197 | static const int maxTries = kMaximumAuthorizationTries; | |
198 | public: | |
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) { } | |
204 | ||
205 | Database &database; | |
206 | ||
207 | Reason operator () (CssmOwnedData &oldPassphrase, CssmOwnedData &passphrase); | |
208 | ||
209 | protected: | |
210 | Reason query(); | |
211 | virtual Reason accept(CssmManagedData &passphrase, CssmData *oldPassphrase); | |
212 | ||
213 | private: | |
214 | Reason initialReason; | |
215 | CssmAutoData mPassphrase; | |
216 | CssmAutoData mOldPassphrase; | |
217 | bool mPassphraseValid; | |
218 | }; | |
219 | ||
220 | ||
221 | // | |
222 | // Generic passphrase query (not associated with a database) | |
223 | // | |
224 | class QueryGenericPassphrase : public SecurityAgentXPCQuery { | |
225 | public: | |
226 | QueryGenericPassphrase() { } | |
227 | Reason operator () (const CssmData *prompt, bool verify, | |
228 | string &passphrase); | |
229 | ||
230 | protected: | |
231 | Reason query(const CssmData *prompt, bool verify, string &passphrase); | |
232 | }; | |
233 | ||
234 | ||
235 | // | |
236 | // Generic secret query (not associated with a database) | |
237 | // | |
238 | class QueryDBBlobSecret : public SecurityAgentXPCQuery { | |
239 | static const int maxTries = kMaximumAuthorizationTries; | |
240 | public: | |
241 | QueryDBBlobSecret() { } | |
242 | Reason operator () (DbHandle *dbHandleArray, uint8 dbHandleArrayCount, DbHandle *dbHandleAuthenticated); | |
243 | ||
244 | protected: | |
245 | Reason query(DbHandle *dbHandleArray, uint8 dbHandleArrayCount, DbHandle *dbHandleAuthenticated); | |
246 | Reason accept(CssmManagedData &passphrase, DbHandle *dbHandlesToAuthenticate, uint8 dbHandleCount, DbHandle *dbHandleAuthenticated); | |
247 | }; | |
248 | ||
d8f41ccd A |
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; | |
255 | public: | |
256 | QueryKeychainAuth() { } | |
257 | // "prompt" can be NULL | |
b54c578e | 258 | Reason performQuery(const KeychainDatabase&, const char *description, AclAuthorization action, const char *prompt); |
d8f41ccd A |
259 | Reason accept(string &username, string &passphrase); |
260 | }; | |
261 | ||
262 | #endif //_H_AGENTQUERY |