]> git.saurik.com Git - apple/securityd.git/blob - libsecurity_agent/lib/agentclient.h
securityd-55199.3.tar.gz
[apple/securityd.git] / libsecurity_agent / lib / agentclient.h
1 /*
2 * agentclient.h
3 * SecurityAgent
4 *
5 * Copyright (c) 2002,2008 Apple Inc.. All rights reserved.
6 *
7 */
8
9 #ifndef _H_AGENTCLIENT
10 #define _H_AGENTCLIENT
11
12 #include <Security/Authorization.h>
13 #include <Security/AuthorizationPlugin.h>
14 #include <Security/AuthorizationTags.h>
15 #include <Security/AuthorizationTagsPriv.h>
16
17 #include <security_agent_client/sa_types.h>
18
19 #if defined(__cplusplus)
20
21 #include <string>
22 #include <security_utilities/mach++.h>
23 #include <security_cdsa_utilities/AuthorizationData.h>
24
25 namespace SecurityAgent {
26 #endif /* __cplusplus__ */
27
28 // Manimum number of failed authentications before
29 // SecurityAgent dialog is killed.
30 #define kMaximumAuthorizationTries 10000
31
32 // Number of failed authentications before a password
33 // hint is displayed.
34 #define kAuthorizationTriesBeforeHint 3
35
36 #define maxPassphraseLength 1024
37
38 //
39 // Unified reason codes transmitted to SecurityAgent (and internationalized there)
40 //
41 enum Reason {
42 noReason = 0, // no reason (not used, used as a NULL)
43 unknownReason, // something else (catch-all internal error)
44
45 // reasons for asking for a new passphrase
46 newDatabase = 11, // need passphrase for a new database
47 changePassphrase, // changing passphrase for existing database
48
49 // reasons for retrying an unlock query
50 invalidPassphrase = 21, // passphrase was wrong
51
52 // reasons for retrying a new passphrase query
53 passphraseIsNull = 31, // empty passphrase
54 passphraseTooSimple, // passphrase is not complex enough
55 passphraseRepeated, // passphrase was used before (must use new one)
56 passphraseUnacceptable, // passphrase unacceptable for some other reason
57 oldPassphraseWrong, // the old passphrase given is wrong
58
59 // reasons for retrying an authorization query
60 userNotInGroup = 41, // authenticated user not in needed group
61 unacceptableUser, // authenticated user unacceptable for some other reason
62
63 // reasons for canceling a staged query
64 tooManyTries = 61, // too many failed attempts to get it right
65 noLongerNeeded, // the queried item is no longer needed
66 keychainAddFailed, // the requested itemed couldn't be added to the keychain
67 generalErrorCancel, // something went wrong so we have to give up now
68 resettingPassword, // The user has indicated that they wish to reset their password
69
70 worldChanged = 101
71 };
72
73 typedef enum {
74 tool = 'TOOL',
75 bundle = 'BNDL',
76 unknown = 'UNKN'
77 } RequestorType;
78
79 #if defined(__cplusplus)
80
81 using MachPlusPlus::Port;
82 using MachPlusPlus::PortSet;
83 using MachPlusPlus::Bootstrap;
84 using MachPlusPlus::ReceivePort;
85 using MachPlusPlus::Message;
86 using Authorization::AuthItemSet;
87 using Authorization::AuthValueVector;
88
89 class Clients;
90
91 class Client
92 {
93 friend class Clients;
94
95 enum MessageType { requestInterruptMessage, didDeactivateMessage, reportErrorMessage };
96
97 public:
98 Client();
99 virtual ~Client();
100
101 static AuthItemSet clientHints(SecurityAgent::RequestorType type, std::string &path, pid_t clientPid, uid_t clientUid);
102
103 static OSStatus startTransaction(Port serverPort);
104 static OSStatus endTransaction(Port serverPort);
105
106 protected:
107 void establishServer();
108
109 public:
110 void activate(Port serverPort);
111
112 OSStatus contact(mach_port_t jobId, Bootstrap processBootstrap, mach_port_t userPrefs);
113 OSStatus create(const char *pluginId, const char *mechanismId, const SessionId inSessionId);
114 void setArguments(const Authorization::AuthValueVector& inArguments) { mArguments = inArguments; }
115 void setInput(const Authorization::AuthItemSet& inHints, const Authorization::AuthItemSet& inContext) { mInHints = inHints; mInContext = inContext; }
116 OSStatus invoke();
117 OSStatus deactivate();
118 OSStatus destroy();
119 OSStatus terminate();
120 void receive();
121
122 void didCreate(const mach_port_t inStagePort);
123 void setResult(const AuthorizationResult inResult, const AuthorizationItemSet *inHints, const AuthorizationItemSet *inContext);
124 void requestInterrupt(); // setMessageType(requestInterrupt);
125 void didDeactivate(); // setMessageType(didDeactivate);
126
127 void setError(const OSStatus inMechanismError); // setMessageType(reportError); setError(mechanismError);
128 OSStatus getError();
129 AuthorizationResult result() { return mResult; }
130
131 typedef enum _PluginState {
132 init,
133 created,
134 current,
135 deactivating,
136 active,
137 interrupting,
138 dead
139 } PluginState;
140 PluginState state() { return mState; }
141
142 protected:
143 void setMessageType(const MessageType inMessageType);
144 // allow didCreate to set stagePort
145 void setStagePort(const mach_port_t inStagePort);
146 // allow server routines to use request port to find instance
147
148 // @@@ implement lessThan operator for set in terms of instance
149
150 protected:
151 void setup();
152 void teardown() throw();
153
154 Port mServerPort;
155 Port mStagePort;
156 Port mClientPort;
157
158 MessageType mMessageType;
159
160 OSStatus mErrorState;
161
162 AuthorizationResult mResult;
163 AuthValueVector mArguments;
164 AuthItemSet mInHints;
165 AuthItemSet mInContext;
166 AuthItemSet mOutHints;
167 AuthItemSet mOutContext;
168
169 PluginState mState;
170 void setState(PluginState mState);
171
172 bool mTerminateOnSleep;
173
174 public:
175 mach_port_t instance() const { return mClientPort; }
176 // bool operator == (const Client &other) const { return this->instance() == other.instance(); }
177 bool operator < (const Client &other) const { return this->instance() < other.instance(); }
178
179 AuthItemSet &inHints() { return mInHints; }
180 AuthItemSet &inContext() { return mInContext; }
181 AuthItemSet &outHints() { return mOutHints; }
182 AuthItemSet &outContext() { return mOutContext; }
183
184 void setTerminateOnSleep(bool terminateOnSleep) {mTerminateOnSleep = terminateOnSleep;}
185 bool getTerminateOnSleep() {return mTerminateOnSleep;}
186
187 public:
188 void check(mach_msg_return_t returnCode);
189 void checkResult();
190 };
191
192 class Clients
193 {
194 friend class Client;
195
196 protected:
197 set<Client*> mClients;
198 PortSet mClientPortSet;
199 public:
200 Clients() {}
201 void create(); // create an agentclient
202 void insert(Client *agent) { StLock<Mutex> _(mLock); mClients.insert(agent); mClientPortSet += agent->instance(); }
203 void remove(Client *agent) { StLock<Mutex> _(mLock); mClientPortSet -= agent->instance(); mClients.erase(agent); }
204 Client &find(const mach_port_t instance) const;
205 bool receive();
206 bool compare(const Client * client, mach_port_t instance);
207
208 mutable Mutex mLock;
209 static ThreadNexus<Clients> gClients;
210 static ModuleNexus<RecursiveMutex> gAllClientsMutex;
211 static ModuleNexus<set<Client*> > allClients;
212 static void killAllClients();
213 };
214
215 } // end namespace Authorization
216
217 #endif /* __cplusplus__ */
218
219 #endif /* _H_AGENTCLIENT */
220