com.atlassian.bamboo.specs.maven.sandbox.LowPrivilegeThreadPermissionVerifier Maven / Gradle / Ivy
package com.atlassian.bamboo.specs.maven.sandbox;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
import java.nio.file.Path;
import java.security.Permission;
import java.util.PropertyPermission;
/**
* A permission checker with very limited set of allowed permissions.
*/
public class LowPrivilegeThreadPermissionVerifier extends AbstractThreadPermissionVerifier {
private final String allowedReadDirectory;
private final String allowedReadWriteDirectory;
/**
* Permission verifier.
* @param allowedReadDirectory read access will be restricted to this directory.
* @param allowedReadWriteDirectory write access will be restricted to this directory.
*/
public LowPrivilegeThreadPermissionVerifier(
@Nullable final Path allowedReadDirectory,
@Nullable final Path allowedReadWriteDirectory) {
try {
this.allowedReadDirectory = allowedReadDirectory!=null ? toCanonicalPath(allowedReadDirectory.toString()) : null;
this.allowedReadWriteDirectory = allowedReadWriteDirectory!=null ? toCanonicalPath(allowedReadWriteDirectory.toString()) : null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean checkPermissionFor(final Permission perm) {
//we need to be able to load classes in low privilege mode
final boolean allowedFileAccess = isAllowedFileAccess(perm);
return allowedFileAccess || isPropertyAccess(perm);
}
private static boolean isPropertyAccess(final Permission perm) {
if (!(perm instanceof PropertyPermission)) {
return false;
}
final PropertyPermission propertyPermission = (PropertyPermission) perm;
return propertyPermission.getActions().equals("read");
}
private boolean isAllowedFileAccess(final Permission perm) {
if (!(perm instanceof FilePermission)) {
return false;
}
final FilePermission filePermission = (FilePermission) perm;
final String fileName;
try {
fileName = toCanonicalPath(filePermission.getName());
} catch (IOException e) {
return false;
}
final boolean isWriteRequested = filePermission.getActions().equals("write");
if (isWriteRequested) {
return allowedReadWriteDirectory != null && fileName.startsWith(allowedReadWriteDirectory);
}
final boolean isReadRequested = filePermission.getActions().equals("read");
if (!isReadRequested) {
return false;
}
if (fileName.endsWith(".class") || fileName.endsWith(".jar")) {
return true;
}
if (allowedReadDirectory != null && fileName.startsWith(allowedReadDirectory)) {
return true;
}
if (allowedReadWriteDirectory != null && fileName.startsWith(allowedReadWriteDirectory)) {
return true;
}
return false;
}
private static String toCanonicalPath(final String pathString) throws IOException {
return new File(pathString).getCanonicalPath();
}
@Nullable
private static String toAbsolutePath(@Nullable final Path path) {
return path!=null ? path.toAbsolutePath().toString() : null;
}
}