]> git.saurik.com Git - apple/securityd.git/blob - libsecurity_agent/lib/agentclient.h
securityd-55137.6.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
69 worldChanged = 101
70 };
71
72 typedef enum {
73 tool = 'TOOL',
74 bundle = 'BNDL',
75 unknown = 'UNKN'
76 } RequestorType;
77
78 #if defined(__cplusplus)
79
80 using MachPlusPlus::Port;
81 using MachPlusPlus::PortSet;
82 using MachPlusPlus::Bootstrap;
83 using MachPlusPlus::ReceivePort;
84 using MachPlusPlus::Message;
85 using Authorization::AuthItemSet;
86 using Authorization::AuthValueVector;
87
88 class Clients;
89
90 class Client
91 {
92 friend class Clients;
93
94 enum MessageType { requestInterruptMessage, didDeactivateMessage, reportErrorMessage };
95
96 public:
97 Client();
98 virtual ~Client();
99
100 static AuthItemSet clientHints(SecurityAgent::RequestorType type, std::string &path, pid_t clientPid, uid_t clientUid);
101
102 static OSStatus startTransaction(Port serverPort);
103 static OSStatus endTransaction(Port serverPort);
104
105 protected:
106 void establishServer();
107
108 public:
109 void activate(Port serverPort);
110
111 OSStatus contact(mach_port_t jobId, Bootstrap processBootstrap, mach_port_t userPrefs);
112 OSStatus create(const char *pluginId, const char *mechanismId, const SessionId inSessionId);
113 void setArguments(const Authorization::AuthValueVector& inArguments) { mArguments = inArguments; }
114 void setInput(const Authorization::AuthItemSet& inHints, const Authorization::AuthItemSet& inContext) { mInHints = inHints; mInContext = inContext; }
115 OSStatus invoke();
116 OSStatus deactivate();
117 OSStatus destroy();
118 OSStatus terminate();
119 void receive();
120
121 void didCreate(const mach_port_t inStagePort);
122 void setResult(const AuthorizationResult inResult, const AuthorizationItemSet *inHints, const AuthorizationItemSet *inContext);
123 void requestInterrupt(); // setMessageType(requestInterrupt);
124 void didDeactivate(); // setMessageType(didDeactivate);
125
126 void setError(const OSStatus inMechanismError); // setMessageType(reportError); setError(mechanismError);
127 OSStatus getError();
128 AuthorizationResult result() { return mResult; }
129
130 typedef enum _PluginState {
131 init,
132 created,
133 current,
134 deactivating,
135 active,
136 interrupting,
137 dead
138 } PluginState;
139 PluginState state() { return mState; }
140
141 protected:
142 void setMessageType(const MessageType inMessageType);
143 // allow didCreate to set stagePort
144 void setStagePort(const mach_port_t inStagePort);
145 // allow server routines to use request port to find instance
146
147 // @@@ implement lessThan operator for set in terms of instance
148
149 protected:
150 void setup();
151 void teardown() throw();
152
153 Port mServerPort;
154 Port mStagePort;
155 Port mClientPort;
156
157 MessageType mMessageType;
158
159 OSStatus mErrorState;
160
161 AuthorizationResult mResult;
162 AuthValueVector mArguments;
163 AuthItemSet mInHints;
164 AuthItemSet mInContext;
165 AuthItemSet mOutHints;
166 AuthItemSet mOutContext;
167
168 PluginState mState;
169 void setState(PluginState mState);
170
171 bool mTerminateOnSleep;
172
173 public:
174 mach_port_t instance() const { return mClientPort; }
175 // bool operator == (const Client &other) const { return this->instance() == other.instance(); }
176 bool operator < (const Client &other) const { return this->instance() < other.instance(); }
177
178 AuthItemSet &inHints() { return mInHints; }
179 AuthItemSet &inContext() { return mInContext; }
180 AuthItemSet &outHints() { return mOutHints; }
181 AuthItemSet &outContext() { return mOutContext; }
182
183 void setTerminateOnSleep(bool terminateOnSleep) {mTerminateOnSleep = terminateOnSleep;}
184 bool getTerminateOnSleep() {return mTerminateOnSleep;}
185
186 public:
187 void check(mach_msg_return_t returnCode);
188 void checkResult();
189 };
190
191 class Clients
192 {
193 friend class Client;
194
195 protected:
196 set<Client*> mClients;
197 PortSet mClientPortSet;
198 public:
199 Clients() {}
200 void create(); // create an agentclient
201 void insert(Client *agent) { StLock<Mutex> _(mLock); mClients.insert(agent); mClientPortSet += agent->instance(); }
202 void remove(Client *agent) { StLock<Mutex> _(mLock); mClientPortSet -= agent->instance(); mClients.erase(agent); }
203 Client &find(const mach_port_t instance) const;
204 bool receive();
205 bool compare(const Client * client, mach_port_t instance);
206
207 mutable Mutex mLock;
208 static ThreadNexus<Clients> gClients;
209 static ModuleNexus<RecursiveMutex> gAllClientsMutex;
210 static ModuleNexus<set<Client*> > allClients;
211 static void killAllClients();
212 };
213
214 } // end namespace Authorization
215
216 #endif /* __cplusplus__ */
217
218 #endif /* _H_AGENTCLIENT */
219