PermissionsWrapper.java

00001 /*
00002  * Copyright (c) 2003-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.permissions;
00036 
00037 import java.io.*;
00038 import java.lang.reflect.*;
00039 import java.security.*;
00040 import java.util.*;
00041 
00042 import org.osgi.framework.Bundle;
00043 import org.osgi.framework.AdminPermission;
00044 import org.osgi.service.permissionadmin.*;
00045 
00046 import org.knopflerfish.framework.Framework;
00047 
00048 
00056 public class PermissionsWrapper extends PermissionCollection {
00057   private static final long serialVersionUID = 1L;
00058   
00059   String location;
00060 
00061   private PermissionInfoStorage pinfos;
00062   private PermissionCollection implicitPermissions;
00063   private PermissionCollection localPermissions;
00064   private PermissionCollection systemPermissions;
00065   private File dataRoot;
00066   private boolean readOnly = false;
00067   
00068 
00069   PermissionsWrapper(Framework fw,
00070                      PermissionInfoStorage pis,
00071                      String loc,
00072                      Bundle b,
00073                      InputStream localPerms) {
00074     pinfos = pis;
00075     location = loc;
00076     dataRoot = fw.getDataStorage(b.getBundleId());
00077     if (localPerms != null) {
00078       localPermissions = makeLocalPermissionCollection(localPerms);
00079     } else {
00080       localPermissions = null;
00081     }
00082     implicitPermissions = makeImplicitPermissionCollection(fw, b);
00083     systemPermissions = makePermissionCollection();
00084   }
00085 
00086 
00087   public void add(Permission permission) {
00088     getPerms().add(permission);
00089   }
00090 
00091     
00092   public Enumeration elements() {
00093     return new Enumeration() {
00094         private Enumeration implicitElements = implicitPermissions.elements();
00095         private Enumeration systemElements = getPerms().elements();
00096 
00097         public boolean hasMoreElements() {
00098           if (implicitElements != null) {
00099             if (implicitElements.hasMoreElements()) {
00100               return true;
00101             }
00102             implicitElements = null;
00103           }
00104           return systemElements.hasMoreElements();
00105         }
00106             
00107 
00108         public Object nextElement() {
00109           if (implicitElements != null) {
00110             try {
00111               return implicitElements.nextElement();
00112             } catch (NoSuchElementException _ignore) { }
00113             implicitElements = null;
00114           }
00115           return systemElements.nextElement();
00116         }
00117       };
00118   }
00119 
00120 
00121   public boolean implies(Permission permission) {
00122     if (implicitPermissions.implies(permission)) {
00123       return true;
00124     } else if (localPermissions != null && !localPermissions.implies(permission)) {
00125       return false;
00126     } else {
00127       return getPerms().implies(permission);
00128     }
00129   }
00130 
00131 
00132   public boolean isReadOnly() {
00133     return readOnly;
00134   }
00135 
00136 
00137   public void setReadOnly() {
00138     if (!readOnly) {
00139       readOnly = true;
00140       getPerms().setReadOnly();
00141     }
00142   }
00143 
00144 
00145   synchronized void invalidate() {
00146     systemPermissions = null;
00147   }
00148 
00149 
00150   synchronized void updateLocalPermissions(InputStream localPerms) {
00151     if (localPerms != null) {
00152       localPermissions = makeLocalPermissionCollection(localPerms);
00153     } else {
00154       localPermissions = null;
00155     }
00156   }
00157 
00158 
00159   private PermissionCollection getPerms() {
00160     PermissionCollection p = systemPermissions;
00161     if (p == null) {
00162       synchronized (this) {
00163         p = systemPermissions;
00164         if (p == null) {
00165           p = makePermissionCollection();
00166           if (readOnly) {
00167             p.setReadOnly();
00168           }
00169           systemPermissions = p;
00170         }
00171       }
00172     }
00173     return p;
00174   }
00175 
00176 
00177   private PermissionCollection makeLocalPermissionCollection(InputStream localPerms) {
00178     try {
00179       DataInputStream dis = new DataInputStream(localPerms);
00180       String l;
00181       Permissions res = new Permissions();
00182       while ((l = dis.readLine()) != null) {
00183         l = l.trim();
00184         if (l.startsWith("#") || l.startsWith("//") || l.length() == 0) {
00185           continue;
00186         }
00187         try {
00188           Permission p = makePermission(new PermissionInfo(l), false);
00189           if (p != null) {
00190             res.add(p);
00191           }
00192         } catch (Exception e) {
00193           // TODO, handle this error
00194         }
00195       }
00196       return res;
00197     } catch (IOException e) {
00198       // TODO, handle this error
00199       return null;
00200     } finally {
00201       try {
00202         localPerms.close();
00203       } catch (IOException _ignore) { }
00204     }
00205   }
00206 
00207 
00208   private PermissionCollection makeImplicitPermissionCollection(Framework fw, Bundle b) {
00209     Permissions pc = new Permissions();
00210     if (dataRoot != null) {
00211       pc.add(new FilePermission(dataRoot.getPath(), "read,write"));
00212       pc.add(new FilePermission((new File(dataRoot, "-")).getPath(),
00213                                 "read,write,delete"));
00214     }
00215     pc.add(new AdminPermission(b,
00216                                AdminPermission.RESOURCE + "," +
00217                                AdminPermission.METADATA + "," +
00218                                AdminPermission.CLASS));
00219     return pc;
00220   }
00221 
00222 
00236   private PermissionCollection makePermissionCollection() {
00237     PermissionInfo[] pi = pinfos.get(location, this);
00238     boolean usingDefault;
00239     if (pi == null) {
00240       pi = pinfos.getDefault(this);
00241       usingDefault = true;
00242     } else {
00243       usingDefault = false;
00244     }
00245     Permissions res = new Permissions();
00246     for (int i = pi.length - 1; i >= 0; i--) {
00247       Permission p = makePermission(pi[i], usingDefault);
00248       if (p != null) {
00249         res.add(p);
00250       }
00251     }
00252     return res;
00253   }
00254 
00255 
00262   private Permission makePermission(PermissionInfo pi, boolean usingDefault) {
00263     String a = pi.getActions();
00264     String n = pi.getName();
00265     String t = pi.getType();
00266     try {
00267       Class pc = Class.forName(t);
00268       Constructor c = pc.getConstructor(new Class[] { String.class, String.class });
00269       if (FilePermission.class.equals(pc)) {
00270         File f = new File(n);
00271         // NYI! How should we handle different seperator chars.
00272         if (!f.isAbsolute()) {
00273           if (usingDefault) {
00274             return null;
00275           }
00276           f = new File(dataRoot, n);
00277         }
00278         n = f.getPath();
00279       }
00280       return (Permission) c.newInstance(new Object[] { n, a });
00281     } catch (ClassNotFoundException e) {
00282       return new UnresolvedPermission(t, n, a, null);
00283     } catch (NoSuchMethodException ignore) {
00284     } catch (InstantiationException ignore) {
00285     } catch (IllegalAccessException ignore) {
00286     } catch (InvocationTargetException ignore) {
00287     }
00288     return null;
00289   }
00290 }

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