Ban write access to system properties
* Forbid System.setProperties & co in forbidden APIs. * Ban property write access at runtime with security manager. Plugins that need to modify system properties will need to request permission in their plugin-security.policy
This commit is contained in:
parent
335e7fca24
commit
30529c008d
|
@ -105,3 +105,10 @@ java.lang.Thread#getAllStackTraces()
|
|||
java.lang.System#exit(int)
|
||||
java.lang.Runtime#exit(int)
|
||||
java.lang.Runtime#halt(int)
|
||||
|
||||
@defaultMessage Treat system properties as immutable
|
||||
java.lang.System#setProperties(java.util.Properties)
|
||||
java.lang.System#setProperty(java.lang.String,java.lang.String)
|
||||
java.lang.System#clearProperty(java.lang.String)
|
||||
java.lang.System#getProperties() @ Use BootstrapInfo.getSystemProperties for a read-only view
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ final class Bootstrap {
|
|||
// Force probes to be loaded
|
||||
ProcessProbe.getInstance();
|
||||
OsProbe.getInstance();
|
||||
JvmInfo.jvmInfo();
|
||||
}
|
||||
|
||||
private void setup(boolean addShutdownHook, Settings settings, Environment environment) throws Exception {
|
||||
|
@ -230,13 +231,20 @@ final class Bootstrap {
|
|||
}
|
||||
}
|
||||
|
||||
/** Set the system property before anything has a chance to trigger its use */
|
||||
// TODO: why? is it just a bad default somewhere? or is it some BS around 'but the client' garbage <-- my guess
|
||||
@SuppressForbidden(reason = "sets logger prefix on initialization")
|
||||
static void initLoggerPrefix() {
|
||||
System.setProperty("es.logger.prefix", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked by {@link Elasticsearch#main(String[])}
|
||||
* to startup elasticsearch.
|
||||
*/
|
||||
static void init(String[] args) throws Throwable {
|
||||
// Set the system property before anything has a chance to trigger its use
|
||||
System.setProperty("es.logger.prefix", "");
|
||||
initLoggerPrefix();
|
||||
|
||||
BootstrapCLIParser bootstrapCLIParser = new BootstrapCLIParser();
|
||||
CliTool.ExitStatus status = bootstrapCLIParser.execute(args);
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.commons.cli.CommandLine;
|
|||
import org.apache.commons.cli.Option;
|
||||
import org.elasticsearch.Build;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.cli.CliTool;
|
||||
import org.elasticsearch.common.cli.CliToolConfig;
|
||||
import org.elasticsearch.common.cli.Terminal;
|
||||
|
@ -100,6 +101,8 @@ final class BootstrapCLIParser extends CliTool {
|
|||
.stopAtNonOption(true) // needed to parse the --foo.bar options, so this parser must be lenient
|
||||
.build();
|
||||
|
||||
// TODO: don't use system properties as a way to do this, its horrible...
|
||||
@SuppressForbidden(reason = "Sets system properties passed as CLI parameters")
|
||||
public static Command parse(Terminal terminal, CommandLine cli) {
|
||||
if (cli.hasOption("V")) {
|
||||
return Version.parse(terminal, cli);
|
||||
|
|
|
@ -19,9 +19,15 @@
|
|||
|
||||
package org.elasticsearch.bootstrap;
|
||||
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* Exposes system startup information
|
||||
*/
|
||||
@SuppressForbidden(reason = "exposes read-only view of system properties")
|
||||
public final class BootstrapInfo {
|
||||
|
||||
/** no instantiation */
|
||||
|
@ -57,4 +63,61 @@ public final class BootstrapInfo {
|
|||
* This is not a full URL, just a path.
|
||||
*/
|
||||
public static final String UNTRUSTED_CODEBASE = "/untrusted";
|
||||
|
||||
// create a view of sysprops map that does not allow modifications
|
||||
// this must be done this way (e.g. versus an actual typed map), because
|
||||
// some test methods still change properties, so whitelisted changes must
|
||||
// be reflected in this this view.
|
||||
private static final Dictionary<Object,Object> SYSTEM_PROPERTIES;
|
||||
static {
|
||||
final Dictionary<Object,Object> sysprops = System.getProperties();
|
||||
SYSTEM_PROPERTIES = new Dictionary<Object,Object>() {
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return sysprops.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return sysprops.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<Object> keys() {
|
||||
return sysprops.keys();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<Object> elements() {
|
||||
return sysprops.elements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
return sysprops.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object put(Object key, Object value) {
|
||||
throw new UnsupportedOperationException("treat system properties as immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object remove(Object key) {
|
||||
throw new UnsupportedOperationException("treat system properties as immutable");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a read-only view of all system properties
|
||||
*/
|
||||
public static Dictionary<Object,Object> getSystemProperties() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPropertyAccess("*");
|
||||
}
|
||||
return SYSTEM_PROPERTIES;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.common.logging.log4j;
|
|||
|
||||
import org.apache.log4j.PropertyConfigurator;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.bootstrap.BootstrapInfo;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsException;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
@ -106,8 +107,8 @@ public class LogConfigurator {
|
|||
resolveConfig(environment, settingsBuilder);
|
||||
}
|
||||
settingsBuilder
|
||||
.putProperties("elasticsearch.", System.getProperties())
|
||||
.putProperties("es.", System.getProperties());
|
||||
.putProperties("elasticsearch.", BootstrapInfo.getSystemProperties())
|
||||
.putProperties("es.", BootstrapInfo.getSystemProperties());
|
||||
// add custom settings after config was added so that they are not overwritten by config
|
||||
settingsBuilder.put(settings);
|
||||
settingsBuilder.replacePropertyPlaceholders();
|
||||
|
|
|
@ -46,13 +46,14 @@ import java.nio.file.Path;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Dictionary;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
@ -1028,9 +1029,9 @@ public final class Settings implements ToXContent {
|
|||
/**
|
||||
* Sets all the provided settings.
|
||||
*/
|
||||
public Builder put(Properties properties) {
|
||||
for (Map.Entry entry : properties.entrySet()) {
|
||||
map.put((String) entry.getKey(), (String) entry.getValue());
|
||||
public Builder put(Dictionary<Object,Object> properties) {
|
||||
for (Object key : Collections.list(properties.keys())) {
|
||||
map.put(Objects.toString(key), Objects.toString(properties.get(key)));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -1096,10 +1097,10 @@ public final class Settings implements ToXContent {
|
|||
* @param properties The properties to put
|
||||
* @return The builder
|
||||
*/
|
||||
public Builder putProperties(String prefix, Properties properties) {
|
||||
for (Object key1 : properties.keySet()) {
|
||||
String key = (String) key1;
|
||||
String value = properties.getProperty(key);
|
||||
public Builder putProperties(String prefix, Dictionary<Object,Object> properties) {
|
||||
for (Object key1 : Collections.list(properties.keys())) {
|
||||
String key = Objects.toString(key1);
|
||||
String value = Objects.toString(properties.get(key));
|
||||
if (key.startsWith(prefix)) {
|
||||
map.put(key.substring(prefix.length()), value);
|
||||
}
|
||||
|
@ -1114,10 +1115,10 @@ public final class Settings implements ToXContent {
|
|||
* @param properties The properties to put
|
||||
* @return The builder
|
||||
*/
|
||||
public Builder putProperties(String prefix, Properties properties, String[] ignorePrefixes) {
|
||||
for (Object key1 : properties.keySet()) {
|
||||
String key = (String) key1;
|
||||
String value = properties.getProperty(key);
|
||||
public Builder putProperties(String prefix, Dictionary<Object,Object> properties, String[] ignorePrefixes) {
|
||||
for (Object key1 : Collections.list(properties.keys())) {
|
||||
String key = Objects.toString(key1);
|
||||
String value = Objects.toString(properties.get(key));
|
||||
if (key.startsWith(prefix)) {
|
||||
boolean ignore = false;
|
||||
for (String ignorePrefix : ignorePrefixes) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.http.netty;
|
||||
|
||||
import org.elasticsearch.common.Booleans;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.netty.NettyUtils;
|
||||
|
@ -138,6 +139,8 @@ public class NettyHttpServerTransport extends AbstractLifecycleComponent<HttpSer
|
|||
protected volatile HttpServerAdapter httpServerAdapter;
|
||||
|
||||
@Inject
|
||||
@SuppressForbidden(reason = "sets org.jboss.netty.epollBugWorkaround based on netty.epollBugWorkaround")
|
||||
// TODO: why be confusing like this? just let the user do it with the netty parameter instead!
|
||||
public NettyHttpServerTransport(Settings settings, NetworkService networkService, BigArrays bigArrays) {
|
||||
super(settings);
|
||||
this.networkService = networkService;
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.elasticsearch.common.xcontent.XContentBuilderString;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.lang.management.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -57,7 +58,7 @@ public class JvmInfo implements Streamable, ToXContent {
|
|||
JvmInfo info = new JvmInfo();
|
||||
info.pid = pid;
|
||||
info.startTime = runtimeMXBean.getStartTime();
|
||||
info.version = runtimeMXBean.getSystemProperties().get("java.version");
|
||||
info.version = System.getProperty("java.version");
|
||||
info.vmName = runtimeMXBean.getVmName();
|
||||
info.vmVendor = runtimeMXBean.getVmVendor();
|
||||
info.vmVersion = runtimeMXBean.getVmVersion();
|
||||
|
@ -84,7 +85,7 @@ public class JvmInfo implements Streamable, ToXContent {
|
|||
}
|
||||
}
|
||||
info.classPath = runtimeMXBean.getClassPath();
|
||||
info.systemProperties = runtimeMXBean.getSystemProperties();
|
||||
info.systemProperties = Collections.unmodifiableMap(runtimeMXBean.getSystemProperties());
|
||||
|
||||
List<GarbageCollectorMXBean> gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans();
|
||||
info.gcCollectors = new String[gcMxBeans.size()];
|
||||
|
@ -104,6 +105,11 @@ public class JvmInfo implements Streamable, ToXContent {
|
|||
}
|
||||
|
||||
public static JvmInfo jvmInfo() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new ManagementPermission("monitor"));
|
||||
sm.checkPropertyAccess("*");
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
package org.elasticsearch.node.internal;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.elasticsearch.bootstrap.BootstrapInfo;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.common.Booleans;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
@ -125,11 +127,11 @@ public class InternalSettingsPreparer {
|
|||
if (useSystemProperties(input)) {
|
||||
if (loadDefaults) {
|
||||
for (String prefix : PROPERTY_DEFAULTS_PREFIXES) {
|
||||
output.putProperties(prefix, System.getProperties());
|
||||
output.putProperties(prefix, BootstrapInfo.getSystemProperties());
|
||||
}
|
||||
}
|
||||
for (String prefix : PROPERTY_PREFIXES) {
|
||||
output.putProperties(prefix, System.getProperties(), PROPERTY_DEFAULTS_PREFIXES);
|
||||
output.putProperties(prefix, BootstrapInfo.getSystemProperties(), PROPERTY_DEFAULTS_PREFIXES);
|
||||
}
|
||||
}
|
||||
output.replacePropertyPlaceholders();
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.Version;
|
|||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.common.Booleans;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.bytes.ReleasablePagedBytesReference;
|
||||
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||
import org.elasticsearch.common.compress.CompressorFactory;
|
||||
|
@ -205,6 +206,8 @@ public class NettyTransport extends AbstractLifecycleComponent<Transport> implem
|
|||
final ScheduledPing scheduledPing;
|
||||
|
||||
@Inject
|
||||
@SuppressForbidden(reason = "sets org.jboss.netty.epollBugWorkaround based on netty.epollBugWorkaround")
|
||||
// TODO: why be confusing like this? just let the user do it with the netty parameter instead!
|
||||
public NettyTransport(Settings settings, ThreadPool threadPool, NetworkService networkService, BigArrays bigArrays, Version version, NamedWriteableRegistry namedWriteableRegistry) {
|
||||
super(settings);
|
||||
this.threadPool = threadPool;
|
||||
|
|
|
@ -48,8 +48,37 @@ grant {
|
|||
// Allow connecting to the internet anywhere
|
||||
permission java.net.SocketPermission "*", "accept,connect,resolve";
|
||||
|
||||
// Allow read/write to all system properties
|
||||
permission java.util.PropertyPermission "*", "read,write";
|
||||
// Allow read access to all system properties
|
||||
permission java.util.PropertyPermission "*", "read";
|
||||
|
||||
// TODO: clean all these property writes up, and don't allow any more in. these are all bogus!
|
||||
|
||||
// LuceneTestCase randomization (locale/timezone/cpus/ssd)
|
||||
// TODO: put these in doPrivileged and move these to test-framework.policy
|
||||
permission java.util.PropertyPermission "user.language", "write";
|
||||
permission java.util.PropertyPermission "user.timezone", "write";
|
||||
permission java.util.PropertyPermission "lucene.cms.override_core_count", "write";
|
||||
permission java.util.PropertyPermission "lucene.cms.override_spins", "write";
|
||||
// messiness in LuceneTestCase: do the above, or clean this up, or simply allow to fail if its denied
|
||||
permission java.util.PropertyPermission "solr.solr.home", "write";
|
||||
permission java.util.PropertyPermission "solr.data.dir", "write";
|
||||
permission java.util.PropertyPermission "solr.directoryFactory", "write";
|
||||
|
||||
// set by ESTestCase to improve test reproducibility
|
||||
// TODO: set this with gradle or some other way that repros with seed?
|
||||
permission java.util.PropertyPermission "es.processors.override", "write";
|
||||
// set by CLIToolTestCase
|
||||
// TODO: do this differently? or test commandline tools differently?
|
||||
permission java.util.PropertyPermission "es.default.path.home", "write";
|
||||
|
||||
// TODO: these simply trigger a noisy warning if its unable to clear the properties
|
||||
// fix that in randomizedtesting
|
||||
permission java.util.PropertyPermission "junit4.childvm.count", "write";
|
||||
permission java.util.PropertyPermission "junit4.childvm.id", "write";
|
||||
|
||||
// set by NettyTransport/NettyHttpServerTransport based on another parameter
|
||||
// TODO: look into this and decide if users should simply set the actual sysprop?!
|
||||
permission java.util.PropertyPermission "org.jboss.netty.epollBugWorkaround", "write";
|
||||
|
||||
// needed by lucene SPI currently
|
||||
permission java.lang.RuntimePermission "getClassLoader";
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.action.bulk.BulkRequestBuilder;
|
|||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.bootstrap.BootstrapForTesting;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
@ -36,6 +37,7 @@ import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
|
|||
|
||||
/**
|
||||
*/
|
||||
@SuppressForbidden(reason = "not really source code or a test")
|
||||
public class ManyMappingsBenchmark {
|
||||
|
||||
private static final String MAPPING = "{\n" +
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
|
||||
package org.elasticsearch.benchmark.monitor.os;
|
||||
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.logging.ESLoggerFactory;
|
||||
import org.elasticsearch.monitor.os.OsProbe;
|
||||
|
||||
@SuppressForbidden(reason = "not really source code or a test")
|
||||
public class OsProbeBenchmark {
|
||||
|
||||
private static final int ITERATIONS = 100_000;
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.bootstrap.BootstrapForTesting;
|
|||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.logging.ESLoggerFactory;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
@ -46,6 +47,7 @@ import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
@SuppressForbidden(reason = "not really source code or a test")
|
||||
public class ReplicaRecoveryBenchmark {
|
||||
|
||||
private static final String INDEX_NAME = "index";
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.elasticsearch.action.search.SearchResponse;
|
|||
import org.elasticsearch.benchmark.search.aggregations.TermsAggregationSearchBenchmark.StatsResult;
|
||||
import org.elasticsearch.bootstrap.BootstrapForTesting;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.ByteSizeValue;
|
||||
import org.elasticsearch.common.unit.SizeValue;
|
||||
|
@ -51,6 +52,7 @@ import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
@SuppressForbidden(reason = "not really source code or a test")
|
||||
public class GlobalOrdinalsBenchmark {
|
||||
|
||||
private static final String INDEX_NAME = "index";
|
||||
|
|
|
@ -74,18 +74,6 @@ public class JarHellTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testBootclasspathLeniency() throws Exception {
|
||||
Path dir = createTempDir();
|
||||
String previousJavaHome = System.getProperty("java.home");
|
||||
System.setProperty("java.home", dir.toString());
|
||||
URL[] jars = {makeJar(dir, "foo.jar", null, "DuplicateClass.class"), makeJar(dir, "bar.jar", null, "DuplicateClass.class")};
|
||||
try {
|
||||
JarHell.checkJarHell(jars);
|
||||
} finally {
|
||||
System.setProperty("java.home", previousJavaHome);
|
||||
}
|
||||
}
|
||||
|
||||
public void testDuplicateClasspathLeniency() throws Exception {
|
||||
Path dir = createTempDir();
|
||||
URL jar = makeJar(dir, "foo.jar", null, "Foo.class");
|
||||
|
@ -179,40 +167,6 @@ public class JarHellTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testRequiredJDKVersionIsOK() throws Exception {
|
||||
Path dir = createTempDir();
|
||||
String previousJavaVersion = System.getProperty("java.specification.version");
|
||||
System.setProperty("java.specification.version", "1.7");
|
||||
|
||||
Manifest manifest = new Manifest();
|
||||
Attributes attributes = manifest.getMainAttributes();
|
||||
attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
|
||||
attributes.put(new Attributes.Name("X-Compile-Target-JDK"), "1.7");
|
||||
URL[] jars = {makeJar(dir, "foo.jar", manifest, "Foo.class")};
|
||||
try {
|
||||
JarHell.checkJarHell(jars);
|
||||
} finally {
|
||||
System.setProperty("java.specification.version", previousJavaVersion);
|
||||
}
|
||||
}
|
||||
|
||||
public void testBadJDKVersionProperty() throws Exception {
|
||||
Path dir = createTempDir();
|
||||
String previousJavaVersion = System.getProperty("java.specification.version");
|
||||
System.setProperty("java.specification.version", "bogus");
|
||||
|
||||
Manifest manifest = new Manifest();
|
||||
Attributes attributes = manifest.getMainAttributes();
|
||||
attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
|
||||
attributes.put(new Attributes.Name("X-Compile-Target-JDK"), "1.7");
|
||||
URL[] jars = {makeJar(dir, "foo.jar", manifest, "Foo.class")};
|
||||
try {
|
||||
JarHell.checkJarHell(jars);
|
||||
} finally {
|
||||
System.setProperty("java.specification.version", previousJavaVersion);
|
||||
}
|
||||
}
|
||||
|
||||
public void testBadJDKVersionInJar() throws Exception {
|
||||
Path dir = createTempDir();
|
||||
Manifest manifest = new Manifest();
|
||||
|
|
|
@ -19,119 +19,14 @@
|
|||
|
||||
package org.elasticsearch.bootstrap;
|
||||
|
||||
import org.apache.lucene.util.Constants;
|
||||
import org.elasticsearch.common.io.PathUtils;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.FilePermission;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Permissions;
|
||||
import java.util.Set;
|
||||
|
||||
public class SecurityTests extends ESTestCase {
|
||||
|
||||
/** test generated permissions */
|
||||
public void testGeneratedPermissions() throws Exception {
|
||||
Path path = createTempDir();
|
||||
// make a fake ES home and ensure we only grant permissions to that.
|
||||
Path esHome = path.resolve("esHome");
|
||||
Settings.Builder settingsBuilder = Settings.builder();
|
||||
settingsBuilder.put("path.home", esHome.toString());
|
||||
Settings settings = settingsBuilder.build();
|
||||
|
||||
Path fakeTmpDir = createTempDir();
|
||||
String realTmpDir = System.getProperty("java.io.tmpdir");
|
||||
Permissions permissions;
|
||||
try {
|
||||
System.setProperty("java.io.tmpdir", fakeTmpDir.toString());
|
||||
Environment environment = new Environment(settings);
|
||||
permissions = Security.createPermissions(environment);
|
||||
} finally {
|
||||
System.setProperty("java.io.tmpdir", realTmpDir);
|
||||
}
|
||||
|
||||
// the fake es home
|
||||
assertNoPermissions(esHome, permissions);
|
||||
// its parent
|
||||
assertNoPermissions(esHome.getParent(), permissions);
|
||||
// some other sibling
|
||||
assertNoPermissions(esHome.getParent().resolve("other"), permissions);
|
||||
// double check we overwrote java.io.tmpdir correctly for the test
|
||||
assertNoPermissions(PathUtils.get(realTmpDir), permissions);
|
||||
}
|
||||
|
||||
/** test generated permissions for all configured paths */
|
||||
public void testEnvironmentPaths() throws Exception {
|
||||
Path path = createTempDir();
|
||||
// make a fake ES home and ensure we only grant permissions to that.
|
||||
Path esHome = path.resolve("esHome");
|
||||
|
||||
Settings.Builder settingsBuilder = Settings.builder();
|
||||
settingsBuilder.put("path.home", esHome.resolve("home").toString());
|
||||
settingsBuilder.put("path.conf", esHome.resolve("conf").toString());
|
||||
settingsBuilder.put("path.scripts", esHome.resolve("scripts").toString());
|
||||
settingsBuilder.put("path.plugins", esHome.resolve("plugins").toString());
|
||||
settingsBuilder.putArray("path.data", esHome.resolve("data1").toString(), esHome.resolve("data2").toString());
|
||||
settingsBuilder.put("path.shared_data", esHome.resolve("custom").toString());
|
||||
settingsBuilder.put("path.logs", esHome.resolve("logs").toString());
|
||||
settingsBuilder.put("pidfile", esHome.resolve("test.pid").toString());
|
||||
Settings settings = settingsBuilder.build();
|
||||
|
||||
Path fakeTmpDir = createTempDir();
|
||||
String realTmpDir = System.getProperty("java.io.tmpdir");
|
||||
Permissions permissions;
|
||||
Environment environment;
|
||||
try {
|
||||
System.setProperty("java.io.tmpdir", fakeTmpDir.toString());
|
||||
environment = new Environment(settings);
|
||||
permissions = Security.createPermissions(environment);
|
||||
} finally {
|
||||
System.setProperty("java.io.tmpdir", realTmpDir);
|
||||
}
|
||||
|
||||
// the fake es home
|
||||
assertNoPermissions(esHome, permissions);
|
||||
// its parent
|
||||
assertNoPermissions(esHome.getParent(), permissions);
|
||||
// some other sibling
|
||||
assertNoPermissions(esHome.getParent().resolve("other"), permissions);
|
||||
// double check we overwrote java.io.tmpdir correctly for the test
|
||||
assertNoPermissions(PathUtils.get(realTmpDir), permissions);
|
||||
|
||||
// check that all directories got permissions:
|
||||
|
||||
// bin file: ro
|
||||
assertExactPermissions(new FilePermission(environment.binFile().toString(), "read,readlink"), permissions);
|
||||
// lib file: ro
|
||||
assertExactPermissions(new FilePermission(environment.libFile().toString(), "read,readlink"), permissions);
|
||||
// config file: ro
|
||||
assertExactPermissions(new FilePermission(environment.configFile().toString(), "read,readlink"), permissions);
|
||||
// scripts file: ro
|
||||
assertExactPermissions(new FilePermission(environment.scriptsFile().toString(), "read,readlink"), permissions);
|
||||
// plugins: ro
|
||||
assertExactPermissions(new FilePermission(environment.pluginsFile().toString(), "read,readlink"), permissions);
|
||||
|
||||
// data paths: r/w
|
||||
for (Path dataPath : environment.dataFiles()) {
|
||||
assertExactPermissions(new FilePermission(dataPath.toString(), "read,readlink,write,delete"), permissions);
|
||||
}
|
||||
for (Path dataPath : environment.dataWithClusterFiles()) {
|
||||
assertExactPermissions(new FilePermission(dataPath.toString(), "read,readlink,write,delete"), permissions);
|
||||
}
|
||||
assertExactPermissions(new FilePermission(environment.sharedDataFile().toString(), "read,readlink,write,delete"), permissions);
|
||||
// logs: r/w
|
||||
assertExactPermissions(new FilePermission(environment.logsFile().toString(), "read,readlink,write,delete"), permissions);
|
||||
// temp dir: r/w
|
||||
assertExactPermissions(new FilePermission(fakeTmpDir.toString(), "read,readlink,write,delete"), permissions);
|
||||
// PID file: delete only (for the shutdown hook)
|
||||
assertExactPermissions(new FilePermission(environment.pidFile().toString(), "delete"), permissions);
|
||||
}
|
||||
|
||||
public void testEnsureExists() throws IOException {
|
||||
Path p = createTempDir();
|
||||
|
||||
|
@ -163,43 +58,6 @@ public class SecurityTests extends ESTestCase {
|
|||
} catch (IOException expected) {}
|
||||
}
|
||||
|
||||
public void testEnsureSymlink() throws IOException {
|
||||
Path p = createTempDir();
|
||||
|
||||
Path exists = p.resolve("exists");
|
||||
Files.createDirectory(exists);
|
||||
|
||||
// symlink
|
||||
Path linkExists = p.resolve("linkExists");
|
||||
try {
|
||||
Files.createSymbolicLink(linkExists, exists);
|
||||
} catch (UnsupportedOperationException | IOException e) {
|
||||
assumeNoException("test requires filesystem that supports symbolic links", e);
|
||||
} catch (SecurityException e) {
|
||||
assumeNoException("test cannot create symbolic links with security manager enabled", e);
|
||||
}
|
||||
Security.ensureDirectoryExists(linkExists);
|
||||
Files.createTempFile(linkExists, null, null);
|
||||
}
|
||||
|
||||
public void testEnsureBrokenSymlink() throws IOException {
|
||||
Path p = createTempDir();
|
||||
|
||||
// broken symlink
|
||||
Path brokenLink = p.resolve("brokenLink");
|
||||
try {
|
||||
Files.createSymbolicLink(brokenLink, p.resolve("nonexistent"));
|
||||
} catch (UnsupportedOperationException | IOException e) {
|
||||
assumeNoException("test requires filesystem that supports symbolic links", e);
|
||||
} catch (SecurityException e) {
|
||||
assumeNoException("test cannot create symbolic links with security manager enabled", e);
|
||||
}
|
||||
try {
|
||||
Security.ensureDirectoryExists(brokenLink);
|
||||
fail("didn't get expected exception");
|
||||
} catch (IOException expected) {}
|
||||
}
|
||||
|
||||
/** can't execute processes */
|
||||
public void testProcessExecution() throws Exception {
|
||||
assumeTrue("test requires security manager", System.getSecurityManager() != null);
|
||||
|
@ -208,61 +66,4 @@ public class SecurityTests extends ESTestCase {
|
|||
fail("didn't get expected exception");
|
||||
} catch (SecurityException expected) {}
|
||||
}
|
||||
|
||||
/** When a configured dir is a symlink, test that permissions work on link target */
|
||||
public void testSymlinkPermissions() throws IOException {
|
||||
// see https://github.com/elastic/elasticsearch/issues/12170
|
||||
assumeFalse("windows does not automatically grant permission to the target of symlinks", Constants.WINDOWS);
|
||||
Path dir = createTempDir();
|
||||
|
||||
Path target = dir.resolve("target");
|
||||
Files.createDirectory(target);
|
||||
|
||||
// symlink
|
||||
Path link = dir.resolve("link");
|
||||
try {
|
||||
Files.createSymbolicLink(link, target);
|
||||
} catch (UnsupportedOperationException | IOException e) {
|
||||
assumeNoException("test requires filesystem that supports symbolic links", e);
|
||||
} catch (SecurityException e) {
|
||||
assumeNoException("test cannot create symbolic links with security manager enabled", e);
|
||||
}
|
||||
Permissions permissions = new Permissions();
|
||||
Security.addPath(permissions, "testing", link, "read");
|
||||
assertExactPermissions(new FilePermission(link.toString(), "read"), permissions);
|
||||
assertExactPermissions(new FilePermission(link.resolve("foo").toString(), "read"), permissions);
|
||||
assertExactPermissions(new FilePermission(target.toString(), "read"), permissions);
|
||||
assertExactPermissions(new FilePermission(target.resolve("foo").toString(), "read"), permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks exact file permissions, meaning those and only those for that path.
|
||||
*/
|
||||
static void assertExactPermissions(FilePermission expected, PermissionCollection actual) {
|
||||
String target = expected.getName(); // see javadocs
|
||||
Set<String> permissionSet = asSet(expected.getActions().split(","));
|
||||
boolean read = permissionSet.remove("read");
|
||||
boolean readlink = permissionSet.remove("readlink");
|
||||
boolean write = permissionSet.remove("write");
|
||||
boolean delete = permissionSet.remove("delete");
|
||||
boolean execute = permissionSet.remove("execute");
|
||||
assertTrue("unrecognized permission: " + permissionSet, permissionSet.isEmpty());
|
||||
assertEquals(read, actual.implies(new FilePermission(target, "read")));
|
||||
assertEquals(readlink, actual.implies(new FilePermission(target, "readlink")));
|
||||
assertEquals(write, actual.implies(new FilePermission(target, "write")));
|
||||
assertEquals(delete, actual.implies(new FilePermission(target, "delete")));
|
||||
assertEquals(execute, actual.implies(new FilePermission(target, "execute")));
|
||||
}
|
||||
|
||||
/**
|
||||
* checks that this path has no permissions
|
||||
*/
|
||||
static void assertNoPermissions(Path path, PermissionCollection actual) {
|
||||
String target = path.toString();
|
||||
assertFalse(actual.implies(new FilePermission(target, "read")));
|
||||
assertFalse(actual.implies(new FilePermission(target, "readlink")));
|
||||
assertFalse(actual.implies(new FilePermission(target, "write")));
|
||||
assertFalse(actual.implies(new FilePermission(target, "delete")));
|
||||
assertFalse(actual.implies(new FilePermission(target, "execute")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,25 +67,23 @@ public class SettingsTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testReplacePropertiesPlaceholderSystemProperty() {
|
||||
System.setProperty("sysProp1", "sysVal1");
|
||||
try {
|
||||
Settings settings = settingsBuilder()
|
||||
.put("setting1", "${sysProp1}")
|
||||
.replacePropertyPlaceholders()
|
||||
.build();
|
||||
assertThat(settings.get("setting1"), equalTo("sysVal1"));
|
||||
} finally {
|
||||
System.clearProperty("sysProp1");
|
||||
}
|
||||
|
||||
String value = System.getProperty("java.home");
|
||||
assertFalse(value.isEmpty());
|
||||
Settings settings = settingsBuilder()
|
||||
.put("setting1", "${sysProp1:defaultVal1}")
|
||||
.put("setting1", "${java.home}")
|
||||
.replacePropertyPlaceholders()
|
||||
.build();
|
||||
assertThat(settings.get("setting1"), equalTo(value));
|
||||
|
||||
assertNull(System.getProperty("_test_property_should_not_exist"));
|
||||
settings = settingsBuilder()
|
||||
.put("setting1", "${_test_property_should_not_exist:defaultVal1}")
|
||||
.replacePropertyPlaceholders()
|
||||
.build();
|
||||
assertThat(settings.get("setting1"), equalTo("defaultVal1"));
|
||||
|
||||
settings = settingsBuilder()
|
||||
.put("setting1", "${sysProp1:}")
|
||||
.put("setting1", "${_test_property_should_not_exist:}")
|
||||
.replacePropertyPlaceholders()
|
||||
.build();
|
||||
assertThat(settings.get("setting1"), is(nullValue()));
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.node.internal;
|
|||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.common.cli.CliToolTestCase;
|
||||
import org.elasticsearch.common.cli.Terminal;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsException;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
@ -35,9 +34,7 @@ import java.io.InputStream;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.elasticsearch.common.settings.Settings.settingsBuilder;
|
||||
|
@ -45,38 +42,8 @@ import static org.hamcrest.Matchers.*;
|
|||
|
||||
public class InternalSettingsPreparerTests extends ESTestCase {
|
||||
|
||||
Map<String, String> savedProperties = new HashMap<>();
|
||||
Settings baseEnvSettings;
|
||||
|
||||
@Before
|
||||
public void saveSettingsSystemProperties() {
|
||||
// clear out any properties the settings preparer may look for
|
||||
savedProperties.clear();
|
||||
for (Object propObj : System.getProperties().keySet()) {
|
||||
String property = (String)propObj;
|
||||
// NOTE: these prefixes are prefixes of the defaults, so both are handled here
|
||||
for (String prefix : InternalSettingsPreparer.PROPERTY_PREFIXES) {
|
||||
if (property.startsWith(prefix)) {
|
||||
savedProperties.put(property, System.getProperty(property));
|
||||
}
|
||||
}
|
||||
}
|
||||
String name = System.getProperty("name");
|
||||
if (name != null) {
|
||||
savedProperties.put("name", name);
|
||||
}
|
||||
for (String property : savedProperties.keySet()) {
|
||||
System.clearProperty(property);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void restoreSettingsSystemProperties() {
|
||||
for (Map.Entry<String, String> property : savedProperties.entrySet()) {
|
||||
System.setProperty(property.getKey(), property.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void createBaseEnvSettings() {
|
||||
baseEnvSettings = settingsBuilder()
|
||||
|
@ -93,13 +60,13 @@ public class InternalSettingsPreparerTests extends ESTestCase {
|
|||
Settings settings = InternalSettingsPreparer.prepareSettings(Settings.EMPTY);
|
||||
assertNotNull(settings.get("name")); // a name was set
|
||||
assertNotNull(settings.get(ClusterName.SETTING)); // a cluster name was set
|
||||
assertEquals(settings.toString(), 2, settings.names().size());
|
||||
int size = settings.names().size();
|
||||
|
||||
Environment env = InternalSettingsPreparer.prepareEnvironment(baseEnvSettings, null);
|
||||
settings = env.settings();
|
||||
assertNotNull(settings.get("name")); // a name was set
|
||||
assertNotNull(settings.get(ClusterName.SETTING)); // a cluster name was set
|
||||
assertEquals(settings.toString(), 3 /* path.home is in the base settings */, settings.names().size());
|
||||
assertEquals(settings.toString(), size + 1 /* path.home is in the base settings */, settings.names().size());
|
||||
String home = baseEnvSettings.get("path.home");
|
||||
String configDir = env.configFile().toString();
|
||||
assertTrue(configDir, configDir.startsWith(home));
|
||||
|
@ -112,30 +79,6 @@ public class InternalSettingsPreparerTests extends ESTestCase {
|
|||
assertEquals(ClusterName.DEFAULT.value(), settings.get(ClusterName.SETTING));
|
||||
}
|
||||
|
||||
public void testIgnoreSystemProperties() {
|
||||
try {
|
||||
System.setProperty("es.node.zone", "foo");
|
||||
Settings settings = settingsBuilder()
|
||||
.put("node.zone", "bar")
|
||||
.put(baseEnvSettings)
|
||||
.build();
|
||||
Environment env = InternalSettingsPreparer.prepareEnvironment(settings, null);
|
||||
// Should use setting from the system property
|
||||
assertThat(env.settings().get("node.zone"), equalTo("foo"));
|
||||
|
||||
settings = settingsBuilder()
|
||||
.put(InternalSettingsPreparer.IGNORE_SYSTEM_PROPERTIES_SETTING, true)
|
||||
.put("node.zone", "bar")
|
||||
.put(baseEnvSettings)
|
||||
.build();
|
||||
env = InternalSettingsPreparer.prepareEnvironment(settings, null);
|
||||
// Should use setting from the system property
|
||||
assertThat(env.settings().get("node.zone"), equalTo("bar"));
|
||||
} finally {
|
||||
System.clearProperty("es.node.zone");
|
||||
}
|
||||
}
|
||||
|
||||
public void testReplacePromptPlaceholders() {
|
||||
final List<String> replacedSecretProperties = new ArrayList<>();
|
||||
final List<String> replacedTextProperties = new ArrayList<>();
|
||||
|
@ -205,74 +148,6 @@ public class InternalSettingsPreparerTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testNameSettingsPreference() {
|
||||
try {
|
||||
System.setProperty("name", "sys-prop-name");
|
||||
// Test system property overrides node.name
|
||||
Settings settings = settingsBuilder()
|
||||
.put("node.name", "node-name")
|
||||
.put(baseEnvSettings)
|
||||
.build();
|
||||
Environment env = InternalSettingsPreparer.prepareEnvironment(settings, null);
|
||||
assertThat(env.settings().get("name"), equalTo("sys-prop-name"));
|
||||
|
||||
// test name in settings overrides sys prop and node.name
|
||||
settings = settingsBuilder()
|
||||
.put("name", "name-in-settings")
|
||||
.put("node.name", "node-name")
|
||||
.put(baseEnvSettings)
|
||||
.build();
|
||||
env = InternalSettingsPreparer.prepareEnvironment(settings, null);
|
||||
assertThat(env.settings().get("name"), equalTo("name-in-settings"));
|
||||
|
||||
// test only node.name in settings
|
||||
System.clearProperty("name");
|
||||
settings = settingsBuilder()
|
||||
.put("node.name", "node-name")
|
||||
.put(baseEnvSettings)
|
||||
.build();
|
||||
env = InternalSettingsPreparer.prepareEnvironment(settings, null);
|
||||
assertThat(env.settings().get("name"), equalTo("node-name"));
|
||||
|
||||
// test no name at all results in name being set
|
||||
env = InternalSettingsPreparer.prepareEnvironment(baseEnvSettings, null);
|
||||
assertThat(env.settings().get("name"), not("name-in-settings"));
|
||||
assertThat(env.settings().get("name"), not("sys-prop-name"));
|
||||
assertThat(env.settings().get("name"), not("node-name"));
|
||||
assertThat(env.settings().get("name"), notNullValue());
|
||||
} finally {
|
||||
System.clearProperty("name");
|
||||
}
|
||||
}
|
||||
|
||||
public void testPromptForNodeNameOnlyPromptsOnce() {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
final Terminal terminal = new CliToolTestCase.MockTerminal() {
|
||||
@Override
|
||||
public char[] readSecret(String message, Object... args) {
|
||||
fail("readSecret should never be called by this test");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readText(String message, Object... args) {
|
||||
int count = counter.getAndIncrement();
|
||||
return "prompted name " + count;
|
||||
}
|
||||
};
|
||||
|
||||
System.clearProperty("name");
|
||||
Settings settings = Settings.builder()
|
||||
.put(baseEnvSettings)
|
||||
.put("node.name", InternalSettingsPreparer.TEXT_PROMPT_VALUE)
|
||||
.build();
|
||||
Environment env = InternalSettingsPreparer.prepareEnvironment(settings, terminal);
|
||||
settings = env.settings();
|
||||
assertThat(counter.intValue(), is(1));
|
||||
assertThat(settings.get("name"), is("prompted name 0"));
|
||||
assertThat(settings.get("node.name"), is("prompted name 0"));
|
||||
}
|
||||
|
||||
public void testGarbageIsNotSwallowed() throws IOException {
|
||||
try {
|
||||
InputStream garbage = getClass().getResourceAsStream("/config/garbage/garbage.yml");
|
||||
|
|
|
@ -26,11 +26,6 @@ import org.elasticsearch.common.settings.SettingsException;
|
|||
import org.elasticsearch.plugin.discovery.ec2.Ec2DiscoveryPlugin;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.ESIntegTestCase.ThirdParty;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base class for AWS tests that require credentials.
|
||||
|
@ -41,35 +36,6 @@ import java.util.Map;
|
|||
@ThirdParty
|
||||
public abstract class AbstractAwsTestCase extends ESIntegTestCase {
|
||||
|
||||
/**
|
||||
* Those properties are set by the AWS SDK v1.9.4 and if not ignored,
|
||||
* lead to tests failure (see AbstractRandomizedTest#IGNORED_INVARIANT_PROPERTIES)
|
||||
*/
|
||||
private static final String[] AWS_INVARIANT_PROPERTIES = {
|
||||
"com.sun.org.apache.xml.internal.dtm.DTMManager",
|
||||
"javax.xml.parsers.DocumentBuilderFactory"
|
||||
};
|
||||
|
||||
private Map<String, String> properties = new HashMap<>();
|
||||
|
||||
@Before
|
||||
public void saveProperties() {
|
||||
for (String p : AWS_INVARIANT_PROPERTIES) {
|
||||
properties.put(p, System.getProperty(p));
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void restoreProperties() {
|
||||
for (String p : AWS_INVARIANT_PROPERTIES) {
|
||||
if (properties.get(p) != null) {
|
||||
System.setProperty(p, properties.get(p));
|
||||
} else {
|
||||
System.clearProperty(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Settings nodeSettings(int nodeOrdinal) {
|
||||
Settings.Builder settings = Settings.builder()
|
||||
|
|
|
@ -48,9 +48,6 @@ public class PythonScriptEngineTests extends ESTestCase {
|
|||
|
||||
@After
|
||||
public void close() {
|
||||
// We need to clear some system properties
|
||||
System.clearProperty("python.cachedir.skip");
|
||||
System.clearProperty("python.console.encoding");
|
||||
se.close();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.elasticsearch.script.CompiledScript;
|
|||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.After;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -39,12 +38,6 @@ import static org.hamcrest.Matchers.equalTo;
|
|||
*
|
||||
*/
|
||||
public class PythonScriptMultiThreadedTests extends ESTestCase {
|
||||
@After
|
||||
public void close() {
|
||||
// We need to clear some system properties
|
||||
System.clearProperty("python.cachedir.skip");
|
||||
System.clearProperty("python.console.encoding");
|
||||
}
|
||||
|
||||
public void testExecutableNoRuntimeParams() throws Exception {
|
||||
final PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
||||
|
|
|
@ -45,9 +45,6 @@ public class PythonSecurityTests extends ESTestCase {
|
|||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
// We need to clear some system properties
|
||||
System.clearProperty("python.cachedir.skip");
|
||||
System.clearProperty("python.console.encoding");
|
||||
se.close();
|
||||
super.tearDown();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.mapper.attachments;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.cli.CliTool;
|
||||
import org.elasticsearch.common.cli.CliToolConfig;
|
||||
|
@ -59,6 +60,7 @@ import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath;
|
|||
* StandaloneRunner -u /tmp/mydoc.pdf
|
||||
* StandaloneRunner -u /tmp/mydoc.pdf --size 1000000
|
||||
*/
|
||||
@SuppressForbidden(reason = "commandline tool")
|
||||
public class StandaloneRunner extends CliTool {
|
||||
|
||||
private static final CliToolConfig CONFIG = CliToolConfig.config("tika", StandaloneRunner.class)
|
||||
|
|
|
@ -68,8 +68,6 @@ public class VariousDocTests extends AttachmentUnitTestCase {
|
|||
*/
|
||||
public void testEncryptedPDFDocument() throws Exception {
|
||||
assertException("encrypted.pdf", "is encrypted");
|
||||
// TODO Remove when this will be fixed in Tika. See https://issues.apache.org/jira/browse/TIKA-1548
|
||||
System.clearProperty("sun.font.fontmanager");
|
||||
testMapper("encrypted.pdf", true);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,11 +26,6 @@ import org.elasticsearch.common.settings.SettingsException;
|
|||
import org.elasticsearch.plugin.repository.s3.S3RepositoryPlugin;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.ESIntegTestCase.ThirdParty;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base class for AWS tests that require credentials.
|
||||
|
@ -41,35 +36,6 @@ import java.util.Map;
|
|||
@ThirdParty
|
||||
public abstract class AbstractAwsTestCase extends ESIntegTestCase {
|
||||
|
||||
/**
|
||||
* Those properties are set by the AWS SDK v1.9.4 and if not ignored,
|
||||
* lead to tests failure (see AbstractRandomizedTest#IGNORED_INVARIANT_PROPERTIES)
|
||||
*/
|
||||
private static final String[] AWS_INVARIANT_PROPERTIES = {
|
||||
"com.sun.org.apache.xml.internal.dtm.DTMManager",
|
||||
"javax.xml.parsers.DocumentBuilderFactory"
|
||||
};
|
||||
|
||||
private Map<String, String> properties = new HashMap<>();
|
||||
|
||||
@Before
|
||||
public void saveProperties() {
|
||||
for (String p : AWS_INVARIANT_PROPERTIES) {
|
||||
properties.put(p, System.getProperty(p));
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void restoreProperties() {
|
||||
for (String p : AWS_INVARIANT_PROPERTIES) {
|
||||
if (properties.get(p) != null) {
|
||||
System.setProperty(p, properties.get(p));
|
||||
} else {
|
||||
System.clearProperty(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Settings nodeSettings(int nodeOrdinal) {
|
||||
Settings.Builder settings = Settings.builder()
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.bootstrap;
|
|||
|
||||
import org.elasticsearch.Build;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.cli.CliTool.ExitStatus;
|
||||
import org.elasticsearch.common.cli.CliToolTestCase;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
|
@ -36,6 +37,7 @@ import java.util.Locale;
|
|||
import static org.elasticsearch.common.cli.CliTool.ExitStatus.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
@SuppressForbidden(reason = "modifies system properties intentionally")
|
||||
public class BootstrapCliParserTests extends CliToolTestCase {
|
||||
|
||||
private CaptureOutputTerminal terminal = new CaptureOutputTerminal();
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.elasticsearch.bootstrap;
|
||||
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/** Tests for Jarhell that change very important system properties... very evil! */
|
||||
@SuppressForbidden(reason = "modifies system properties intentionally")
|
||||
public class EvilJarHellTests extends ESTestCase {
|
||||
|
||||
URL makeJar(Path dir, String name, Manifest manifest, String... files) throws IOException {
|
||||
Path jarpath = dir.resolve(name);
|
||||
ZipOutputStream out;
|
||||
if (manifest == null) {
|
||||
out = new JarOutputStream(Files.newOutputStream(jarpath, StandardOpenOption.CREATE));
|
||||
} else {
|
||||
out = new JarOutputStream(Files.newOutputStream(jarpath, StandardOpenOption.CREATE), manifest);
|
||||
}
|
||||
for (String file : files) {
|
||||
out.putNextEntry(new ZipEntry(file));
|
||||
}
|
||||
out.close();
|
||||
return jarpath.toUri().toURL();
|
||||
}
|
||||
|
||||
public void testBootclasspathLeniency() throws Exception {
|
||||
Path dir = createTempDir();
|
||||
String previousJavaHome = System.getProperty("java.home");
|
||||
System.setProperty("java.home", dir.toString());
|
||||
URL[] jars = {makeJar(dir, "foo.jar", null, "DuplicateClass.class"), makeJar(dir, "bar.jar", null, "DuplicateClass.class")};
|
||||
try {
|
||||
JarHell.checkJarHell(jars);
|
||||
} finally {
|
||||
System.setProperty("java.home", previousJavaHome);
|
||||
}
|
||||
}
|
||||
|
||||
public void testRequiredJDKVersionIsOK() throws Exception {
|
||||
Path dir = createTempDir();
|
||||
String previousJavaVersion = System.getProperty("java.specification.version");
|
||||
System.setProperty("java.specification.version", "1.7");
|
||||
|
||||
Manifest manifest = new Manifest();
|
||||
Attributes attributes = manifest.getMainAttributes();
|
||||
attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
|
||||
attributes.put(new Attributes.Name("X-Compile-Target-JDK"), "1.7");
|
||||
URL[] jars = {makeJar(dir, "foo.jar", manifest, "Foo.class")};
|
||||
try {
|
||||
JarHell.checkJarHell(jars);
|
||||
} finally {
|
||||
System.setProperty("java.specification.version", previousJavaVersion);
|
||||
}
|
||||
}
|
||||
|
||||
public void testBadJDKVersionProperty() throws Exception {
|
||||
Path dir = createTempDir();
|
||||
String previousJavaVersion = System.getProperty("java.specification.version");
|
||||
System.setProperty("java.specification.version", "bogus");
|
||||
|
||||
Manifest manifest = new Manifest();
|
||||
Attributes attributes = manifest.getMainAttributes();
|
||||
attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
|
||||
attributes.put(new Attributes.Name("X-Compile-Target-JDK"), "1.7");
|
||||
URL[] jars = {makeJar(dir, "foo.jar", manifest, "Foo.class")};
|
||||
try {
|
||||
JarHell.checkJarHell(jars);
|
||||
} finally {
|
||||
System.setProperty("java.specification.version", previousJavaVersion);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.elasticsearch.bootstrap;
|
||||
|
||||
import org.apache.lucene.util.Constants;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.io.PathUtils;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.FilePermission;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Permissions;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressForbidden(reason = "modifies system properties and attempts to create symbolic links intentionally")
|
||||
public class EvilSecurityTests extends ESTestCase {
|
||||
|
||||
/** test generated permissions */
|
||||
public void testGeneratedPermissions() throws Exception {
|
||||
Path path = createTempDir();
|
||||
// make a fake ES home and ensure we only grant permissions to that.
|
||||
Path esHome = path.resolve("esHome");
|
||||
Settings.Builder settingsBuilder = Settings.builder();
|
||||
settingsBuilder.put("path.home", esHome.toString());
|
||||
Settings settings = settingsBuilder.build();
|
||||
|
||||
Path fakeTmpDir = createTempDir();
|
||||
String realTmpDir = System.getProperty("java.io.tmpdir");
|
||||
Permissions permissions;
|
||||
try {
|
||||
System.setProperty("java.io.tmpdir", fakeTmpDir.toString());
|
||||
Environment environment = new Environment(settings);
|
||||
permissions = Security.createPermissions(environment);
|
||||
} finally {
|
||||
System.setProperty("java.io.tmpdir", realTmpDir);
|
||||
}
|
||||
|
||||
// the fake es home
|
||||
assertNoPermissions(esHome, permissions);
|
||||
// its parent
|
||||
assertNoPermissions(esHome.getParent(), permissions);
|
||||
// some other sibling
|
||||
assertNoPermissions(esHome.getParent().resolve("other"), permissions);
|
||||
// double check we overwrote java.io.tmpdir correctly for the test
|
||||
assertNoPermissions(PathUtils.get(realTmpDir), permissions);
|
||||
}
|
||||
|
||||
/** test generated permissions for all configured paths */
|
||||
public void testEnvironmentPaths() throws Exception {
|
||||
Path path = createTempDir();
|
||||
// make a fake ES home and ensure we only grant permissions to that.
|
||||
Path esHome = path.resolve("esHome");
|
||||
|
||||
Settings.Builder settingsBuilder = Settings.builder();
|
||||
settingsBuilder.put("path.home", esHome.resolve("home").toString());
|
||||
settingsBuilder.put("path.conf", esHome.resolve("conf").toString());
|
||||
settingsBuilder.put("path.scripts", esHome.resolve("scripts").toString());
|
||||
settingsBuilder.put("path.plugins", esHome.resolve("plugins").toString());
|
||||
settingsBuilder.putArray("path.data", esHome.resolve("data1").toString(), esHome.resolve("data2").toString());
|
||||
settingsBuilder.put("path.shared_data", esHome.resolve("custom").toString());
|
||||
settingsBuilder.put("path.logs", esHome.resolve("logs").toString());
|
||||
settingsBuilder.put("pidfile", esHome.resolve("test.pid").toString());
|
||||
Settings settings = settingsBuilder.build();
|
||||
|
||||
Path fakeTmpDir = createTempDir();
|
||||
String realTmpDir = System.getProperty("java.io.tmpdir");
|
||||
Permissions permissions;
|
||||
Environment environment;
|
||||
try {
|
||||
System.setProperty("java.io.tmpdir", fakeTmpDir.toString());
|
||||
environment = new Environment(settings);
|
||||
permissions = Security.createPermissions(environment);
|
||||
} finally {
|
||||
System.setProperty("java.io.tmpdir", realTmpDir);
|
||||
}
|
||||
|
||||
// the fake es home
|
||||
assertNoPermissions(esHome, permissions);
|
||||
// its parent
|
||||
assertNoPermissions(esHome.getParent(), permissions);
|
||||
// some other sibling
|
||||
assertNoPermissions(esHome.getParent().resolve("other"), permissions);
|
||||
// double check we overwrote java.io.tmpdir correctly for the test
|
||||
assertNoPermissions(PathUtils.get(realTmpDir), permissions);
|
||||
|
||||
// check that all directories got permissions:
|
||||
|
||||
// bin file: ro
|
||||
assertExactPermissions(new FilePermission(environment.binFile().toString(), "read,readlink"), permissions);
|
||||
// lib file: ro
|
||||
assertExactPermissions(new FilePermission(environment.libFile().toString(), "read,readlink"), permissions);
|
||||
// config file: ro
|
||||
assertExactPermissions(new FilePermission(environment.configFile().toString(), "read,readlink"), permissions);
|
||||
// scripts file: ro
|
||||
assertExactPermissions(new FilePermission(environment.scriptsFile().toString(), "read,readlink"), permissions);
|
||||
// plugins: ro
|
||||
assertExactPermissions(new FilePermission(environment.pluginsFile().toString(), "read,readlink"), permissions);
|
||||
|
||||
// data paths: r/w
|
||||
for (Path dataPath : environment.dataFiles()) {
|
||||
assertExactPermissions(new FilePermission(dataPath.toString(), "read,readlink,write,delete"), permissions);
|
||||
}
|
||||
for (Path dataPath : environment.dataWithClusterFiles()) {
|
||||
assertExactPermissions(new FilePermission(dataPath.toString(), "read,readlink,write,delete"), permissions);
|
||||
}
|
||||
assertExactPermissions(new FilePermission(environment.sharedDataFile().toString(), "read,readlink,write,delete"), permissions);
|
||||
// logs: r/w
|
||||
assertExactPermissions(new FilePermission(environment.logsFile().toString(), "read,readlink,write,delete"), permissions);
|
||||
// temp dir: r/w
|
||||
assertExactPermissions(new FilePermission(fakeTmpDir.toString(), "read,readlink,write,delete"), permissions);
|
||||
// PID file: delete only (for the shutdown hook)
|
||||
assertExactPermissions(new FilePermission(environment.pidFile().toString(), "delete"), permissions);
|
||||
}
|
||||
|
||||
public void testEnsureSymlink() throws IOException {
|
||||
Path p = createTempDir();
|
||||
|
||||
Path exists = p.resolve("exists");
|
||||
Files.createDirectory(exists);
|
||||
|
||||
// symlink
|
||||
Path linkExists = p.resolve("linkExists");
|
||||
try {
|
||||
Files.createSymbolicLink(linkExists, exists);
|
||||
} catch (UnsupportedOperationException | IOException e) {
|
||||
assumeNoException("test requires filesystem that supports symbolic links", e);
|
||||
} catch (SecurityException e) {
|
||||
assumeNoException("test cannot create symbolic links with security manager enabled", e);
|
||||
}
|
||||
Security.ensureDirectoryExists(linkExists);
|
||||
Files.createTempFile(linkExists, null, null);
|
||||
}
|
||||
|
||||
public void testEnsureBrokenSymlink() throws IOException {
|
||||
Path p = createTempDir();
|
||||
|
||||
// broken symlink
|
||||
Path brokenLink = p.resolve("brokenLink");
|
||||
try {
|
||||
Files.createSymbolicLink(brokenLink, p.resolve("nonexistent"));
|
||||
} catch (UnsupportedOperationException | IOException e) {
|
||||
assumeNoException("test requires filesystem that supports symbolic links", e);
|
||||
} catch (SecurityException e) {
|
||||
assumeNoException("test cannot create symbolic links with security manager enabled", e);
|
||||
}
|
||||
try {
|
||||
Security.ensureDirectoryExists(brokenLink);
|
||||
fail("didn't get expected exception");
|
||||
} catch (IOException expected) {}
|
||||
}
|
||||
|
||||
/** When a configured dir is a symlink, test that permissions work on link target */
|
||||
public void testSymlinkPermissions() throws IOException {
|
||||
// see https://github.com/elastic/elasticsearch/issues/12170
|
||||
assumeFalse("windows does not automatically grant permission to the target of symlinks", Constants.WINDOWS);
|
||||
Path dir = createTempDir();
|
||||
|
||||
Path target = dir.resolve("target");
|
||||
Files.createDirectory(target);
|
||||
|
||||
// symlink
|
||||
Path link = dir.resolve("link");
|
||||
try {
|
||||
Files.createSymbolicLink(link, target);
|
||||
} catch (UnsupportedOperationException | IOException e) {
|
||||
assumeNoException("test requires filesystem that supports symbolic links", e);
|
||||
} catch (SecurityException e) {
|
||||
assumeNoException("test cannot create symbolic links with security manager enabled", e);
|
||||
}
|
||||
Permissions permissions = new Permissions();
|
||||
Security.addPath(permissions, "testing", link, "read");
|
||||
assertExactPermissions(new FilePermission(link.toString(), "read"), permissions);
|
||||
assertExactPermissions(new FilePermission(link.resolve("foo").toString(), "read"), permissions);
|
||||
assertExactPermissions(new FilePermission(target.toString(), "read"), permissions);
|
||||
assertExactPermissions(new FilePermission(target.resolve("foo").toString(), "read"), permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks exact file permissions, meaning those and only those for that path.
|
||||
*/
|
||||
static void assertExactPermissions(FilePermission expected, PermissionCollection actual) {
|
||||
String target = expected.getName(); // see javadocs
|
||||
Set<String> permissionSet = asSet(expected.getActions().split(","));
|
||||
boolean read = permissionSet.remove("read");
|
||||
boolean readlink = permissionSet.remove("readlink");
|
||||
boolean write = permissionSet.remove("write");
|
||||
boolean delete = permissionSet.remove("delete");
|
||||
boolean execute = permissionSet.remove("execute");
|
||||
assertTrue("unrecognized permission: " + permissionSet, permissionSet.isEmpty());
|
||||
assertEquals(read, actual.implies(new FilePermission(target, "read")));
|
||||
assertEquals(readlink, actual.implies(new FilePermission(target, "readlink")));
|
||||
assertEquals(write, actual.implies(new FilePermission(target, "write")));
|
||||
assertEquals(delete, actual.implies(new FilePermission(target, "delete")));
|
||||
assertEquals(execute, actual.implies(new FilePermission(target, "execute")));
|
||||
}
|
||||
|
||||
/**
|
||||
* checks that this path has no permissions
|
||||
*/
|
||||
static void assertNoPermissions(Path path, PermissionCollection actual) {
|
||||
String target = path.toString();
|
||||
assertFalse(actual.implies(new FilePermission(target, "read")));
|
||||
assertFalse(actual.implies(new FilePermission(target, "readlink")));
|
||||
assertFalse(actual.implies(new FilePermission(target, "write")));
|
||||
assertFalse(actual.implies(new FilePermission(target, "delete")));
|
||||
assertFalse(actual.implies(new FilePermission(target, "execute")));
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.common.cli;
|
|||
import org.apache.commons.cli.CommandLine;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
||||
|
@ -45,6 +46,7 @@ import static org.hamcrest.Matchers.is;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
@SuppressForbidden(reason = "modifies system properties intentionally")
|
||||
public class CliToolTests extends CliToolTestCase {
|
||||
public void testOK() throws Exception {
|
||||
Terminal terminal = new MockTerminal();
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.elasticsearch.node.internal;
|
||||
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.common.settings.Settings.settingsBuilder;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
@SuppressForbidden(reason = "modifies system properties intentionally")
|
||||
public class EvilInternalSettingsPreparerTests extends ESTestCase {
|
||||
|
||||
Map<String, String> savedProperties = new HashMap<>();
|
||||
Settings baseEnvSettings;
|
||||
|
||||
@Before
|
||||
public void saveSettingsSystemProperties() {
|
||||
// clear out any properties the settings preparer may look for
|
||||
savedProperties.clear();
|
||||
for (Object propObj : System.getProperties().keySet()) {
|
||||
String property = (String)propObj;
|
||||
// NOTE: these prefixes are prefixes of the defaults, so both are handled here
|
||||
for (String prefix : InternalSettingsPreparer.PROPERTY_PREFIXES) {
|
||||
if (property.startsWith(prefix)) {
|
||||
savedProperties.put(property, System.getProperty(property));
|
||||
}
|
||||
}
|
||||
}
|
||||
String name = System.getProperty("name");
|
||||
if (name != null) {
|
||||
savedProperties.put("name", name);
|
||||
}
|
||||
for (String property : savedProperties.keySet()) {
|
||||
System.clearProperty(property);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void restoreSettingsSystemProperties() {
|
||||
for (Map.Entry<String, String> property : savedProperties.entrySet()) {
|
||||
System.setProperty(property.getKey(), property.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void createBaseEnvSettings() {
|
||||
baseEnvSettings = settingsBuilder()
|
||||
.put("path.home", createTempDir())
|
||||
.build();
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearBaseEnvSettings() {
|
||||
baseEnvSettings = null;
|
||||
}
|
||||
|
||||
public void testIgnoreSystemProperties() {
|
||||
try {
|
||||
System.setProperty("es.node.zone", "foo");
|
||||
Settings settings = settingsBuilder()
|
||||
.put("node.zone", "bar")
|
||||
.put(baseEnvSettings)
|
||||
.build();
|
||||
Environment env = InternalSettingsPreparer.prepareEnvironment(settings, null);
|
||||
// Should use setting from the system property
|
||||
assertThat(env.settings().get("node.zone"), equalTo("foo"));
|
||||
|
||||
settings = settingsBuilder()
|
||||
.put(InternalSettingsPreparer.IGNORE_SYSTEM_PROPERTIES_SETTING, true)
|
||||
.put("node.zone", "bar")
|
||||
.put(baseEnvSettings)
|
||||
.build();
|
||||
env = InternalSettingsPreparer.prepareEnvironment(settings, null);
|
||||
// Should use setting from the system property
|
||||
assertThat(env.settings().get("node.zone"), equalTo("bar"));
|
||||
} finally {
|
||||
System.clearProperty("es.node.zone");
|
||||
}
|
||||
}
|
||||
|
||||
public void testNameSettingsPreference() {
|
||||
try {
|
||||
System.setProperty("name", "sys-prop-name");
|
||||
// Test system property overrides node.name
|
||||
Settings settings = settingsBuilder()
|
||||
.put("node.name", "node-name")
|
||||
.put(baseEnvSettings)
|
||||
.build();
|
||||
Environment env = InternalSettingsPreparer.prepareEnvironment(settings, null);
|
||||
assertThat(env.settings().get("name"), equalTo("sys-prop-name"));
|
||||
|
||||
// test name in settings overrides sys prop and node.name
|
||||
settings = settingsBuilder()
|
||||
.put("name", "name-in-settings")
|
||||
.put("node.name", "node-name")
|
||||
.put(baseEnvSettings)
|
||||
.build();
|
||||
env = InternalSettingsPreparer.prepareEnvironment(settings, null);
|
||||
assertThat(env.settings().get("name"), equalTo("name-in-settings"));
|
||||
|
||||
// test only node.name in settings
|
||||
System.clearProperty("name");
|
||||
settings = settingsBuilder()
|
||||
.put("node.name", "node-name")
|
||||
.put(baseEnvSettings)
|
||||
.build();
|
||||
env = InternalSettingsPreparer.prepareEnvironment(settings, null);
|
||||
assertThat(env.settings().get("name"), equalTo("node-name"));
|
||||
|
||||
// test no name at all results in name being set
|
||||
env = InternalSettingsPreparer.prepareEnvironment(baseEnvSettings, null);
|
||||
assertThat(env.settings().get("name"), not("name-in-settings"));
|
||||
assertThat(env.settings().get("name"), not("sys-prop-name"));
|
||||
assertThat(env.settings().get("name"), not("node-name"));
|
||||
assertThat(env.settings().get("name"), notNullValue());
|
||||
} finally {
|
||||
System.clearProperty("name");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ import org.apache.http.impl.client.HttpClients;
|
|||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.Base64;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.cli.CliTool;
|
||||
import org.elasticsearch.common.cli.CliTool.ExitStatus;
|
||||
import org.elasticsearch.common.cli.CliToolTestCase.CaptureOutputTerminal;
|
||||
|
@ -82,6 +83,7 @@ import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
|||
@LuceneTestCase.SuppressFileSystems("*") // TODO: clean up this test to allow extra files
|
||||
// TODO: jimfs is really broken here (throws wrong exception from detection method).
|
||||
// if its in your classpath, then do not use plugins!!!!!!
|
||||
@SuppressForbidden(reason = "modifies system properties intentionally")
|
||||
public class PluginManagerTests extends ESIntegTestCase {
|
||||
|
||||
private Environment environment;
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.plugins;
|
|||
|
||||
import org.elasticsearch.Build;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.http.client.HttpDownloadHelper;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
@ -42,6 +43,7 @@ import static org.hamcrest.Matchers.is;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
@SuppressForbidden(reason = "modifies system properties intentionally")
|
||||
public class PluginManagerUnitTests extends ESTestCase {
|
||||
@After
|
||||
public void cleanSystemProperty() {
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.tribe;
|
|||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.node.NodeBuilder;
|
||||
|
@ -42,6 +43,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
|
|||
* all the time, while we need to make the tribe node accept them in this case, so that we can verify that they are not read again as part
|
||||
* of the tribe client nodes initialization. Note that the started nodes will obey to the 'node.mode' settings as the internal cluster does.
|
||||
*/
|
||||
@SuppressForbidden(reason = "modifies system properties intentionally")
|
||||
public class TribeUnitTests extends ESTestCase {
|
||||
|
||||
private static Node tribe1;
|
|
@ -84,6 +84,9 @@ public class BootstrapForTesting {
|
|||
// initialize probes
|
||||
Bootstrap.initializeProbes();
|
||||
|
||||
// initialize sysprops
|
||||
BootstrapInfo.getSystemProperties();
|
||||
|
||||
// check for jar hell
|
||||
try {
|
||||
JarHell.checkJarHell();
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.common.cli;
|
|||
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.StreamsUtils;
|
||||
import org.junit.After;
|
||||
|
@ -40,11 +41,13 @@ import static org.hamcrest.Matchers.hasSize;
|
|||
public abstract class CliToolTestCase extends ESTestCase {
|
||||
|
||||
@Before
|
||||
@SuppressForbidden(reason = "sets es.default.path.home during tests")
|
||||
public void setPathHome() {
|
||||
System.setProperty("es.default.path.home", createTempDir().toString());
|
||||
}
|
||||
|
||||
@After
|
||||
@SuppressForbidden(reason = "clears es.default.path.home during tests")
|
||||
public void clearPathHome() {
|
||||
System.clearProperty("es.default.path.home");
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.elasticsearch.bootstrap.BootstrapForTesting;
|
|||
import org.elasticsearch.cache.recycler.MockPageCacheRecycler;
|
||||
import org.elasticsearch.client.Requests;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.io.PathUtils;
|
||||
import org.elasticsearch.common.io.PathUtilsForTesting;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
|
@ -163,6 +164,7 @@ public abstract class ESTestCase extends LuceneTestCase {
|
|||
// randomize and override the number of cpus so tests reproduce regardless of real number of cpus
|
||||
|
||||
@BeforeClass
|
||||
@SuppressForbidden(reason = "sets the number of cpus during tests")
|
||||
public static void setProcessors() {
|
||||
int numCpu = TestUtil.nextInt(random(), 1, 4);
|
||||
System.setProperty(EsExecutors.DEFAULT_SYSPROP, Integer.toString(numCpu));
|
||||
|
@ -170,6 +172,7 @@ public abstract class ESTestCase extends LuceneTestCase {
|
|||
}
|
||||
|
||||
@AfterClass
|
||||
@SuppressForbidden(reason = "clears the number of cpus during tests")
|
||||
public static void restoreProcessors() {
|
||||
System.clearProperty(EsExecutors.DEFAULT_SYSPROP);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue