Thought you might like an example of a Security Delegate.

NB. In Pepe, I've replaced the ExecutionContextManager, with an InternetSecurityManager.

The InternetSecurityManager does the following:

   * Caches AccessControlContext.checkPermission(perm) results, for
     fast repeated permission checks, this will also speed up ordinary
     permission checks.
   * Checks ProtectionDomains in an execution context for a
     DelegatePermission or a Permission contained by the
     DelegatePermission, so privileged ProtectionDomains on the stack
     are considered to have a DelegatePermission, if they have the
     Permission the delegate represents or contains.

A Service (with smart proxy) doesn't change the Permission's it requires, if a client can authenticate it, but doesn't trust it much, or wants to trial trust, it grants it DelegatePermission's containing the requested Permission's.

Note: in the Security Delegate below, I can't extend java.io.FileInputStream, since this would pose a security risk, if java.io.FileInputStream was given new methods in the next version of Java, those methods would be unprotected, therefore it must encapsulate java.io.FileInputStream and extend InputStream, this means it can't be directly substituted for FileInputStream. This is a good example of why it can be important to separate implementation from API using interfaces or abstract classes.

The Security Delegate reference is allowed to escape into untrusted code, without that code being able to exploit it, the use of SecurityDelegate's would make code easier to secure, since escaped references wouldn't be a concern.

The Guard is used as per Li Gong's suggestion on page 176 of Inside Java 2 Platform Security, Second Edition ISBN:0201787911

Peter.

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.river.api.delegates;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FilePermission;
import java.io.IOException;
import java.security.AccessController;
import java.security.Guard;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import org.apache.river.api.security.DelegatePermission;
import sun.security.util.SecurityConstants;

/**
*
* @author Peter Firmstone
*/
public class FileInputStream extends java.io.InputStream {
   private final Guard g;
   private final java.io.FileInputStream in;
public FileInputStream(final String name) throws FileNotFoundException, Throwable{
   try {
       // Permission check is delayed.
g = new DelegatePermission(new FilePermission(name, SecurityConstants.FILE_READ_ACTION)); in = AccessController.doPrivileged(new PrivilegedExceptionAction<java.io.FileInputStream>() {

       public java.io.FileInputStream run() throws FileNotFoundException {
           return new java.io.FileInputStream(name);
       }
       });
   } catch (PrivilegedActionException ex) {
       throw ex.getCause();
   }
   }
public FileInputStream(final File file) throws FileNotFoundException, Throwable{
   try {
       // If we get here the path is not null.
g = new DelegatePermission(new FilePermission(file.getPath(), SecurityConstants.FILE_READ_ACTION)); in = AccessController.doPrivileged(new PrivilegedExceptionAction<java.io.FileInputStream>() {

       public java.io.FileInputStream run() throws FileNotFoundException {
           return new java.io.FileInputStream(file);
       }
       });
   } catch (PrivilegedActionException ex) {
       throw ex.getCause();
   }
   }
   public FileInputStream(final FileDescriptor fdObj) {
   g = new DelegatePermission(new RuntimePermission("readFileDescriptor"));
in = AccessController.doPrivileged(new PrivilegedAction<java.io.FileInputStream>() {
       public java.io.FileInputStream run() {
       return new java.io.FileInputStream(fdObj);
       }
   });
   }

   @Override
   public int read() throws IOException {
   g.checkGuard(this);
   return in.read();
   }
@Override
   public int read(byte b[]) throws IOException {
   g.checkGuard(this);
   return in.read(b);
   }
@Override
   public int read(byte b[], int off, int len) throws IOException {
   g.checkGuard(this);
   return in.read(b, off, len);
   }
@Override
   public long skip(long n) throws IOException {
   g.checkGuard(this);
   return in.skip(n);
   }
@Override
   public int available() throws IOException {
   g.checkGuard(this);
   return in.available();
   }
}

Reply via email to