2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 // SecurityAgentClient - client interface to SecurityAgent
22 #ifndef _H_SECURITYAGENTCLIENT
23 #define _H_SECURITYAGENTCLIENT
25 #if defined(__cplusplus)
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>
36 using Authorization::AuthItemSet
;
37 using Authorization::AuthValueVector
;
41 using MachPlusPlus::Port
;
42 using MachPlusPlus::Bootstrap
;
43 using CodeSigning::OSXCode
;
46 namespace SecurityAgent
{
50 // Note: Following section also available to C code for inclusion
52 static const unsigned int maxPassphraseLength
= 1024;
53 static const unsigned int maxUsernameLength
= 80;
55 #define kMaximumAuthorizationTries 3
58 // Unified reason codes transmitted to SecurityAgent (and internationalized there)
61 noReason
= 0, // no reason (not used, used as a NULL)
62 unknownReason
, // something else (catch-all internal error)
64 // reasons for asking for a new passphrase
65 newDatabase
= 11, // need passphrase for a new database
66 changePassphrase
, // changing passphrase for existing database
68 // reasons for retrying an unlock query
69 invalidPassphrase
= 21, // passphrase was wrong
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
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
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
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"
102 // "Login Keychain Creation" Right: Hint and context keys
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"
112 #define LOGIN_KC_CREATION_RIGHT "system.keychain.create.loginkc"
114 #if defined(__cplusplus)
118 // The client interface to the SecurityAgent.
123 Client(uid_t clientUID
, Bootstrap clientBootstrap
, const char *agentName
);
126 virtual void activate();
127 virtual void terminate();
128 bool isActive() const { return mActive
; }
130 bool keepAlive() const { return mKeepAlive
; }
131 void keepAlive(bool ka
) { mKeepAlive
= ka
; }
133 // common stage termination calls
134 void finishStagedQuery();
135 void cancelStagedQuery(Reason reason
);
139 bool show
; // show the "save in keychain" checkbox (in)
140 bool setting
; // value of the checkbox (in/out)
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
]);
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
]);
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
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
);
165 // one-shot code-identity confirmation query
166 void queryCodeIdentity(const OSXCode
*requestor
, pid_t requestPid
,
167 const char *aclPath
, KeychainChoice
&choice
);
169 // generic old passphrase query
170 void queryOldGenericPassphrase(const OSXCode
*requestor
, pid_t requestPid
,
172 KeychainBox
&addToKeychain
, char passphrase
[maxPassphraseLength
]);
173 void retryOldGenericPassphrase(Reason reason
,
174 bool &addToKeychain
, char passphrase
[maxPassphraseLength
]);
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
]);
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
]);
190 bool invokeMechanism(const string
&inPluginId
, const string
&inMechanismId
, const AuthValueVector
&inArguments
, AuthItemSet
&inHints
, AuthItemSet
&inContext
, AuthorizationResult
*outResult
);
192 void terminateAgent();
194 // Cancel a pending client call in another thread by sending a cancel message.
195 // This call (only) may be made from another thread.
199 // used by client call wrappers to receive IPC return-status
207 Bootstrap mClientBootstrap
;
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
223 void locateDesktop();
224 void establishServer();
225 void check(kern_return_t error
);
229 static const int cancelMessagePseudoID
= 1200;
232 }; // end namespace SecurityAgent
234 } // end namespace Security
238 #endif //_H_SECURITYAGENTCLIENT