1 package org.eclipse.jetty.policy;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.PrintStream;
22 import java.io.PrintWriter;
23 import java.security.AccessControlException;
24 import java.security.CodeSource;
25 import java.security.Permission;
26 import java.security.PermissionCollection;
27 import java.security.Permissions;
28 import java.security.Policy;
29 import java.security.Principal;
30 import java.security.ProtectionDomain;
31 import java.util.ArrayList;
32 import java.util.Enumeration;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Set;
39
40 import org.eclipse.jetty.policy.loader.DefaultPolicyLoader;
41 import org.eclipse.jetty.util.Scanner;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class JettyPolicy extends Policy
58 {
59 private static boolean __DEBUG = false;
60 private static boolean __RELOAD = false;
61
62
63 private final Set<String> _policies;
64
65 private final Set<PolicyBlock> _grants = new HashSet<PolicyBlock>();
66
67 private final Map<Object, PermissionCollection> _cache = new HashMap<Object, PermissionCollection>();
68
69 private final PolicyContext _context = new PolicyContext();
70
71 private Boolean _initialized = false;
72
73 private Scanner _scanner;
74
75 public JettyPolicy(Set<String> policies, Map<String, String> properties)
76 {
77 try
78 {
79
80 __RELOAD = Boolean.getBoolean("org.eclipse.jetty.policy.RELOAD");
81 __DEBUG = Boolean.getBoolean("org.eclipse.jetty.policy.DEBUG");
82 }
83 catch (AccessControlException ace)
84 {
85 __RELOAD = false;
86 __DEBUG = false;
87 }
88
89 _policies = policies;
90 _context.setProperties(properties);
91 }
92
93 @Override
94 public PermissionCollection getPermissions(ProtectionDomain domain)
95 {
96
97 if (!_initialized)
98 {
99 synchronized (_initialized)
100 {
101
102 if (!_initialized)
103 {
104 refresh();
105 }
106 }
107 }
108
109 if (_cache.containsKey(domain))
110 {
111 return _cache.get(domain);
112 }
113
114 synchronized (_cache)
115 {
116
117 if (_cache.containsKey(domain))
118 {
119 return _cache.get(domain);
120 }
121
122 PermissionCollection perms = new Permissions();
123
124 for (Iterator<PolicyBlock> i = _grants.iterator(); i.hasNext();)
125 {
126 PolicyBlock policyBlock = i.next();
127 ProtectionDomain grantPD = policyBlock.toProtectionDomain();
128
129 if (__DEBUG)
130 {
131 System.out.println("----START----");
132 System.out.println("PDCS: " + policyBlock.getCodeSource());
133 System.out.println("CS: " + domain.getCodeSource());
134 }
135
136
137
138
139 if (grantPD.getCodeSource() == null || grantPD.getCodeSource().implies(domain.getCodeSource()) && grantPD.getPrincipals() == null || grantPD.getCodeSource().implies(domain.getCodeSource())
140 && validate(grantPD.getPrincipals(),domain.getPrincipals()))
141 {
142
143 for (Enumeration<Permission> e = policyBlock.getPermissions().elements(); e.hasMoreElements();)
144 {
145 Permission perm = e.nextElement();
146 if (__DEBUG)
147 {
148 System.out.println("D: " + perm);
149 }
150 perms.add(perm);
151 }
152 }
153 if (__DEBUG)
154 {
155 System.out.println("----STOP----");
156 }
157 }
158
159 _cache.put(domain,perms);
160
161 return perms;
162 }
163 }
164
165 @Override
166 public PermissionCollection getPermissions(CodeSource codesource)
167 {
168 if (!_initialized)
169 {
170 synchronized (_initialized)
171 {
172
173 if (!_initialized)
174 {
175 refresh();
176 }
177 }
178 }
179
180 if (_cache.containsKey(codesource))
181 {
182 return _cache.get(codesource);
183 }
184
185 synchronized (_cache)
186 {
187
188 if (_cache.containsKey(codesource))
189 {
190 return _cache.get(codesource);
191 }
192
193 PermissionCollection perms = new Permissions();
194
195 for (Iterator<PolicyBlock> i = _grants.iterator(); i.hasNext();)
196 {
197 PolicyBlock policyBlock = i.next();
198 ProtectionDomain grantPD = policyBlock.toProtectionDomain();
199
200 if (grantPD.getCodeSource() == null || grantPD.getCodeSource().implies(codesource))
201 {
202 if (__DEBUG)
203 {
204 System.out.println("----START----");
205 System.out.println("PDCS: " + grantPD.getCodeSource());
206 System.out.println("CS: " + codesource);
207 }
208
209 for (Enumeration<Permission> e = policyBlock.getPermissions().elements(); e.hasMoreElements();)
210 {
211 Permission perm = e.nextElement();
212 if (__DEBUG)
213 {
214 System.out.println("D: " + perm);
215 }
216 perms.add(perm);
217 }
218
219 if (__DEBUG)
220 {
221 System.out.println("----STOP----");
222 }
223 }
224 }
225
226 _cache.put(codesource,perms);
227
228 return perms;
229 }
230 }
231
232 @Override
233 public boolean implies(ProtectionDomain domain, Permission permission) {
234 PermissionCollection pc;
235
236 if (!_initialized)
237 {
238 synchronized (_initialized)
239 {
240
241 if (!_initialized)
242 {
243 refresh();
244 }
245 }
246 }
247
248 synchronized (_cache) {
249 pc = _cache.get(domain);
250 }
251
252 if (pc != null) {
253 return pc.implies(permission);
254 }
255
256 pc = getPermissions(domain);
257 if (pc == null) {
258 return false;
259 }
260
261 synchronized (_cache) {
262
263 _cache.put(domain, pc);
264 }
265
266 return pc.implies(permission);
267 }
268
269
270 private static boolean validate(Principal[] permCerts, Principal[] classCerts)
271 {
272 if (classCerts == null)
273 {
274 return false;
275 }
276
277 for (int i = 0; i < permCerts.length; ++i)
278 {
279 boolean found = false;
280 for (int j = 0; j < classCerts.length; ++j)
281 {
282 if (permCerts[i].equals(classCerts[j]))
283 {
284 found = true;
285 break;
286 }
287 }
288
289 if (found == false)
290 {
291 return false;
292 }
293 }
294
295 return true;
296 }
297
298 @Override
299 public synchronized void refresh()
300 {
301
302 try
303 {
304
305 if (__RELOAD && _scanner == null)
306 {
307 initializeReloading();
308 }
309
310 if (__DEBUG)
311 {
312 synchronized (_cache)
313 {
314 for (Iterator<Object> i = _cache.keySet().iterator(); i.hasNext();)
315 {
316 System.out.println(i.next().toString());
317 }
318 }
319 }
320
321 Set<PolicyBlock> clean = new HashSet<PolicyBlock>();
322
323 for (Iterator<String> i = _policies.iterator(); i.hasNext();)
324 {
325 File policyFile = new File(i.next());
326
327 clean.addAll(DefaultPolicyLoader.load(new FileInputStream(policyFile),_context));
328 }
329
330 synchronized (_cache)
331 {
332 _grants.clear();
333 _grants.addAll(clean);
334 _cache.clear();
335 }
336 _initialized = true;
337 }
338 catch (Exception e)
339 {
340 e.printStackTrace();
341 }
342 }
343
344 private void initializeReloading() throws Exception
345 {
346 _scanner = new Scanner();
347
348 List<File> scanDirs = new ArrayList<File>();
349
350 for (Iterator<String> i = _policies.iterator(); i.hasNext();)
351 {
352 File policyFile = new File(i.next());
353 scanDirs.add(policyFile.getParentFile());
354 }
355
356 _scanner.addListener(new Scanner.DiscreteListener()
357 {
358
359 public void fileRemoved(String filename) throws Exception
360 {
361
362 }
363
364
365 public void fileChanged(String filename) throws Exception
366 {
367 if (filename.endsWith("policy"))
368 {
369 System.out.println("JettyPolicy: refreshing policy files");
370 refresh();
371 System.out.println("JettyPolicy: finished refreshing policies");
372 }
373 }
374
375 public void fileAdded(String filename) throws Exception
376 {
377
378 }
379 });
380
381 _scanner.setScanDirs(scanDirs);
382 _scanner.start();
383 _scanner.setScanInterval(10);
384 }
385
386 public void dump(PrintStream out)
387 {
388 PrintWriter write = new PrintWriter(out);
389 write.println("dumping policy settings");
390
391 synchronized (_cache)
392 {
393 for (Iterator<Object> i = _cache.keySet().iterator(); i.hasNext();)
394 {
395 Object o = i.next();
396 write.println(o.toString());
397 }
398 }
399 write.flush();
400 }
401 }