SecurePermissionOps.java

00001 /*
00002  * Copyright (c) 2006, KNOPFLERFISH project
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following
00007  * conditions are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  *
00012  * - Redistributions in binary form must reproduce the above
00013  *   copyright notice, this list of conditions and the following
00014  *   disclaimer in the documentation and/or other materials
00015  *   provided with the distribution.
00016  *
00017  * - Neither the name of the KNOPFLERFISH project nor the names of its
00018  *   contributors may be used to endorse or promote products derived
00019  *   from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00028  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00030  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00032  * OF THE POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 package org.knopflerfish.framework;
00036 
00037 import java.io.InputStream;
00038 import java.net.URL;
00039 import java.net.MalformedURLException;
00040 import java.security.*;
00041 import java.security.cert.Certificate;
00042 import java.util.*;
00043 
00044 import org.osgi.framework.*;
00045 import org.osgi.service.permissionadmin.PermissionAdmin;
00046 
00047 import org.knopflerfish.framework.PermissionOps;
00048 import org.knopflerfish.framework.permissions.PermissionsHandle;
00049 
00050 
00051 class SecurePermissionOps extends PermissionOps {
00052 
00053   private static final int AP_CLASS = 0;
00054   private static final int AP_EXECUTE = 1;
00055   private static final int AP_EXTENSIONLIFECYCLE = 2;
00056   private static final int AP_LIFECYCLE = 3;
00057   private static final int AP_LISTENER = 4;
00058   private static final int AP_METADATA = 5;
00059   private static final int AP_RESOURCE = 6;
00060   private static final int AP_MAX = 7;
00061 
00062   private static String [] AP_TO_STRING = new String [] {
00063     AdminPermission.CLASS,
00064     AdminPermission.EXECUTE,
00065     AdminPermission.EXTENSIONLIFECYCLE,
00066     AdminPermission.LIFECYCLE,
00067     AdminPermission.LISTENER,
00068     AdminPermission.METADATA,
00069     AdminPermission.RESOURCE,
00070   };
00071 
00072   private final Framework framework;
00073   private final PermissionsHandle ph;
00074 
00075   private AdminPermission ap_resolve_perm = null;
00076   private AdminPermission ap_startlevel_perm = null;
00077 
00078 
00079   Hashtable /* Bundle -> AdminPermission [] */ adminPerms = new Hashtable();
00080 
00081 
00082   SecurePermissionOps(Framework fw) {
00083     framework = fw;
00084     ph = new PermissionsHandle(fw);
00085   }
00086 
00087 
00088   void registerService() {
00089     String[] classes = new String [] { PermissionAdmin.class.getName() };
00090     framework.services.register(framework.systemBundle, classes,
00091                                 ph.getPermissionAdminService(), null);
00092   }
00093 
00094 
00095   boolean checkPermissions() {
00096     return true;
00097   }
00098 
00099   //
00100   // Permission checks
00101   //
00102 
00103   boolean okClassAdminPerm(Bundle b) {
00104     try {
00105       AccessController.checkPermission(getAdminPermission(b, AP_CLASS));
00106       return true;
00107     } catch (AccessControlException _ignore) {
00108       return false;
00109     }
00110   }
00111 
00112   void checkExecuteAdminPerm(Bundle b){
00113     AccessController.checkPermission(getAdminPermission(b, AP_EXECUTE));
00114   }
00115 
00116   void checkExtensionLifecycleAdminPerm(Bundle b) {
00117     AccessController.checkPermission(getAdminPermission(b, AP_EXTENSIONLIFECYCLE));
00118   }
00119 
00120   void checkExtensionLifecycleAdminPerm(Bundle b, Object checkContext) {
00121     ((AccessControlContext)checkContext).
00122       checkPermission(getAdminPermission(b, AP_EXTENSIONLIFECYCLE));
00123   }
00124 
00125   void checkLifecycleAdminPerm(Bundle b) {
00126     AccessController.checkPermission(getAdminPermission(b, AP_LIFECYCLE));
00127   }
00128 
00129   void checkLifecycleAdminPerm(Bundle b, Object checkContext) {
00130     ((AccessControlContext)checkContext).
00131       checkPermission(getAdminPermission(b, AP_LIFECYCLE));
00132   }
00133 
00134   void checkListenerAdminPerm(Bundle b) {
00135     AccessController.checkPermission(getAdminPermission(b, AP_LISTENER));
00136   }
00137 
00138   void checkMetadataAdminPerm(Bundle b) {
00139     AccessController.checkPermission(getAdminPermission(b, AP_METADATA));
00140   }
00141 
00142   void checkResolveAdminPerm() {
00143     if (ap_resolve_perm == null) {
00144       ap_resolve_perm = new AdminPermission(framework.systemBundle, AdminPermission.RESOLVE);
00145     }
00146     AccessController.checkPermission(ap_resolve_perm);
00147   }
00148   
00149   void checkResourceAdminPerm(Bundle b) {
00150     AccessController.checkPermission(getAdminPermission(b, AP_RESOURCE));
00151   }
00152 
00153   boolean okResourceAdminPerm(Bundle b) {
00154     try {
00155       checkResourceAdminPerm(b);
00156       return true;
00157     } catch (AccessControlException _ignore) {
00158       return false;
00159     }
00160   }
00161   
00162   void checkStartLevelAdminPerm(){
00163     if (ap_startlevel_perm == null) {
00164       ap_startlevel_perm = new AdminPermission(framework.systemBundle,
00165                                                AdminPermission.STARTLEVEL);
00166     }
00167     AccessController.checkPermission(ap_startlevel_perm);
00168   }
00169 
00170   //
00171   // Bundle permission checks
00172   //
00173 
00174   boolean okFragmentBundlePerm(BundleImpl b) {
00175     PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
00176     return pc.implies(new BundlePermission(b.symbolicName, BundlePermission.FRAGMENT));
00177   }
00178 
00179   boolean okHostBundlePerm(BundleImpl b) {
00180     PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
00181     return pc.implies(new BundlePermission(b.symbolicName, BundlePermission.HOST));
00182   }
00183 
00184   boolean okProvideBundlePerm(BundleImpl b) {
00185     PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
00186     return pc.implies(new BundlePermission(b.symbolicName, BundlePermission.PROVIDE));
00187   }
00188 
00189   boolean okRequireBundlePerm(BundleImpl b) {
00190     PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
00191     return pc.implies(new BundlePermission(b.symbolicName, BundlePermission.REQUIRE));
00192   }
00193 
00194   //
00195   // Package permission checks
00196   //  
00197 
00198   boolean hasImportPackagePermission(BundleImpl b, String pkg) {
00199     if (b.id != 0) {
00200       PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
00201       return pc.implies(new PackagePermission(pkg, PackagePermission.IMPORT));
00202     }
00203     return true;
00204   }
00205 
00212   String missingMandatoryPackagePermissions(BundlePackages bpkgs, List okImports) {
00213     if (bpkgs.bundle.id == 0) {
00214       return null;
00215     }
00216     PermissionCollection pc = ph.getPermissionCollection(new Long(bpkgs.bundle.id));
00217     String e_res = null;
00218     for (Iterator i = bpkgs.getExports(); i.hasNext();) {
00219       ExportPkg p = (ExportPkg)i.next();
00220       if (!pc.implies(new PackagePermission(p.name, PackagePermission.EXPORT))) {
00221         if (e_res != null) {
00222           e_res = e_res + ", " + p.name;
00223         } else {
00224           e_res = "missing export permission for package(s): " + p.name;
00225           e_res = p.name;
00226         }
00227       }
00228     }
00229     String i_res = null;
00230     for (Iterator i = bpkgs.getImports(); i.hasNext();) {
00231       ImportPkg p = (ImportPkg)i.next();
00232       if (!pc.implies(new PackagePermission(p.name, PackagePermission.IMPORT))) {
00233         if (p.resolution == Constants.RESOLUTION_OPTIONAL) {
00234           // Ok, that we do not have permission to optional packages
00235           continue;
00236         }
00237         if (i_res != null) {
00238           i_res = i_res + ", " + p.name;
00239         } else {
00240           i_res = "missing import permission for package(s): " + p.name;
00241         }
00242       } else {
00243         okImports.add(p);
00244       }
00245     }
00246     if (e_res != null) {
00247       if (i_res != null) {
00248         return e_res + "; " + i_res;
00249       } else {
00250         return e_res;
00251       }
00252     } else {
00253       return i_res;
00254     }
00255   }
00256 
00257   //
00258   // Service permission checks
00259   //  
00260 
00261   void checkRegisterServicePerm(String clazz) {
00262     AccessController.checkPermission(new ServicePermission(clazz, ServicePermission.REGISTER));
00263   }
00264 
00265   boolean okGetServicePerm(String clazz) {
00266     String c = (clazz != null) ? clazz : "*";
00267     try {
00268       AccessController.checkPermission(new ServicePermission(c, ServicePermission.GET));
00269       return true;
00270     } catch (AccessControlException _ignore) {
00271       return false;
00272     }
00273   }
00274 
00275   void checkGetServicePerms(String [] classes) {
00276     if (!okGetServicePerms(classes)) {
00277       throw new SecurityException("Missing permission to get the service.");
00278     }
00279   }
00280 
00281   boolean okGetServicePerms(String [] classes) {
00282     AccessControlContext acc = AccessController.getContext();
00283     return okGetServicePerms(acc, classes);
00284   }
00285 
00286 
00287   private boolean okGetServicePerms(AccessControlContext acc, String [] classes) {
00288     for (int i = 0; i < classes.length; i++) {
00289       try { 
00290         acc.checkPermission(new ServicePermission(classes[i], ServicePermission.GET));
00291         return true;
00292       } catch (AccessControlException ignore) { }
00293     }
00294     return false;
00295   }
00296 
00302   void filterGetServicePermission(Set srs) {
00303     AccessControlContext acc = AccessController.getContext();
00304     for (Iterator i = srs.iterator(); i.hasNext();) {
00305       ServiceRegistrationImpl sr = (ServiceRegistrationImpl)i.next();;
00306       String[] classes = (String[])sr.properties.get(Constants.OBJECTCLASS);
00307       if (!okGetServicePerms(acc, classes)) {
00308         i.remove();
00309       }
00310     }
00311   }
00312 
00313   //
00314   // BundleArchive secure operations
00315   //
00316 
00317   InputStream callGetInputStream(final BundleArchive archive,
00318                                  final String name,
00319                                  final int ix) {
00320     return (InputStream)AccessController.doPrivileged(new PrivilegedAction() {
00321         public Object run() {
00322           return archive.getInputStream(name, ix);
00323         }
00324       });
00325   }
00326 
00327 
00328   Enumeration callFindResourcesPath(final BundleArchive archive,
00329                                    final String path) {
00330     return (Enumeration)AccessController.doPrivileged(new PrivilegedAction() {
00331         public Object run() {
00332           return archive.findResourcesPath(path);
00333         }
00334       });
00335   }
00336 
00337   //
00338   // BundleClassLoader secure operations
00339   //
00340 
00341   Object callSearchFor(final BundleClassLoader cl,
00342                        final String name,
00343                        final String pkg,
00344                        final String path,
00345                        final BundleClassLoader.SearchAction action,
00346                        final boolean onlyFirst,
00347                        final BundleClassLoader requestor,
00348                        final HashSet visited) {
00349     return AccessController.doPrivileged(new PrivilegedAction() {
00350         public Object run() {
00351           return cl.searchFor(name, pkg, path, action, onlyFirst, requestor, visited);
00352         }
00353       });
00354   }
00355 
00356 
00357   //
00358   // BundleImpl secure operations
00359   //
00360 
00361   void callStart0(final BundleImpl b) throws BundleException {
00362     try {
00363       AccessController.doPrivileged(new PrivilegedExceptionAction() {
00364           public Object run() throws BundleException {
00365             b.start0();
00366             return null;
00367           }
00368         });
00369     } catch (PrivilegedActionException e) {
00370       throw (BundleException) e.getException();
00371     }
00372   }
00373 
00374 
00375   BundleException callStop0(final BundleImpl b, final boolean resetPersistent)  {
00376     return (BundleException)
00377       AccessController.doPrivileged(new PrivilegedAction() {
00378           public Object run() {
00379             return b.stop0(resetPersistent);
00380           }
00381         });
00382   }
00383 
00384 
00385   void callUpdate0(final BundleImpl b, final InputStream in, final boolean wasActive)
00386     throws BundleException {
00387     try {
00388       AccessController.doPrivileged(new PrivilegedExceptionAction() {
00389           public Object run() throws BundleException {
00390             b.update0(in, wasActive);
00391             return null;
00392           }
00393         });
00394     } catch (PrivilegedActionException e) {
00395       throw (BundleException) e.getException();
00396     }
00397   }
00398 
00399 
00400   void callUninstall0(final BundleImpl b) {
00401     AccessController.doPrivileged(new PrivilegedAction() {
00402         public Object run() {
00403           b.uninstall0();
00404           return null;
00405         }
00406       });
00407   }
00408 
00409 
00410   void callStartOnLaunch(final BundleImpl b, final boolean flag) {
00411     AccessController.doPrivileged(new PrivilegedAction() {
00412         public Object run() {
00413           b.startOnLaunch(flag);
00414           return null;
00415         }
00416       });
00417   }
00418 
00419 
00420   void callSetPersistent(final BundleImpl b, final boolean flag) {
00421     AccessController.doPrivileged(new PrivilegedAction() {
00422         public Object run() {
00423           b.setPersistent(flag);
00424           return null;
00425         }
00426       });
00427   }
00428 
00429 
00430   ClassLoader callGetClassLoader0(final BundleImpl b) {
00431     return (ClassLoader)
00432       AccessController.doPrivileged(new PrivilegedAction() {
00433           public Object run() {
00434             return b.getClassLoader0();
00435           }
00436         });
00437   }
00438 
00439 
00440   HeaderDictionary callGetHeaders0(final BundleImpl b, final String locale) {
00441     return (HeaderDictionary)
00442       AccessController.doPrivileged(new PrivilegedAction() {
00443           public Object run() {
00444             return b.getHeaders0(locale);
00445           }
00446         });
00447   }
00448 
00449 
00450   Enumeration callFindEntries0(final BundleImpl b, final String path,
00451                                final String filePattern, final boolean recurse) {
00452     return (Enumeration)
00453       AccessController.doPrivileged(new PrivilegedAction() {
00454           public Object run() {
00455             return b.findEntries0(path, filePattern, recurse);
00456           }
00457         });
00458   }
00459 
00460   //
00461   // Bundles Secure operation
00462   //
00463 
00464   BundleImpl callInstall0(final Bundles bs, final String location, final InputStream in)
00465     throws BundleException {
00466     try {
00467       final AccessControlContext acc = AccessController.getContext();
00468       return (BundleImpl)
00469         AccessController.doPrivileged(new PrivilegedExceptionAction() {
00470             public Object run() throws BundleException {
00471               return bs.install0(location, in, acc);
00472             }
00473           });
00474     } catch (PrivilegedActionException e) {
00475       throw (BundleException) e.getException();
00476     }
00477   }
00478 
00479   //
00480   // Listeners Secure operations
00481   //
00482 
00483   void callBundleChanged(final BundleListener bl, final BundleEvent evt) {
00484     AccessController.doPrivileged(new PrivilegedAction() {
00485         public Object run() {
00486           bl.bundleChanged(evt);
00487           return null;
00488         }
00489       });
00490   }
00491 
00492 
00493   void callFrameworkEvent(final FrameworkListener fl, final FrameworkEvent evt) {
00494     AccessController.doPrivileged(new PrivilegedAction() {
00495         public Object run() {
00496           fl.frameworkEvent(evt);
00497           return null;
00498         }
00499       });
00500   }
00501 
00502 
00503   void callServiceChanged(final ServiceListener sl, final ServiceEvent evt) {
00504     AccessController.doPrivileged(new PrivilegedAction() {
00505         public Object run() {
00506           sl.serviceChanged(evt);
00507           return null;
00508         }
00509       });
00510   }
00511 
00512   //
00513   // Main Secure operations
00514   //
00515 
00516   void callMainRestart() {
00517     AccessController.doPrivileged(new PrivilegedAction() {
00518         public Object run() {
00519           Main.restart();
00520           return null;
00521         }
00522       });
00523   }
00524 
00525   void callMainShutdown(final int exitcode) {
00526     AccessController.doPrivileged(new PrivilegedAction() {
00527         public Object run() {
00528           Main.shutdown(exitcode);
00529           return null;
00530         }
00531       });
00532   }
00533 
00534   //
00535   // PackageAdmin secure operations
00536   //
00537 
00538   void callRefreshPackages0(final PackageAdminImpl pa, final Bundle [] bundles) {
00539     AccessController.doPrivileged(new PrivilegedAction() {
00540         public Object run() {
00541           pa.refreshPackages0(bundles);
00542           return null;
00543         }
00544       });
00545   }
00546 
00547   //
00548   // ServiceReferenceImpl secure operations
00549   //
00550 
00551   Object callGetService(final ServiceFactory sf,
00552                         final Bundle b,
00553                         final ServiceRegistration sr) {
00554     return
00555       AccessController.doPrivileged(new PrivilegedAction() {
00556           public Object run() {
00557             return sf.getService(b, sr);
00558           }
00559         });
00560   }
00561 
00562   //
00563   // ServiceRegisterationImpl secure operations
00564   //
00565 
00566   void callUnregister0(final ServiceRegistrationImpl sr) {
00567     AccessController.doPrivileged(new PrivilegedAction() {
00568         public Object run() {
00569           sr.unregister0();
00570           return null;
00571         }
00572       });
00573   }
00574 
00575   //
00576   // Permissions package functionality
00577   //
00578 
00582   ProtectionDomain getProtectionDomain(BundleImpl b) {
00583     try {
00584       String h = Long.toString(b.id) + "." + Long.toString(b.generation);
00585       URL bundleUrl = new URL(BundleURLStreamHandler.PROTOCOL, h, "");
00586       InputStream pis = b.archive.getInputStream("OSGI-INF/permissions.perm", 0);
00587       PermissionCollection pc = ph.createPermissionCollection(b.location, b, pis);
00588       return new ProtectionDomain(new CodeSource(bundleUrl, (Certificate[])null), pc);
00589     } catch (MalformedURLException _ignore) { }
00590     return null;
00591   }
00592 
00593   //
00594   // Cleaning
00595   //
00596 
00600   void purge(BundleImpl b, ProtectionDomain pd) {
00601     if (ph.purgePermissionCollection(new Long(b.id), pd.getPermissions())) {
00602       adminPerms.remove(b);
00603     }
00604   }
00605 
00606   //
00607   // Private
00608   //
00609 
00610  
00611   AdminPermission getAdminPermission(Bundle b, int ti) {
00612     AdminPermission [] res;
00613     res = (AdminPermission [])adminPerms.get(b);
00614     if (res != null) {
00615       if (res[ti] != null) {
00616         return res[ti];
00617       }
00618     } else {
00619       res = new AdminPermission [AP_MAX];
00620       adminPerms.put(b, res);
00621     }
00622     res[ti] = new AdminPermission(b, AP_TO_STRING[ti]);
00623     return res[ti];
00624   } 
00625    
00626 }

Generated on Mon Jan 11 21:19:16 2010 for OpenMobileIS by  doxygen 1.5.4