KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > internal > core > PermissionAdminImpl


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.osgi.framework.internal.core;
13
14 import java.io.*;
15 import java.net.URL JavaDoc;
16 import java.security.*;
17 import java.util.ArrayList JavaDoc;
18 import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain;
19 import org.eclipse.osgi.framework.adaptor.PermissionStorage;
20 import org.eclipse.osgi.framework.debug.Debug;
21 import org.osgi.framework.AdminPermission;
22 import org.osgi.framework.FrameworkEvent;
23 import org.osgi.service.permissionadmin.PermissionAdmin;
24 import org.osgi.service.permissionadmin.PermissionInfo;
25
26 /**
27  * Permission Admin service for the OSGi specification.
28  *
29  * The Permission Admin service allows operators to
30  * manage the permissions of bundles. There is at most one Permission Admin
31  * service present in the Framework.
32  * <p>
33  * Access to the Permission Admin service is protected by
34  * corresponding
35  * <tt>ServicePermission</tt>. In addition the <tt>AdminPermission</tt>
36  * is required to actually set permissions.
37  *
38  * <p>Bundle permissions are managed using a permission table. A bundle's location
39  * serves as the key into this permission table. The value of a table entry is
40  * the set of permissions (of type <tt>PermissionInfo</tt>) granted to the
41  * bundle with the given location.
42  * A bundle may have an entry in the permission table prior to being installed
43  * in the Framework.
44  *
45  * <p>The permissions specified in <tt>setDefaultPermissions</tt> are used as the
46  * default
47  * permissions which are granted to all bundles that do not have an entry in
48  * the permission table.
49  *
50  * <p>Any changes to a bundle's permissions in the permission table will take
51  * effect no later than when bundle's <tt>java.security.ProtectionDomain</tt>
52  * is involved in a permission check, and will be made persistent.
53  *
54  * <p>Only permission classes on the system classpath or from an exported
55  * package are considered during a permission check.
56  * Additionally, only permission classes that are subclasses of
57  * <tt>java.security.Permission</tt> and define a 2-argument constructor
58  * that takes a <i>name</i> string and an <i>actions</i> string can be used.
59  * <p>
60  * Permissions implicitly granted by the Framework (for example, a bundle's
61  * permission to access its persistent storage area) cannot be changed, and
62  * are not reflected in the permissions returned by <tt>getPermissions</tt>
63  * and <tt>getDefaultPermissions</tt>.
64  */

65 public class PermissionAdminImpl implements PermissionAdmin {
66     private static final String JavaDoc ADMIN_IMPLIED_ACTIONS = AdminPermission.RESOURCE + ',' + AdminPermission.METADATA + ',' + AdminPermission.CLASS;
67
68     /** framework object */
69     protected Framework framework;
70
71     /** permission storage object */
72     protected PermissionStorage storage;
73
74     /** The permissions to use if no other permissions can be determined */
75     protected PermissionInfo[] defaultDefaultPermissionInfos;
76
77     /** The basic implied permissions for a bundle */
78     protected PermissionInfo[] baseImpliedPermissionInfos;
79
80     /** The permission collection containing the default assigned permissions */
81     protected BundleCombinedPermissions defaultAssignedPermissions;
82
83     /**
84      * Construstor.
85      *
86      * @param framework Framework object.
87      */

88     protected PermissionAdminImpl(Framework framework, PermissionStorage storage) {
89         this.framework = framework;
90         this.storage = storage;
91
92         defaultDefaultPermissionInfos = getPermissionInfos(getClass().getResource(Constants.OSGI_DEFAULT_DEFAULT_PERMISSIONS));
93         baseImpliedPermissionInfos = getPermissionInfos(getClass().getResource(Constants.OSGI_BASE_IMPLIED_PERMISSIONS));
94
95         if (Debug.DEBUG && Debug.DEBUG_SECURITY) {
96             Debug.println("Default default assigned bundle permissions"); //$NON-NLS-1$
97
if (defaultDefaultPermissionInfos == null) {
98                 Debug.println(" <none>"); //$NON-NLS-1$
99
} else {
100                 for (int i = 0; i < defaultDefaultPermissionInfos.length; i++) {
101                     Debug.println(" " + defaultDefaultPermissionInfos[i]); //$NON-NLS-1$
102
}
103             }
104
105             Debug.println("Base implied bundle permissions"); //$NON-NLS-1$
106
if (baseImpliedPermissionInfos == null) {
107                 Debug.println(" <none>"); //$NON-NLS-1$
108
} else {
109                 for (int i = 0; i < baseImpliedPermissionInfos.length; i++) {
110                     Debug.println(" " + baseImpliedPermissionInfos[i]); //$NON-NLS-1$
111
}
112             }
113         }
114
115         defaultAssignedPermissions = new BundleCombinedPermissions(null);
116         defaultAssignedPermissions.setAssignedPermissions(createDefaultAssignedPermissions(getDefaultPermissions()), true);
117     }
118
119     /**
120      * Gets the permissions assigned to the bundle with the specified
121      * location.
122      *
123      * @param location The location of the bundle whose permissions are to
124      * be returned.
125      *
126      * @return The permissions assigned to the bundle with the specified
127      * location, or <tt>null</tt> if that bundle has not been assigned any
128      * permissions.
129      */

130     public PermissionInfo[] getPermissions(String JavaDoc location) {
131         if (location == null) {
132             throw new NullPointerException JavaDoc();
133         }
134
135         PermissionStorage storage = new org.eclipse.osgi.framework.internal.core.SecurePermissionStorage(this.storage);
136
137         try {
138             String JavaDoc[] data = storage.getPermissionData(location);
139
140             if (Debug.DEBUG && Debug.DEBUG_SECURITY) {
141                 Debug.println("Getting permissions for location: " + location); //$NON-NLS-1$
142
if (data == null) {
143                     Debug.println(" <none>"); //$NON-NLS-1$
144
} else {
145                     for (int i = 0; i < data.length; i++) {
146                         Debug.println(" " + data[i]); //$NON-NLS-1$
147
}
148                 }
149             }
150
151             return makePermissionInfo(data);
152         } catch (IOException e) {
153             framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, e);
154
155             return null;
156         }
157     }
158
159     /**
160      * Assigns the specified permissions to the bundle with the specified
161      * location.
162      *
163      * @param location The location of the bundle that will be assigned the
164      * permissions.
165      * @param permissions The permissions to be assigned, or <tt>null</tt>
166      * if the specified location is to be removed from the permission table.
167      * @exception SecurityException if the caller does not have the
168      * <tt>AllPermission</tt>.
169      */

170     public void setPermissions(String JavaDoc location, PermissionInfo[] permissions) {
171         SecurityManager JavaDoc sm = System.getSecurityManager();
172         if (sm != null)
173             sm.checkPermission(new AllPermission());
174         if (location == null) {
175             throw new NullPointerException JavaDoc();
176         }
177
178         PermissionStorage storage = new org.eclipse.osgi.framework.internal.core.SecurePermissionStorage(this.storage);
179
180         try {
181             String JavaDoc[] data = makePermissionData(permissions);
182
183             if (Debug.DEBUG && Debug.DEBUG_SECURITY) {
184                 Debug.println("Setting permissions for location: " + location); //$NON-NLS-1$
185
if (data == null) {
186                     Debug.println(" <none>"); //$NON-NLS-1$
187
} else {
188                     for (int i = 0; i < data.length; i++) {
189                         Debug.println(" " + data[i]); //$NON-NLS-1$
190
}
191                 }
192             }
193
194             storage.setPermissionData(location, data);
195         } catch (IOException e) {
196             framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, e);
197
198             return;
199         }
200
201         AbstractBundle bundle = framework.getBundleByLocation(location);
202
203         if ((bundle != null) && (bundle.getBundleId() != 0)) {
204             ProtectionDomain domain = bundle.getProtectionDomain();
205
206             if (domain != null) {
207                 BundleCombinedPermissions combined = (BundleCombinedPermissions) domain.getPermissions();
208
209                 if (permissions == null) {
210                     combined.setAssignedPermissions(defaultAssignedPermissions, true);
211                 } else {
212                     combined.setAssignedPermissions(createPermissions(permissions, bundle, false), false);
213                 }
214             }
215         }
216     }
217
218     /**
219      * Returns the bundle locations that have permissions assigned to them,
220      * that is, bundle locations for which an entry
221      * exists in the permission table.
222      *
223      * @return The locations of bundles that have been assigned any
224      * permissions, or <tt>null</tt> if the permission table is empty.
225      */

226     public String JavaDoc[] getLocations() {
227         PermissionStorage storage = new org.eclipse.osgi.framework.internal.core.SecurePermissionStorage(this.storage);
228
229         try {
230             String JavaDoc[] locations = storage.getLocations();
231
232             return locations;
233         } catch (IOException e) {
234             framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, e);
235
236             return null;
237         }
238     }
239
240     /**
241      * Gets the default permissions.
242      *
243      * <p>These are the permissions granted to any bundle that does not
244      * have permissions assigned to its location.
245      *
246      * @return The default permissions, or <tt>null</tt> if default
247      * permissions have not been defined.
248      */

249     public PermissionInfo[] getDefaultPermissions() {
250         PermissionStorage storage = new org.eclipse.osgi.framework.internal.core.SecurePermissionStorage(this.storage);
251
252         try {
253             String JavaDoc[] data = storage.getPermissionData(null);
254
255             if (Debug.DEBUG && Debug.DEBUG_SECURITY) {
256                 Debug.println("Getting default permissions"); //$NON-NLS-1$
257
if (data == null) {
258                     Debug.println(" <none>"); //$NON-NLS-1$
259
} else {
260                     for (int i = 0; i < data.length; i++) {
261                         Debug.println(" " + data[i]); //$NON-NLS-1$
262
}
263                 }
264             }
265
266             return makePermissionInfo(data);
267         } catch (IOException e) {
268             framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, e);
269
270             return null;
271         }
272     }
273
274     /**
275      * Sets the default permissions.
276      *
277      * <p>These are the permissions granted to any bundle that does not
278      * have permissions assigned to its location.
279      *
280      * @param permissions The default permissions.
281      * @exception SecurityException if the caller does not have the
282      * <tt>AllPermission</tt>.
283      */

284     public void setDefaultPermissions(PermissionInfo[] permissions) {
285         SecurityManager JavaDoc sm = System.getSecurityManager();
286         if (sm != null)
287             sm.checkPermission(new AllPermission());
288         PermissionStorage storage = new org.eclipse.osgi.framework.internal.core.SecurePermissionStorage(this.storage);
289
290         try {
291             String JavaDoc[] data = makePermissionData(permissions);
292
293             if (Debug.DEBUG && Debug.DEBUG_SECURITY) {
294                 Debug.println("Setting default permissions"); //$NON-NLS-1$
295
if (data == null) {
296                     Debug.println(" <none>"); //$NON-NLS-1$
297
} else {
298                     for (int i = 0; i < data.length; i++) {
299                         Debug.println(" " + data[i]); //$NON-NLS-1$
300
}
301                 }
302             }
303
304             storage.setPermissionData(null, data);
305         } catch (IOException e) {
306             framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, e);
307
308             return;
309         }
310
311         defaultAssignedPermissions.setAssignedPermissions(createDefaultAssignedPermissions(permissions), true);
312     }
313
314     /**
315      * Make a PermissionInfo array from an array of encoded permission Strings.
316      *
317      * @param data Array of encoded permission Strings
318      * @return Array of PermissionInfo objects.
319      */

320     protected PermissionInfo[] makePermissionInfo(String JavaDoc[] data) {
321         if (data == null) {
322             return null;
323         }
324
325         int size = data.length;
326
327         PermissionInfo[] permissions = new PermissionInfo[size];
328
329         for (int i = 0; i < size; i++) {
330             permissions[i] = new PermissionInfo(data[i]);
331         }
332
333         return permissions;
334     }
335
336     /**
337      * Make an array of encoded permission Strings from a PermissionInfo array.
338      *
339      * @param permissions Array of PermissionInfor objects.
340      * @return Array of encoded permission Strings
341      */

342     protected String JavaDoc[] makePermissionData(PermissionInfo[] permissions) {
343         if (permissions == null) {
344             return null;
345         }
346
347         int size = permissions.length;
348
349         String JavaDoc[] data = new String JavaDoc[size];
350
351         for (int i = 0; i < size; i++) {
352             data[i] = permissions[i].getEncoded();
353         }
354
355         return data;
356     }
357
358     /**
359      * This method is called by the Bundle object to create the
360      * PermissionCollection used by the bundle's ProtectionDomain.
361      *
362      * @param bundle the bundle object
363      * @return BundleCombinedPermission object with the bundle's
364      * dynamic permissions.
365      */

366     protected BundleProtectionDomain createProtectionDomain(AbstractBundle bundle) {
367         BundlePermissionCollection implied = getImpliedPermissions(bundle);
368
369         BundleCombinedPermissions combined = new BundleCombinedPermissions(implied);
370
371         BundlePermissionCollection assigned = getAssignedPermissions(bundle);
372
373         combined.setAssignedPermissions(assigned, assigned == defaultAssignedPermissions);
374
375         combined.setConditionalPermissions(new ConditionalPermissions(bundle, framework.condPermAdmin));
376
377         /* now process the permissions.perm file, if it exists, and build the
378          * restrictedPermissions using it. */

379         PermissionInfo[] permInfos = getPermissionInfos(bundle.getEntry("OSGI-INF/permissions.perm")); //$NON-NLS-1$
380
if (permInfos != null) {
381             ConditionalPermissionInfoImpl cpiArray[] = new ConditionalPermissionInfoImpl[1];
382             cpiArray[0] = new ConditionalPermissionInfoImpl(null, ConditionalPermissionAdminImpl.EMPTY_COND_INFO, permInfos);
383             ConditionalPermissionSet cps = new ConditionalPermissionSet(bundle, cpiArray, ConditionalPermissionAdminImpl.EMPTY_COND);
384             combined.setRestrictedPermissions(cps);
385         }
386
387         return new BundleProtectionDomainImpl(bundle, combined);
388     }
389
390     /**
391      * Creates the default assigned permissions for bundles that
392      * have no assigned permissions.
393      * The default permissions are assigned via the PermissionAdmin service
394      * and may change dynamically.
395      *
396      * @return A PermissionCollection of the default assigned permissions.
397      */

398     protected BundlePermissionCollection createDefaultAssignedPermissions(PermissionInfo[] info) {
399         if (Debug.DEBUG && Debug.DEBUG_SECURITY) {
400             Debug.println("Creating default assigned permissions"); //$NON-NLS-1$
401
}
402
403         if (info == null) {
404             info = defaultDefaultPermissionInfos;
405         }
406
407         return createPermissions(info, null, false);
408     }
409
410     /**
411      * Returns the assigned permissions for a bundle.
412      * These permissions are assigned via the PermissionAdmin service
413      * and may change dynamically.
414      *
415      * @param bundle The bundle to create the permissions for.
416      * @return A PermissionCollection of the assigned permissions.
417      */

418     protected BundlePermissionCollection getAssignedPermissions(AbstractBundle bundle) {
419         String JavaDoc location = bundle.getLocation();
420
421         PermissionInfo[] info = getPermissions(location);
422
423         if (info == null) {
424             return defaultAssignedPermissions;
425         }
426
427         if (Debug.DEBUG && Debug.DEBUG_SECURITY) {
428             Debug.println("Creating assigned permissions for " + bundle); //$NON-NLS-1$
429
}
430
431         return createPermissions(info, bundle, false);
432     }
433
434     /**
435      * Returns the implied permissions for a bundle.
436      * These permissions never change.
437      *
438      * @param bundle The bundle to create the permissions for.
439      * @return A PermissionCollection of the implied permissions.
440      */

441     protected BundlePermissionCollection getImpliedPermissions(AbstractBundle bundle) {
442         if (Debug.DEBUG && Debug.DEBUG_SECURITY)
443             Debug.println("Creating implied permissions for " + bundle); //$NON-NLS-1$
444

445         return createPermissions(baseImpliedPermissionInfos, bundle, true);
446     }
447
448     /**
449      * Read the permissions from the specified resource.
450      *
451      * @return An array of PermissionInfo objects from the specified
452      * resource.
453      */

454     protected PermissionInfo[] getPermissionInfos(URL JavaDoc resource) {
455         if (resource == null)
456             return null;
457         PermissionInfo[] info = ConditionalPermissionAdminImpl.EMPTY_PERM_INFO;
458         DataInputStream in = null;
459         try {
460             in = new DataInputStream(resource.openStream());
461             ArrayList JavaDoc permissions = new ArrayList JavaDoc();
462             BufferedReader reader;
463             try {
464                 reader = new BufferedReader(new InputStreamReader(in, "UTF8")); //$NON-NLS-1$
465
} catch (UnsupportedEncodingException e) {
466                 reader = new BufferedReader(new InputStreamReader(in));
467             }
468
469             while (true) {
470                 String JavaDoc line = reader.readLine();
471                 if (line == null) /* EOF */
472                     break;
473                 line = line.trim();
474                 if ((line.length() == 0) || line.startsWith("#") || line.startsWith("//")) /* comments */ //$NON-NLS-1$ //$NON-NLS-2$
475
continue;
476
477                 try {
478                     permissions.add(new PermissionInfo(line));
479                 } catch (IllegalArgumentException JavaDoc iae) {
480                     /* incorrectly encoded permission */
481                     framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, iae);
482                 }
483             }
484             int size = permissions.size();
485             if (size > 0)
486                 info = (PermissionInfo[]) permissions.toArray(new PermissionInfo[size]);
487         } catch (IOException e) {
488             // do nothing
489
} finally {
490             try {
491                 if (in != null)
492                     in.close();
493             } catch (IOException ee) {
494                 // do nothing
495
}
496         }
497         return info;
498     }
499
500     /**
501      * Create a PermissionCollection from a PermissionInfo array.
502      *
503      * @param info Array of PermissionInfo objects.
504      * @param bundle The target bundle for the permissions.
505      * @return A PermissionCollection containing Permission objects.
506      */

507     protected BundlePermissionCollection createPermissions(PermissionInfo[] info, final AbstractBundle bundle, boolean implied) {
508         if (info == null)
509             info = new PermissionInfo[0];
510         if (implied) {
511             // create the implied AdminPermission actions for this bundle
512
PermissionInfo impliedInfo = new PermissionInfo(AdminPermission.class.getName(), "(id=" + bundle.getBundleId() + ")", ADMIN_IMPLIED_ACTIONS); //$NON-NLS-1$ //$NON-NLS-2$
513
if (Debug.DEBUG && Debug.DEBUG_SECURITY)
514                 Debug.println("Created permission: " + impliedInfo); //$NON-NLS-1$
515
PermissionInfo[] impliedInfos = new PermissionInfo[info.length + 1];
516             System.arraycopy(info, 0, impliedInfos, 0, info.length);
517             impliedInfos[info.length] = impliedInfo;
518             info = impliedInfos;
519         }
520         ConditionalPermissionInfoImpl cpiArray[] = new ConditionalPermissionInfoImpl[1];
521         cpiArray[0] = new ConditionalPermissionInfoImpl(null, ConditionalPermissionAdminImpl.EMPTY_COND_INFO, info);
522         return new ConditionalPermissionSet(bundle, cpiArray, ConditionalPermissionAdminImpl.EMPTY_COND);
523     }
524
525 }
526
Popular Tags