00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
00194 }
00195 }
00196 return res;
00197 } catch (IOException e) {
00198
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
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 }