]> git.saurik.com Git - apple/security.git/blob - SecurityServer/Authorization/AuthorizationEngine.h
Security-29.tar.gz
[apple/security.git] / SecurityServer / Authorization / AuthorizationEngine.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 * AuthorizationEngine.h
21 * Authorization
22 *
23 * Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved
24 *
25 */
26
27 #if !defined(__AuthorizationEngine__)
28 #define __AuthorizationEngine__ 1
29
30 #include <Security/Authorization.h>
31 #include <Security/refcount.h>
32 #include <Security/osxsigning.h>
33 #include "agentquery.h"
34
35 #include <CoreFoundation/CFDate.h>
36 #include <CoreFoundation/CFDictionary.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39
40 #include <map>
41 #include <set>
42 #include <string>
43
44 class AuthorizationToken;
45
46 namespace Authorization
47 {
48
49 class Error : public CssmCommonError {
50 protected:
51 Error(int err);
52 public:
53 const int error;
54 virtual CSSM_RETURN cssmError() const;
55 virtual OSStatus osStatus() const;
56 virtual const char *what () const;
57 // @@@ Default value should be internal error.
58 static void throwMe(int err = -1) __attribute((noreturn));
59 };
60
61
62 /* Credentials are less than comparable so they can be put in sets or maps. */
63 class CredentialImpl : public RefCount
64 {
65 public:
66 CredentialImpl(const string &username, const uid_t uid, gid_t gid, bool shared);
67 CredentialImpl(const string &username, const string &password, bool shared);
68 ~CredentialImpl();
69
70 bool operator < (const CredentialImpl &other) const;
71
72 // Returns true if this credential should be shared.
73 bool isShared() const;
74
75 // Merge with other
76 void merge(const CredentialImpl &other);
77
78 // The time at which this credential was obtained.
79 CFAbsoluteTime creationTime() const;
80
81 // Return true iff this credential is valid.
82 bool isValid() const;
83
84 // Make this credential invalid.
85 void invalidate();
86
87 // We could make Rule a friend but instead we just expose this for now
88 inline const string& username() const { return mUsername; }
89 inline const uid_t uid() const { return mUid; }
90 inline const gid_t gid() const { return mGid; }
91
92
93 private:
94 // The username of the user that provided his password.
95 // This and mShared are what make this credential unique.
96 // @@@ We do not deal with the domain as of yet.
97 string mUsername;
98
99 // True iff this credential is shared.
100 bool mShared;
101
102 // Fields below are not used by less than operator
103
104 // cached pw-data as returned by getpwnam(mUsername)
105 uid_t mUid;
106 gid_t mGid;
107
108 CFAbsoluteTime mCreationTime;
109 bool mValid;
110 };
111
112
113 /* Credentials are less than comparable so they can be put in sets or maps. */
114 class Credential : public RefPointer<CredentialImpl>
115 {
116 public:
117 Credential();
118 Credential(CredentialImpl *impl);
119 Credential(const string &username, const uid_t uid, gid_t gid, bool shared);
120 Credential(const string &username, const string &password, bool shared);
121 ~Credential();
122
123 bool operator < (const Credential &other) const;
124 };
125
126
127 class MutableRightSet;
128 class RightSet;
129
130 class Right : protected AuthorizationItem
131 {
132 friend MutableRightSet;
133 friend RightSet;
134 public:
135 static Right &overlay(AuthorizationItem &item);
136 static Right *overlay(AuthorizationItem *item);
137 Right();
138 Right(AuthorizationString name, size_t valueLength, const void *value);
139 ~Right();
140
141 bool operator < (const Right &other) const;
142 AuthorizationString rightName() const { return name; }
143 size_t argumentLength() const { return valueLength; }
144 const void *argument() const { return value; }
145 };
146
147
148 /* A RightSet is a Container and a Back Insertion Sequence, but it is not a Sequence. Also it only
149 implements the const members of Container and Back Insertion Sequence. */
150 class RightSet
151 {
152 friend class MutableRightSet;
153 public:
154 // Container required memebers
155 typedef Right value_type;
156 typedef const Right &const_reference;
157 typedef const Right *const_pointer;
158 typedef const_pointer const_iterator;
159 typedef ptrdiff_t difference_type;
160 typedef size_t size_type;
161
162 RightSet(const AuthorizationRights *rights = NULL);
163 RightSet(const RightSet &other);
164 ~RightSet();
165
166 size_type size() const { return mRights->count; }
167 size_type max_size() const { return INT_MAX; }
168 const_iterator begin() const { return static_cast<const_pointer>(mRights->items); }
169 const_iterator end() const { return static_cast<const_pointer>(&mRights->items[mRights->count]); }
170 bool empty() const { return size() == 0; }
171
172 // Back Insertion Sequence required memebers
173 const_reference back() const;
174
175 // Other convenience members
176 operator const AuthorizationRights *() const { return mRights; }
177 private:
178 RightSet &operator = (const RightSet &other);
179
180 protected:
181 static const AuthorizationRights gEmptyRights;
182 AuthorizationRights *mRights;
183 };
184
185
186 /* A MutableRightSet is a Container and a Back Insertion Sequence, but it is not a Sequence. */
187 class MutableRightSet : public RightSet
188 {
189 public:
190 // Container required memebers
191 typedef Right &reference;
192 typedef Right *pointer;
193 typedef pointer iterator;
194
195 MutableRightSet(size_t count = 0, const Right &element = Right());
196 MutableRightSet(const RightSet &other);
197 ~MutableRightSet();
198
199 MutableRightSet &operator = (const RightSet &other);
200
201 iterator begin() { return static_cast<pointer>(mRights->items); }
202 iterator end() { return static_cast<pointer>(&mRights->items[mRights->count]); }
203 void swap(MutableRightSet &other);
204
205 // Back Insertion Sequence required memebers
206 reference back();
207 void push_back(const_reference right);
208 void pop_back();
209
210 // Other convenience members
211 size_type capacity() const { return mCapacity; }
212 private:
213 void grow(size_type min_capacity);
214
215 size_type mCapacity;
216 };
217
218
219 typedef set<Credential> CredentialSet;
220
221
222 class Rule
223 {
224 public:
225 Rule();
226 Rule(CFTypeRef cfRule);
227 Rule(const Rule &other);
228 Rule &operator = (const Rule &other);
229 ~Rule();
230
231 OSStatus evaluate(const Right &inRight, const AuthorizationEnvironment *environment,
232 AuthorizationFlags flags, CFAbsoluteTime now,
233 const CredentialSet *inCredentials, CredentialSet &credentials,
234 const AuthorizationToken &auth);
235
236 private:
237 OSStatus evaluate(const Right &inRight, const AuthorizationEnvironment *environment,
238 CFAbsoluteTime now, const Credential &credential, bool ignoreShared);
239 OSStatus obtainCredential(QueryAuthorizeByGroup &client, const Right &inRight,
240 const AuthorizationEnvironment *environment, const char *usernameHint,
241 Credential &outCredential, SecurityAgent::Reason reason);
242
243 enum Type
244 {
245 kDeny,
246 kAllow,
247 kUserInGroup
248 } mType;
249
250 string mGroupName;
251 CFTimeInterval mMaxCredentialAge;
252 bool mShared;
253 bool mAllowRoot;
254
255 static CFStringRef kUserInGroupID;
256 static CFStringRef kTimeoutID;
257 static CFStringRef kSharedID;
258 static CFStringRef kAllowRootID;
259 static CFStringRef kDenyID;
260 static CFStringRef kAllowID;
261 };
262
263
264 /* The engine which performs the actual authentication and authorization computations.
265
266 The implementation of a typical call to AuthorizationCreate would look like:
267
268 Get the current shared CredentialSet for this session.
269 Call authorizedRights() with inRights and the shared CredentialSet.
270 Compute the difference set between the rights requested and the rights returned from authorizedRights().
271 Call credentialIds() with the rights computed above (for which we have no credentials yet).
272 Call aquireCredentials() for the credentialIds returned from credentialIds()
273 For each credential returned place it in the session (replacing when needed) if shared() returns true.
274 The authorization returned to the user should now refer to the credentials in the session and the non shared ones returned by aquireCredentials().
275
276 When a call to AuthorizationCopyRights() is made, just call authorizedRights() using the union of the session credentials and the credentials tied to the authorization specified.
277
278 When a call to AuthorizationCopyInfo() is made, ask the Credential specified by tag for it info and return it.
279
280 When a call to AuthorizationFree() is made, delete all the non-shared credentials ascociated with the authorization specified. If the kAuthorizationFreeFlagDestroy is set. Also delete the shared credentials ascociated with the authorization specified.
281 */
282 class Engine
283 {
284 public:
285 Engine(const char *configFile);
286 ~Engine();
287
288 OSStatus authorize(const RightSet &inRights, const AuthorizationEnvironment *environment,
289 AuthorizationFlags flags, const CredentialSet *inCredentials, CredentialSet *outCredentials,
290 MutableRightSet *outRights, const AuthorizationToken &auth);
291 private:
292 void updateRules(CFAbsoluteTime now);
293 void readRules();
294 void parseRules(CFDictionaryRef rules);
295 static void parseRuleCallback(const void *key, const void *value, void *context);
296 void parseRule(CFStringRef right, CFTypeRef rule);
297
298 Rule getRule(const Right &inRight) const;
299
300 char *mRulesFileName;
301 CFAbsoluteTime mLastChecked;
302 struct timespec mRulesFileMtimespec;
303
304 typedef map<Right, Rule> RightMap;
305 typedef map<string, Rule> RuleMap;
306
307 RuleMap mRules;
308 };
309
310 }; // namespace Authorization
311
312 #endif /* ! __AuthorizationEngine__ */