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();
}
}