]> git.saurik.com Git - apple/security.git/blob - SecurityServer/SecurityAgentClient.h
Security-164.1.tar.gz
[apple/security.git] / SecurityServer / SecurityAgentClient.h
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // SecurityAgentClient - client interface to SecurityAgent
21 //
22 #ifndef _H_SECURITYAGENTCLIENT
23 #define _H_SECURITYAGENTCLIENT
24
25 #if defined(__cplusplus)
26 #include <string>
27 #include <Security/mach++.h>
28 #include <Security/osxsigning.h>
29 #include <Security/cssmacl.h>
30 #include <Security/cssm.h>
31 #include <Security/Authorization.h>
32 #include <Security/AuthorizationPlugin.h>
33 #include <Security/AuthorizationWalkers.h>
34 #include <Security/AuthorizationData.h>
35
36 using Authorization::AuthItemSet;
37 using Authorization::AuthValueVector;
38
39 namespace Security {
40
41 using MachPlusPlus::Port;
42 using MachPlusPlus::Bootstrap;
43 using CodeSigning::OSXCode;
44
45
46 namespace SecurityAgent {
47
48 #endif //C++ only
49
50 // Note: Following section also available to C code for inclusion
51
52 static const unsigned int maxPassphraseLength = 1024;
53 static const unsigned int maxUsernameLength = 80;
54
55 #define kMaximumAuthorizationTries 3
56
57 //
58 // Unified reason codes transmitted to SecurityAgent (and internationalized there)
59 //
60 enum Reason {
61 noReason = 0, // no reason (not used, used as a NULL)
62 unknownReason, // something else (catch-all internal error)
63
64 // reasons for asking for a new passphrase
65 newDatabase = 11, // need passphrase for a new database
66 changePassphrase, // changing passphrase for existing database
67
68 // reasons for retrying an unlock query
69 invalidPassphrase = 21, // passphrase was wrong
70
71 // reasons for retrying a new passphrase query
72 passphraseIsNull = 31, // empty passphrase
73 passphraseTooSimple, // passphrase is not complex enough
74 passphraseRepeated, // passphrase was used before (must use new one)
75 passphraseUnacceptable, // passphrase unacceptable for some other reason
76 oldPassphraseWrong, // the old passphrase given is wrong
77
78 // reasons for retrying an authorization query
79 userNotInGroup = 41, // authenticated user not in needed group
80 unacceptableUser, // authenticated user unacceptable for some other reason
81
82 // reasons for canceling a staged query
83 tooManyTries = 61, // too many failed attempts to get it right
84 noLongerNeeded, // the queried item is no longer needed
85 keychainAddFailed, // the requested itemed couldn't be added to the keychain
86 generalErrorCancel // something went wrong so we have to give up now
87 };
88
89 #define AGENT_HINT_SUGGESTED_USER "suggestedUser"
90 #define AGENT_HINT_REQUIRE_USER_IN_GROUP "requireUserInGroup"
91 #define AGENT_HINT_CUSTOM_PROMPT "prompt"
92 #define AGENT_HINT_AUTHORIZE_RIGHT "authorizeRight"
93 #define AGENT_HINT_CLIENT_PID "clientPid"
94 #define AGENT_HINT_CLIENT_UID "clientUid"
95 #define AGENT_HINT_CREATOR_PID "creatorPid"
96 #define AGENT_HINT_CLIENT_TYPE "clientType"
97 #define AGENT_HINT_CLIENT_PATH "clientPath"
98 #define AGENT_HINT_TRIES "tries"
99 #define AGENT_HINT_RETRY_REASON "reason"
100 #define AGENT_HINT_AUTHORIZE_RULE "authorizeRule"
101 //
102 // "Login Keychain Creation" Right: Hint and context keys
103 //
104 #define AGENT_HINT_ATTR_NAME "loginKCCreate:attributeName"
105 #define AGENT_HINT_LOGIN_KC_NAME "loginKCCreate:pathName"
106 #define AGENT_HINT_LOGIN_KC_EXISTS_IN_KC_FOLDER "loginKCCreate:exists"
107 #define AGENT_HINT_LOGIN_KC_USER_NAME "loginKCCreate:userName"
108 #define AGENT_HINT_LOGIN_KC_CUST_STR1 "loginKCCreate:customStr1"
109 #define AGENT_HINT_LOGIN_KC_CUST_STR2 "loginKCCreate:customStr2"
110 #define AGENT_HINT_LOGIN_KC_USER_HAS_OTHER_KCS_STR "loginKCCreate:moreThanOneKeychainExists"
111
112 #define LOGIN_KC_CREATION_RIGHT "system.keychain.create.loginkc"
113
114 #if defined(__cplusplus)
115
116
117 //
118 // The client interface to the SecurityAgent.
119 //
120 class Client {
121 public:
122 Client();
123 Client(uid_t clientUID, Bootstrap clientBootstrap, const char *agentName);
124 virtual ~Client();
125
126 virtual void activate();
127 virtual void terminate();
128 bool isActive() const { return mActive; }
129
130 bool keepAlive() const { return mKeepAlive; }
131 void keepAlive(bool ka) { mKeepAlive = ka; }
132
133 // common stage termination calls
134 void finishStagedQuery();
135 void cancelStagedQuery(Reason reason);
136
137 public:
138 struct KeychainBox {
139 bool show; // show the "save in keychain" checkbox (in)
140 bool setting; // value of the checkbox (in/out)
141 };
142
143 public:
144 // ask to unlock an existing database. Staged protocol
145 void queryUnlockDatabase(const OSXCode *requestor, pid_t requestPid,
146 const char *database, char passphrase[maxPassphraseLength]);
147 void retryUnlockDatabase(Reason reason, char passphrase[maxPassphraseLength]);
148
149 // ask for a new passphrase for a database. Not yet staged
150 void queryNewPassphrase(const OSXCode *requestor, pid_t requestPid,
151 const char *database, Reason reason, char passphrase[maxPassphraseLength], char oldPassphrase[maxPassphraseLength]);
152 void retryNewPassphrase(Reason reason, char passphrase[maxPassphraseLength], char oldPassphrase[maxPassphraseLength]);
153
154 // ask permission to use an item in a database
155 struct KeychainChoice {
156 bool allowAccess; // user said "yes"
157 bool continueGrantingToCaller; // user wants calling App added to ACL
158 char passphrase[maxPassphraseLength]; // only if requested
159 };
160 void queryKeychainAccess(const OSXCode *requestor, pid_t requestPid,
161 const char *database, const char *itemName, AclAuthorization action,
162 bool needPassphrase, KeychainChoice &choice);
163 void retryQueryKeychainAccess (Reason reason, KeychainChoice &choice);
164
165 // one-shot code-identity confirmation query
166 void queryCodeIdentity(const OSXCode *requestor, pid_t requestPid,
167 const char *aclPath, KeychainChoice &choice);
168
169 // generic old passphrase query
170 void queryOldGenericPassphrase(const OSXCode *requestor, pid_t requestPid,
171 const char *prompt,
172 KeychainBox &addToKeychain, char passphrase[maxPassphraseLength]);
173 void retryOldGenericPassphrase(Reason reason,
174 bool &addToKeychain, char passphrase[maxPassphraseLength]);
175
176 // generic new passphrase query
177 void queryNewGenericPassphrase(const OSXCode *requestor, pid_t requestPid,
178 const char *prompt, Reason reason,
179 KeychainBox &addToKeychain, char passphrase[maxPassphraseLength]);
180 void retryNewGenericPassphrase(Reason reason,
181 bool &addToKeychain, char passphrase[maxPassphraseLength]);
182
183 // authenticate a user for the purpose of authorization
184 bool authorizationAuthenticate(const OSXCode *requestor, pid_t requestPid,
185 const char *neededGroup, const char *candidateUser,
186 char username[maxUsernameLength], char passphrase[maxPassphraseLength]);
187 bool retryAuthorizationAuthenticate(Reason reason,
188 char username[maxUsernameLength], char passphrase[maxPassphraseLength]);
189
190 bool invokeMechanism(const string &inPluginId, const string &inMechanismId, const AuthValueVector &inArguments, AuthItemSet &inHints, AuthItemSet &inContext, AuthorizationResult *outResult);
191
192 void terminateAgent();
193
194 // Cancel a pending client call in another thread by sending a cancel message.
195 // This call (only) may be made from another thread.
196 void cancel();
197
198 private:
199 // used by client call wrappers to receive IPC return-status
200 OSStatus status;
201
202 private:
203 Port mServerPort;
204 Port mClientPort;
205 bool mActive;
206 uid_t desktopUid;
207 Bootstrap mClientBootstrap;
208 bool mKeepAlive;
209
210 enum Stage {
211 mainStage, // in between requests
212 unlockStage, // in unlock sub-protocol
213 newPassphraseStage, // in get-new-passphrase sub-protocol
214 newGenericPassphraseStage, // in get-new-generic-passphrase sub-protocol
215 oldGenericPassphraseStage, // in get-old-generic-passphrase sub-protocol
216 authorizeStage, // in authorize-by-group-membership sub-protocol
217 queryKeychainAccessStage,
218 invokeMechanismStage // in invoke mechanism sub-protocol
219 } stage;
220 Port mStagePort;
221 string mAgentName;
222
223 void locateDesktop();
224 void establishServer();
225 void check(kern_return_t error);
226 void unstage();
227
228 private:
229 static const int cancelMessagePseudoID = 1200;
230 };
231
232 }; // end namespace SecurityAgent
233
234 } // end namespace Security
235
236 #endif //C++ only
237
238 #endif //_H_SECURITYAGENTCLIENT