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 synchronized (_initialized)
98 {
99 if (!_initialized)
100 {
101 refresh();
102 }
103 }
104
105 synchronized (_cache)
106 {
107 if (_cache.containsKey(domain))
108 {
109 return copyOf(_cache.get(domain));
110 }
111
112 PermissionCollection perms = new Permissions();
113
114 for (Iterator<PolicyBlock> i = _grants.iterator(); i.hasNext();)
115 {
116 PolicyBlock policyBlock = i.next();
117 ProtectionDomain grantPD = policyBlock.toProtectionDomain();
118
119 if (__DEBUG)
120 {
121 System.out.println("----START----");
122 System.out.println("PDCS: " + policyBlock.getCodeSource());
123 System.out.println("CS: " + domain.getCodeSource());
124 }
125
126
127
128
129 if (grantPD.getCodeSource() == null || grantPD.getCodeSource().implies(domain.getCodeSource()) && grantPD.getPrincipals() == null || grantPD.getCodeSource().implies(domain.getCodeSource())
130 && validate(grantPD.getPrincipals(),domain.getPrincipals()))
131 {
132
133 for (Enumeration<Permission> e = policyBlock.getPermissions().elements(); e.hasMoreElements();)
134 {
135 Permission perm = e.nextElement();
136 if (__DEBUG)
137 {
138 System.out.println("D: " + perm);
139 }
140 perms.add(perm);
141 }
142 }
143 if (__DEBUG)
144 {
145 System.out.println("----STOP----");
146 }
147 }
148
149 _cache.put(domain,perms);
150
151 return copyOf(perms);
152 }
153 }
154
155 @Override
156 public PermissionCollection getPermissions(CodeSource codesource)
157 {
158 synchronized (_initialized)
159 {
160 if (!_initialized)
161 {
162 refresh();
163 }
164 }
165
166 synchronized (_cache)
167 {
168 if (_cache.containsKey(codesource))
169 {
170 return copyOf(_cache.get(codesource));
171 }
172
173 PermissionCollection perms = new Permissions();
174
175 for (Iterator<PolicyBlock> i = _grants.iterator(); i.hasNext();)
176 {
177 PolicyBlock policyBlock = i.next();
178 ProtectionDomain grantPD = policyBlock.toProtectionDomain();
179
180 if (grantPD.getCodeSource() == null || grantPD.getCodeSource().implies(codesource))
181 {
182 if (__DEBUG)
183 {
184 System.out.println("----START----");
185 System.out.println("PDCS: " + grantPD.getCodeSource());
186 System.out.println("CS: " + codesource);
187 }
188
189 for (Enumeration<Permission> e = policyBlock.getPermissions().elements(); e.hasMoreElements();)
190 {
191 Permission perm = e.nextElement();
192 if (__DEBUG)
193 {
194 System.out.println("D: " + perm);
195 }
196 perms.add(perm);
197 }
198
199 if (__DEBUG)
200 {
201 System.out.println("----STOP----");
202 }
203 }
204 }
205
206 _cache.put(codesource,perms);
207
208 return copyOf(perms);
209 }
210 }
211
212 @Override
213 public boolean implies(ProtectionDomain domain, Permission permission)
214 {
215 PermissionCollection pc = getPermissions(domain);
216
217 return (pc == null ? false : pc.implies(permission));
218 }
219
220
221 private static boolean validate(Principal[] permCerts, Principal[] classCerts)
222 {
223 if (classCerts == null)
224 {
225 return false;
226 }
227
228 for (int i = 0; i < permCerts.length; ++i)
229 {
230 boolean found = false;
231 for (int j = 0; j < classCerts.length; ++j)
232 {
233 if (permCerts[i].equals(classCerts[j]))
234 {
235 found = true;
236 break;
237 }
238 }
239
240 if (found == false)
241 {
242 return false;
243 }
244 }
245
246 return true;
247 }
248
249 @Override
250 public synchronized void refresh()
251 {
252
253 try
254 {
255
256 if (__RELOAD && _scanner == null)
257 {
258 initializeReloading();
259 }
260
261 if (__DEBUG)
262 {
263 synchronized (_cache)
264 {
265 for (Iterator<Object> i = _cache.keySet().iterator(); i.hasNext();)
266 {
267 System.out.println(i.next().toString());
268 }
269 }
270 }
271
272 Set<PolicyBlock> clean = new HashSet<PolicyBlock>();
273
274 for (Iterator<String> i = _policies.iterator(); i.hasNext();)
275 {
276 File policyFile = new File(i.next());
277
278 clean.addAll(DefaultPolicyLoader.load(new FileInputStream(policyFile),_context));
279 }
280
281 synchronized (_cache)
282 {
283 _grants.clear();
284 _grants.addAll(clean);
285 _cache.clear();
286 }
287 _initialized = true;
288 }
289 catch (Exception e)
290 {
291 e.printStackTrace();
292 }
293 }
294
295 private void initializeReloading() throws Exception
296 {
297 _scanner = new Scanner();
298
299 List<File> scanDirs = new ArrayList<File>();
300
301 for (Iterator<String> i = _policies.iterator(); i.hasNext();)
302 {
303 File policyFile = new File(i.next());
304 scanDirs.add(policyFile.getParentFile());
305 }
306
307 _scanner.addListener(new Scanner.DiscreteListener()
308 {
309
310 public void fileRemoved(String filename) throws Exception
311 {
312
313 }
314
315
316 public void fileChanged(String filename) throws Exception
317 {
318 if (filename.endsWith("policy"))
319 {
320 System.out.println("JettyPolicy: refreshing policy files");
321 refresh();
322 System.out.println("JettyPolicy: finished refreshing policies");
323 }
324 }
325
326 public void fileAdded(String filename) throws Exception
327 {
328
329 }
330 });
331
332 _scanner.setScanDirs(scanDirs);
333 _scanner.start();
334 _scanner.setScanInterval(10);
335 }
336
337 public void dump(PrintStream out)
338 {
339 PrintWriter write = new PrintWriter(out);
340 write.println("dumping policy settings");
341
342 synchronized (_cache)
343 {
344 for (Iterator<Object> i = _cache.keySet().iterator(); i.hasNext();)
345 {
346 Object o = i.next();
347 write.println(o.toString());
348 }
349 }
350 write.flush();
351 }
352
353 public PermissionCollection copyOf(final PermissionCollection in)
354 {
355 PermissionCollection out = new Permissions();
356 synchronized (in)
357 {
358 for (Enumeration el = in.elements() ; el.hasMoreElements() ;)
359 {
360 out.add((Permission)el.nextElement());
361 }
362 }
363 return out;
364 }
365 }