Merge branch 'master' into fix/client-cookie

Original commit: elastic/x-pack-elasticsearch@a9920d5626
This commit is contained in:
Lukas Olson 2016-05-24 11:39:42 -07:00
commit 00fba58c56
63 changed files with 339 additions and 310 deletions

View File

@ -5,6 +5,8 @@ dependencies {
testCompile "org.elasticsearch.test:framework:${version}" testCompile "org.elasticsearch.test:framework:${version}"
} }
compactProfile = 'full'
dependencyLicenses.enabled = false dependencyLicenses.enabled = false
jar { jar {

View File

@ -6,8 +6,6 @@
package org.elasticsearch.license.core; package org.elasticsearch.license.core;
import org.elasticsearch.common.Base64;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException; import javax.crypto.IllegalBlockSizeException;
@ -27,6 +25,7 @@ import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class CryptUtils { public class CryptUtils {
private static final int minimumPadding = 20; private static final int minimumPadding = 20;
@ -251,6 +250,6 @@ public class CryptUtils {
private static char[] hashPassPhrase(String passPhrase) throws NoSuchAlgorithmException { private static char[] hashPassPhrase(String passPhrase) throws NoSuchAlgorithmException {
final byte[] passBytes = passPhrase.getBytes(StandardCharsets.UTF_8); final byte[] passBytes = passPhrase.getBytes(StandardCharsets.UTF_8);
final byte[] digest = MessageDigest.getInstance(passHashAlgorithm).digest(passBytes); final byte[] digest = MessageDigest.getInstance(passHashAlgorithm).digest(passBytes);
return new String(Base64.encodeBytesToBytes(digest), StandardCharsets.UTF_8).toCharArray(); return Base64.getEncoder().encodeToString(digest).toCharArray();
} }
} }

View File

@ -8,7 +8,6 @@ package org.elasticsearch.license.core;
import org.apache.lucene.util.CollectionUtil; import org.apache.lucene.util.CollectionUtil;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
@ -20,6 +19,7 @@ import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -388,7 +388,7 @@ public class License implements ToXContent {
} }
// not a license spec // not a license spec
if (builder.signature != null) { if (builder.signature != null) {
byte[] signatureBytes = Base64.decode(builder.signature); byte[] signatureBytes = Base64.getDecoder().decode(builder.signature);
ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes); ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes);
int version = byteBuffer.getInt(); int version = byteBuffer.getInt();
// we take the absolute version, because negative versions // we take the absolute version, because negative versions
@ -415,10 +415,10 @@ public class License implements ToXContent {
*/ */
public static boolean isAutoGeneratedLicense(String signature) { public static boolean isAutoGeneratedLicense(String signature) {
try { try {
byte[] signatureBytes = Base64.decode(signature); byte[] signatureBytes = Base64.getDecoder().decode(signature);
ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes); ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes);
return byteBuffer.getInt() < 0; return byteBuffer.getInt() < 0;
} catch (IOException e) { } catch (IllegalArgumentException e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
} }

View File

@ -5,7 +5,6 @@
*/ */
package org.elasticsearch.license.core; package org.elasticsearch.license.core;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
@ -18,6 +17,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.Signature; import java.security.Signature;
import java.security.SignatureException; import java.security.SignatureException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Base64;
import java.util.Collections; import java.util.Collections;
/** /**
@ -35,7 +35,7 @@ public class LicenseVerifier {
byte[] signedContent = null; byte[] signedContent = null;
byte[] signatureHash = null; byte[] signatureHash = null;
try { try {
byte[] signatureBytes = Base64.decode(license.signature()); byte[] signatureBytes = Base64.getDecoder().decode(license.signature());
ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes); ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes);
int version = byteBuffer.getInt(); int version = byteBuffer.getInt();
int magicLen = byteBuffer.getInt(); int magicLen = byteBuffer.getInt();
@ -53,7 +53,7 @@ public class LicenseVerifier {
rsa.initVerify(CryptUtils.readEncryptedPublicKey(encryptedPublicKeyData)); rsa.initVerify(CryptUtils.readEncryptedPublicKey(encryptedPublicKeyData));
rsa.update(contentBuilder.bytes().toBytes()); rsa.update(contentBuilder.bytes().toBytes());
return rsa.verify(signedContent) return rsa.verify(signedContent)
&& Arrays.equals(Base64.encodeBytesToBytes(encryptedPublicKeyData), signatureHash); && Arrays.equals(Base64.getEncoder().encode(encryptedPublicKeyData), signatureHash);
} catch (IOException | NoSuchAlgorithmException | SignatureException | InvalidKeyException e) { } catch (IOException | NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} finally { } finally {

View File

@ -5,7 +5,6 @@
*/ */
package org.elasticsearch.license.licensor; package org.elasticsearch.license.licensor;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
@ -22,6 +21,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.Signature; import java.security.Signature;
import java.security.SignatureException; import java.security.SignatureException;
import java.util.Base64;
import java.util.Collections; import java.util.Collections;
/** /**
@ -63,7 +63,7 @@ public class LicenseSigner {
final byte[] magic = new byte[MAGIC_LENGTH]; final byte[] magic = new byte[MAGIC_LENGTH];
SecureRandom random = new SecureRandom(); SecureRandom random = new SecureRandom();
random.nextBytes(magic); random.nextBytes(magic);
final byte[] hash = Base64.encodeBytesToBytes(Files.readAllBytes(publicKeyPath)); final byte[] hash = Base64.getEncoder().encode(Files.readAllBytes(publicKeyPath));
assert hash != null; assert hash != null;
byte[] bytes = new byte[4 + 4 + MAGIC_LENGTH + 4 + hash.length + 4 + signedContent.length]; byte[] bytes = new byte[4 + 4 + MAGIC_LENGTH + 4 + hash.length + 4 + signedContent.length];
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
@ -76,7 +76,7 @@ public class LicenseSigner {
.put(signedContent); .put(signedContent);
return License.builder() return License.builder()
.fromLicenseSpec(licenseSpec, Base64.encodeBytes(bytes)) .fromLicenseSpec(licenseSpec, Base64.getEncoder().encodeToString(bytes))
.build(); .build();
} }
} }

View File

@ -10,7 +10,6 @@ import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType; import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Requests; import org.elasticsearch.client.Requests;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.io.Streams;
@ -60,6 +59,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -214,7 +214,7 @@ public class SearchTransformIT extends ESIntegTestCase {
assertThat(map.get("query"), instanceOf(String.class)); assertThat(map.get("query"), instanceOf(String.class));
String queryAsBase64 = (String) map.get("query"); String queryAsBase64 = (String) map.get("query");
String decodedQuery = new String(Base64.decode(queryAsBase64), StandardCharsets.UTF_8); String decodedQuery = new String(Base64.getDecoder().decode(queryAsBase64), StandardCharsets.UTF_8);
assertThat(decodedQuery, containsString("_unknown_query_")); assertThat(decodedQuery, containsString("_unknown_query_"));
} }

View File

@ -140,12 +140,12 @@ def smoke_test_release(release, files, expected_hash):
# put the supplied license to ensure that system was built with # put the supplied license to ensure that system was built with
license = read_fully(os.path.join(os.path.dirname(__file__), 'license.json')) license = read_fully(os.path.join(os.path.dirname(__file__), 'license.json'))
conn.request('PUT', '/_license?acknowledge=true', license, headers=headers) conn.request('PUT', '/_xpack/license?acknowledge=true', license, headers=headers)
res = conn.getresponse() res = conn.getresponse()
# reading the result, so we can execute the next request on the same connection # reading the result, so we can execute the next request on the same connection
license_resp = json.loads(res.read().decode('utf-8')) license_resp = json.loads(res.read().decode('utf-8'))
if res.status != 200: if res.status != 200:
raise RuntimeError('Could not PUT _license, got status %s' % res.status) raise RuntimeError('Could not PUT _xpack/license, got status %s' % res.status)
if license_resp['license_status'] != 'valid': if license_resp['license_status'] != 'valid':
raise RuntimeError('Expected license to be valid, but was %s' % license_resp['license_status']) raise RuntimeError('Expected license to be valid, but was %s' % license_resp['license_status'])

View File

@ -35,6 +35,10 @@ dependencies {
compile 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:r239' compile 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:r239'
compile 'com.google.guava:guava:16.0.1' // needed by watcher for the html sanitizer and shield tests for jimfs compile 'com.google.guava:guava:16.0.1' // needed by watcher for the html sanitizer and shield tests for jimfs
compile 'com.sun.mail:javax.mail:1.5.3' compile 'com.sun.mail:javax.mail:1.5.3'
// HACK: java 9 removed javax.activation from the default modules, so instead of trying to add modules, which would have
// to be conditionalized for java 8/9, we pull in the classes directly
compile 'javax.activation:activation:1.1'
testCompile 'org.subethamail:subethasmtp:3.1.7' testCompile 'org.subethamail:subethasmtp:3.1.7'
// needed for subethasmtp, has @GuardedBy annotation // needed for subethasmtp, has @GuardedBy annotation
testCompile 'com.google.code.findbugs:jsr305:3.0.1' testCompile 'com.google.code.findbugs:jsr305:3.0.1'
@ -169,6 +173,42 @@ thirdPartyAudit.excludes = [
'com.google.common.cache.Striped64$Cell', 'com.google.common.cache.Striped64$Cell',
'com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator', 'com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator',
'com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator$1', 'com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator$1',
// pulled in as external dependency to work on java 9
'com.sun.activation.registries.LineTokenizer',
'com.sun.activation.registries.LogSupport',
'com.sun.activation.registries.MailcapFile',
'com.sun.activation.registries.MailcapParseException',
'com.sun.activation.registries.MailcapTokenizer',
'com.sun.activation.registries.MimeTypeEntry',
'com.sun.activation.registries.MimeTypeFile',
'javax.activation.ActivationDataFlavor',
'javax.activation.CommandInfo',
'javax.activation.CommandMap',
'javax.activation.CommandObject',
'javax.activation.DataContentHandler',
'javax.activation.DataContentHandlerFactory',
'javax.activation.DataHandler$1',
'javax.activation.DataHandler',
'javax.activation.DataHandlerDataSource',
'javax.activation.DataSource',
'javax.activation.DataSourceDataContentHandler',
'javax.activation.FileDataSource',
'javax.activation.FileTypeMap',
'javax.activation.MailcapCommandMap',
'javax.activation.MimeType',
'javax.activation.MimeTypeParameterList',
'javax.activation.MimeTypeParseException',
'javax.activation.MimetypesFileTypeMap',
'javax.activation.ObjectDataContentHandler',
'javax.activation.SecuritySupport$1',
'javax.activation.SecuritySupport$2',
'javax.activation.SecuritySupport$3',
'javax.activation.SecuritySupport$4',
'javax.activation.SecuritySupport$5',
'javax.activation.SecuritySupport',
'javax.activation.URLDataSource',
'javax.activation.UnsupportedDataTypeException'
] ]
// someone figure out what the x-plugins logic should be // someone figure out what the x-plugins logic should be

View File

@ -9,7 +9,6 @@ import org.apache.lucene.util.CollectionUtil;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.cluster.AbstractDiffable; import org.elasticsearch.cluster.AbstractDiffable;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
@ -21,6 +20,7 @@ import org.elasticsearch.license.core.License;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
@ -114,7 +114,7 @@ public class LicensesMetaData extends AbstractDiffable<MetaData.Custom> implemen
while (parser.nextToken() != XContentParser.Token.END_ARRAY) { while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
if (parser.currentToken().isValue()) { if (parser.currentToken().isValue()) {
// trial license // trial license
byte[] data = decrypt(Base64.decode(parser.text())); byte[] data = decrypt(Base64.getDecoder().decode(parser.text()));
try (XContentParser trialLicenseParser = try (XContentParser trialLicenseParser =
XContentFactory.xContent(XContentType.JSON).createParser(data)) { XContentFactory.xContent(XContentType.JSON).createParser(data)) {
trialLicenseParser.nextToken(); trialLicenseParser.nextToken();
@ -186,7 +186,7 @@ public class LicensesMetaData extends AbstractDiffable<MetaData.Custom> implemen
XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON); XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON);
license.toXContent(contentBuilder, license.toXContent(contentBuilder,
new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true"))); new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true")));
streamOutput.writeString(Base64.encodeBytes(encrypt(contentBuilder.bytes().toBytes()))); streamOutput.writeString(Base64.getEncoder().encodeToString(encrypt(contentBuilder.bytes().toBytes())));
} }
} else { } else {
if (license == LICENSE_TOMBSTONE) { if (license == LICENSE_TOMBSTONE) {
@ -209,7 +209,7 @@ public class LicensesMetaData extends AbstractDiffable<MetaData.Custom> implemen
} }
int numTrialLicenses = streamInput.readVInt(); int numTrialLicenses = streamInput.readVInt();
for (int i = 0; i < numTrialLicenses; i++) { for (int i = 0; i < numTrialLicenses; i++) {
byte[] data = decrypt(Base64.decode(streamInput.readString())); byte[] data = decrypt(Base64.getDecoder().decode(streamInput.readString()));
try (XContentParser trialLicenseParser = XContentFactory.xContent(XContentType.JSON).createParser(data)) { try (XContentParser trialLicenseParser = XContentFactory.xContent(XContentType.JSON).createParser(data)) {
trialLicenseParser.nextToken(); trialLicenseParser.nextToken();
License pre20TrialLicense = License.fromXContent(trialLicenseParser); License pre20TrialLicense = License.fromXContent(trialLicenseParser);

View File

@ -149,7 +149,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
} }
private void populateExpirationCallbacks() { private void populateExpirationCallbacks() {
expirationCallbacks.add(new ExpirationCallback.Pre(days(7), days(30), days(1)) { expirationCallbacks.add(new ExpirationCallback.Pre(days(7), days(25), days(1)) {
@Override @Override
public void on(License license) { public void on(License license) {
String general = LoggerMessageFormat.format(null, "\n" + String general = LoggerMessageFormat.format(null, "\n" +
@ -174,9 +174,9 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
} }
} }
} }
logger.error("{}", builder); logger.warn("{}", builder);
} else { } else {
logger.error("{}", general); logger.warn("{}", general);
} }
} }
} }
@ -206,9 +206,9 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
} }
} }
} }
logger.error("{}", builder.toString()); logger.warn("{}", builder.toString());
} else { } else {
logger.error("{}", general); logger.warn("{}", general);
} }
} }
} }
@ -238,9 +238,9 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
} }
} }
} }
logger.error("{}", builder.toString()); logger.warn("{}", builder.toString());
} else { } else {
logger.error("{}", general); logger.warn("{}", general);
} }
} }
} }

View File

@ -5,7 +5,6 @@
*/ */
package org.elasticsearch.license.plugin.core; package org.elasticsearch.license.plugin.core;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
@ -15,6 +14,7 @@ import org.elasticsearch.license.core.License;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Base64;
import java.util.Collections; import java.util.Collections;
import static org.elasticsearch.license.core.CryptUtils.decrypt; import static org.elasticsearch.license.core.CryptUtils.decrypt;
@ -39,7 +39,7 @@ public class TrialLicense {
byteBuffer.putInt(-License.VERSION_CURRENT) byteBuffer.putInt(-License.VERSION_CURRENT)
.putInt(encrypt.length) .putInt(encrypt.length)
.put(encrypt); .put(encrypt);
signature = Base64.encodeBytes(bytes); signature = Base64.getEncoder().encodeToString(bytes);
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
@ -48,7 +48,7 @@ public class TrialLicense {
public static boolean verify(final License license) { public static boolean verify(final License license) {
try { try {
byte[] signatureBytes = Base64.decode(license.signature()); byte[] signatureBytes = Base64.getDecoder().decode(license.signature());
ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes); ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes);
int version = byteBuffer.getInt(); int version = byteBuffer.getInt();
int contentLen = byteBuffer.getInt(); int contentLen = byteBuffer.getInt();

View File

@ -23,7 +23,7 @@ public class RestDeleteLicenseAction extends BaseRestHandler {
@Inject @Inject
public RestDeleteLicenseAction(Settings settings, RestController controller, Client client) { public RestDeleteLicenseAction(Settings settings, RestController controller, Client client) {
super(settings, client); super(settings, client);
controller.registerHandler(DELETE, "/_license", this); controller.registerHandler(DELETE, "/_xpack/license", this);
} }
@Override @Override

View File

@ -34,7 +34,7 @@ public class RestGetLicenseAction extends BaseRestHandler {
@Inject @Inject
public RestGetLicenseAction(Settings settings, RestController controller, Client client) { public RestGetLicenseAction(Settings settings, RestController controller, Client client) {
super(settings, client); super(settings, client);
controller.registerHandler(GET, "/_license", this); controller.registerHandler(GET, "/_xpack/license", this);
} }
/** /**

View File

@ -30,8 +30,8 @@ public class RestPutLicenseAction extends BaseRestHandler {
@Inject @Inject
public RestPutLicenseAction(Settings settings, RestController controller, Client client) { public RestPutLicenseAction(Settings settings, RestController controller, Client client) {
super(settings, client); super(settings, client);
controller.registerHandler(PUT, "/_license", this); controller.registerHandler(PUT, "/_xpack/license", this);
controller.registerHandler(POST, "/_license", this); controller.registerHandler(POST, "/_xpack/license", this);
} }
@Override @Override

View File

@ -5,7 +5,6 @@
*/ */
package org.elasticsearch.license.plugin; package org.elasticsearch.license.plugin;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
@ -17,6 +16,7 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Base64;
import java.util.Collections; import java.util.Collections;
import java.util.UUID; import java.util.UUID;
@ -102,7 +102,7 @@ public class TrialLicenseTests extends ESTestCase {
byteBuffer.putInt(-spec.version()) byteBuffer.putInt(-spec.version())
.putInt(encrypt.length) .putInt(encrypt.length)
.put(encrypt); .put(encrypt);
signature = Base64.encodeBytes(bytes); signature = Base64.getEncoder().encodeToString(bytes);
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }

View File

@ -9,7 +9,6 @@ import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.metadata.RepositoriesMetaData; import org.elasticsearch.cluster.metadata.RepositoriesMetaData;
import org.elasticsearch.cluster.metadata.RepositoryMetaData; import org.elasticsearch.cluster.metadata.RepositoryMetaData;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.io.stream.ByteBufferStreamInput; import org.elasticsearch.common.io.stream.ByteBufferStreamInput;
import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
@ -26,6 +25,7 @@ import org.elasticsearch.license.plugin.TestUtils;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Base64;
import java.util.Collections; import java.util.Collections;
import java.util.UUID; import java.util.UUID;
@ -113,7 +113,7 @@ public class LicensesMetaDataSerializationTests extends ESTestCase {
builder.startArray("trial_licenses"); builder.startArray("trial_licenses");
XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON); XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON);
trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true"))); trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true")));
builder.value(Base64.encodeBytes(encrypt(contentBuilder.bytes().toBytes()))); builder.value(Base64.getEncoder().encodeToString(encrypt(contentBuilder.bytes().toBytes())));
builder.endArray(); builder.endArray();
builder.startArray("signed_licenses"); builder.startArray("signed_licenses");
builder.endArray(); builder.endArray();
@ -143,7 +143,7 @@ public class LicensesMetaDataSerializationTests extends ESTestCase {
builder.startArray("trial_licenses"); builder.startArray("trial_licenses");
contentBuilder = XContentFactory.contentBuilder(XContentType.JSON); contentBuilder = XContentFactory.contentBuilder(XContentType.JSON);
trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true"))); trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true")));
builder.value(Base64.encodeBytes(encrypt(contentBuilder.bytes().toBytes()))); builder.value(Base64.getEncoder().encodeToString(encrypt(contentBuilder.bytes().toBytes())));
builder.endArray(); builder.endArray();
builder.startArray("signed_licenses"); builder.startArray("signed_licenses");
signedLicense.toXContent(builder, ToXContent.EMPTY_PARAMS); signedLicense.toXContent(builder, ToXContent.EMPTY_PARAMS);
@ -162,7 +162,7 @@ public class LicensesMetaDataSerializationTests extends ESTestCase {
builder.startArray("trial_licenses"); builder.startArray("trial_licenses");
contentBuilder = XContentFactory.contentBuilder(XContentType.JSON); contentBuilder = XContentFactory.contentBuilder(XContentType.JSON);
trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true"))); trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true")));
builder.value(Base64.encodeBytes(encrypt(contentBuilder.bytes().toBytes()))); builder.value(Base64.getEncoder().encodeToString(encrypt(contentBuilder.bytes().toBytes())));
builder.endArray(); builder.endArray();
builder.startArray("signed_licenses"); builder.startArray("signed_licenses");
signedLicense.toXContent(builder, ToXContent.EMPTY_PARAMS); signedLicense.toXContent(builder, ToXContent.EMPTY_PARAMS);
@ -190,7 +190,7 @@ public class LicensesMetaDataSerializationTests extends ESTestCase {
output.writeVInt(1); output.writeVInt(1);
XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON); XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON);
trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true"))); trialLicense.toXContent(contentBuilder, new ToXContent.MapParams(Collections.singletonMap(License.LICENSE_SPEC_VIEW_MODE, "true")));
output.writeString(Base64.encodeBytes(encrypt(contentBuilder.bytes().toBytes()))); output.writeString(Base64.getEncoder().encodeToString(encrypt(contentBuilder.bytes().toBytes())));
byte[] bytes = output.bytes().toBytes(); byte[] bytes = output.bytes().toBytes();
ByteBufferStreamInput input = new ByteBufferStreamInput(ByteBuffer.wrap(bytes)); ByteBufferStreamInput input = new ByteBufferStreamInput(ByteBuffer.wrap(bytes));

View File

@ -3,8 +3,8 @@
"documentation": "https://www.elastic.co/guide/en/shield/current/license-management.html", "documentation": "https://www.elastic.co/guide/en/shield/current/license-management.html",
"methods": ["DELETE"], "methods": ["DELETE"],
"url": { "url": {
"path": "/_license", "path": "/_xpack/license",
"paths": ["/_license"], "paths": ["/_xpack/license"],
"parts" : {} "parts" : {}
}, },
"body": null "body": null

View File

@ -3,8 +3,8 @@
"documentation": "https://www.elastic.co/guide/en/shield/current/license-management.html", "documentation": "https://www.elastic.co/guide/en/shield/current/license-management.html",
"methods": ["GET"], "methods": ["GET"],
"url": { "url": {
"path": "/_license", "path": "/_xpack/license",
"paths": ["/_license"], "paths": ["/_xpack/license"],
"parts" : { "parts" : {
}, },
"params": { "params": {

View File

@ -3,8 +3,8 @@
"documentation": "https://www.elastic.co/guide/en/shield/current/license-management.html", "documentation": "https://www.elastic.co/guide/en/shield/current/license-management.html",
"methods": ["PUT", "POST"], "methods": ["PUT", "POST"],
"url": { "url": {
"path": "/_license", "path": "/_xpack/license",
"paths": ["/_license"], "paths": ["/_xpack/license"],
"parts" : { "parts" : {
}, },
"params": { "params": {

View File

@ -9,7 +9,6 @@ import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.SpecialPermission; import org.elasticsearch.SpecialPermission;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
@ -53,6 +52,7 @@ import java.security.AccessController;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -683,7 +683,7 @@ public class HttpExporter extends Exporter {
void apply(HttpURLConnection connection) throws UnsupportedEncodingException { void apply(HttpURLConnection connection) throws UnsupportedEncodingException {
String userInfo = username + ":" + (password != null ? new String(password) : ""); String userInfo = username + ":" + (password != null ? new String(password) : "");
String basicAuth = "Basic " + Base64.encodeBytes(userInfo.getBytes("ISO-8859-1")); String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userInfo.getBytes("ISO-8859-1"));
connection.setRequestProperty("Authorization", basicAuth); connection.setRequestProperty("Authorization", basicAuth);
} }
} }

View File

@ -161,7 +161,7 @@ public abstract class AbstractCollectorTestCase extends MarvelIntegTestCase {
public void run() { public void run() {
for (String nodeId : internalCluster().getNodeNames()) { for (String nodeId : internalCluster().getNodeNames()) {
try { try {
assertTrue(waitForNoBlocksOnNode(nodeId)); waitForNoBlocksOnNode(nodeId);
} catch (Exception e) { } catch (Exception e) {
fail("failed to wait for no blocks on node [" + nodeId + "]: " + e.getMessage()); fail("failed to wait for no blocks on node [" + nodeId + "]: " + e.getMessage());
} }
@ -170,13 +170,12 @@ public abstract class AbstractCollectorTestCase extends MarvelIntegTestCase {
}); });
} }
public boolean waitForNoBlocksOnNode(final String nodeId) throws Exception { public void waitForNoBlocksOnNode(final String nodeId) throws Exception {
return assertBusy(() -> { assertBusy(() -> {
ClusterBlocks clusterBlocks = ClusterBlocks clusterBlocks =
client(nodeId).admin().cluster().prepareState().setLocal(true).execute().actionGet().getState().blocks(); client(nodeId).admin().cluster().prepareState().setLocal(true).execute().actionGet().getState().blocks();
assertTrue(clusterBlocks.global().isEmpty()); assertTrue(clusterBlocks.global().isEmpty());
assertTrue(clusterBlocks.indices().values().isEmpty()); assertTrue(clusterBlocks.indices().values().isEmpty());
return true;
}, 30L, TimeUnit.SECONDS); }, 30L, TimeUnit.SECONDS);
} }

View File

@ -121,7 +121,8 @@ public abstract class AbstractExporterTemplateTestCase extends MarvelIntegTestCa
assertNotNull(exporters); assertNotNull(exporters);
// Wait for exporting bulks to be ready to export // Wait for exporting bulks to be ready to export
assertBusy(() -> assertThat(exporters.openBulk(), notNullValue())); Runnable busy = () -> assertThat(exporters.openBulk(), notNullValue());
assertBusy(busy);
exporters.export(collector.collect()); exporters.export(collector.collect());
} }

View File

@ -93,7 +93,8 @@ public class HttpExporterTemplateTests extends AbstractExporterTemplateTestCase
@Override @Override
protected void awaitIndexExists(String index) throws Exception { protected void awaitIndexExists(String index) throws Exception {
assertBusy(() -> assertThat("could not find index " + index, dispatcher.hasIndex(index), is(true)), 10, TimeUnit.SECONDS); Runnable busy = () -> assertThat("could not find index " + index, dispatcher.hasIndex(index), is(true));
assertBusy(busy, 10, TimeUnit.SECONDS);
} }
class MockServerDispatcher extends Dispatcher { class MockServerDispatcher extends Dispatcher {

View File

@ -7,7 +7,6 @@ package org.elasticsearch.shield.authc;
import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
@ -29,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportMessage; import org.elasticsearch.transport.TransportMessage;
import java.io.IOException; import java.io.IOException;
import java.util.Base64;
import static org.elasticsearch.shield.Security.setting; import static org.elasticsearch.shield.Security.setting;
import static org.elasticsearch.shield.support.Exceptions.authenticationError; import static org.elasticsearch.shield.support.Exceptions.authenticationError;
@ -157,7 +157,7 @@ public class InternalAuthenticationService extends AbstractComponent implements
static User decodeUser(String text) { static User decodeUser(String text) {
try { try {
byte[] bytes = Base64.decode(text); byte[] bytes = Base64.getDecoder().decode(text);
StreamInput input = StreamInput.wrap(bytes); StreamInput input = StreamInput.wrap(bytes);
Version version = Version.readVersion(input); Version version = Version.readVersion(input);
input.setVersion(version); input.setVersion(version);
@ -173,7 +173,7 @@ public class InternalAuthenticationService extends AbstractComponent implements
Version.writeVersion(Version.CURRENT, output); Version.writeVersion(Version.CURRENT, output);
User.writeTo(user, output); User.writeTo(user, output);
byte[] bytes = output.bytes().toBytes(); byte[] bytes = output.bytes().toBytes();
return Base64.encodeBytes(bytes); return Base64.getEncoder().encodeToString(bytes);
} catch (IOException ioe) { } catch (IOException ioe) {
if (logger != null) { if (logger != null) {
logger.error("could not encode authenticated user in message header... falling back to token headers", ioe); logger.error("could not encode authenticated user in message header... falling back to token headers", ioe);

View File

@ -18,7 +18,7 @@ import org.elasticsearch.shield.support.Exceptions;
import org.elasticsearch.shield.user.AnonymousUser; import org.elasticsearch.shield.user.AnonymousUser;
import org.elasticsearch.shield.user.KibanaUser; import org.elasticsearch.shield.user.KibanaUser;
import org.elasticsearch.shield.user.User; import org.elasticsearch.shield.user.User;
import org.elasticsearch.shield.user.XPackUser; import org.elasticsearch.shield.user.ElasticUser;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -86,7 +86,7 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
public static boolean isReserved(String username) { public static boolean isReserved(String username) {
assert username != null; assert username != null;
switch (username) { switch (username) {
case XPackUser.NAME: case ElasticUser.NAME:
case KibanaUser.NAME: case KibanaUser.NAME:
return true; return true;
default: default:
@ -97,8 +97,8 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
public static User getUser(String username) { public static User getUser(String username) {
assert username != null; assert username != null;
switch (username) { switch (username) {
case XPackUser.NAME: case ElasticUser.NAME:
return XPackUser.INSTANCE; return ElasticUser.INSTANCE;
case KibanaUser.NAME: case KibanaUser.NAME:
return KibanaUser.INSTANCE; return KibanaUser.INSTANCE;
default: default:
@ -111,9 +111,9 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
public static Collection<User> users() { public static Collection<User> users() {
if (AnonymousUser.enabled()) { if (AnonymousUser.enabled()) {
return Arrays.asList(XPackUser.INSTANCE, KibanaUser.INSTANCE, AnonymousUser.INSTANCE); return Arrays.asList(ElasticUser.INSTANCE, KibanaUser.INSTANCE, AnonymousUser.INSTANCE);
} }
return Arrays.asList(XPackUser.INSTANCE, KibanaUser.INSTANCE); return Arrays.asList(ElasticUser.INSTANCE, KibanaUser.INSTANCE);
} }
private char[] getPasswordHash(final String username) { private char[] getPasswordHash(final String username) {

View File

@ -5,13 +5,12 @@
*/ */
package org.elasticsearch.shield.authc.support; package org.elasticsearch.shield.authc.support;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.Randomness; import org.elasticsearch.common.Randomness;
import org.elasticsearch.common.hash.MessageDigests; import org.elasticsearch.common.hash.MessageDigests;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.util.Base64;
import java.util.Locale; import java.util.Locale;
import java.util.Random; import java.util.Random;
@ -145,7 +144,7 @@ public enum Hasher {
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars()); byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
MessageDigest md = MessageDigests.sha1(); MessageDigest md = MessageDigests.sha1();
md.update(textBytes); md.update(textBytes);
String hash = Base64.encodeBytes(md.digest()); String hash = Base64.getEncoder().encodeToString(md.digest());
return (SHA1_PREFIX + hash).toCharArray(); return (SHA1_PREFIX + hash).toCharArray();
} }
@ -158,7 +157,7 @@ public enum Hasher {
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars()); byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
MessageDigest md = MessageDigests.sha1(); MessageDigest md = MessageDigests.sha1();
md.update(textBytes); md.update(textBytes);
String passwd64 = Base64.encodeBytes(md.digest()); String passwd64 = Base64.getEncoder().encodeToString(md.digest());
String hashNoPrefix = hashStr.substring(SHA1_PREFIX.length()); String hashNoPrefix = hashStr.substring(SHA1_PREFIX.length());
return SecuredString.constantTimeEquals(hashNoPrefix, passwd64); return SecuredString.constantTimeEquals(hashNoPrefix, passwd64);
} }
@ -169,7 +168,7 @@ public enum Hasher {
public char[] hash(SecuredString text) { public char[] hash(SecuredString text) {
MessageDigest md = MessageDigests.md5(); MessageDigest md = MessageDigests.md5();
md.update(CharArrays.toUtf8Bytes(text.internalChars())); md.update(CharArrays.toUtf8Bytes(text.internalChars()));
String hash = Base64.encodeBytes(md.digest()); String hash = Base64.getEncoder().encodeToString(md.digest());
return (MD5_PREFIX + hash).toCharArray(); return (MD5_PREFIX + hash).toCharArray();
} }
@ -182,7 +181,7 @@ public enum Hasher {
hashStr = hashStr.substring(MD5_PREFIX.length()); hashStr = hashStr.substring(MD5_PREFIX.length());
MessageDigest md = MessageDigests.md5(); MessageDigest md = MessageDigests.md5();
md.update(CharArrays.toUtf8Bytes(text.internalChars())); md.update(CharArrays.toUtf8Bytes(text.internalChars()));
String computedHashStr = Base64.encodeBytes(md.digest()); String computedHashStr = Base64.getEncoder().encodeToString(md.digest());
return SecuredString.constantTimeEquals(hashStr, computedHashStr); return SecuredString.constantTimeEquals(hashStr, computedHashStr);
} }
}, },
@ -194,7 +193,7 @@ public enum Hasher {
md.update(CharArrays.toUtf8Bytes(text.internalChars())); md.update(CharArrays.toUtf8Bytes(text.internalChars()));
char[] salt = SaltProvider.salt(8); char[] salt = SaltProvider.salt(8);
md.update(CharArrays.toUtf8Bytes(salt)); md.update(CharArrays.toUtf8Bytes(salt));
String hash = Base64.encodeBytes(md.digest()); String hash = Base64.getEncoder().encodeToString(md.digest());
char[] result = new char[SSHA256_PREFIX.length() + salt.length + hash.length()]; char[] result = new char[SSHA256_PREFIX.length() + salt.length + hash.length()];
System.arraycopy(SSHA256_PREFIX.toCharArray(), 0, result, 0, SSHA256_PREFIX.length()); System.arraycopy(SSHA256_PREFIX.toCharArray(), 0, result, 0, SSHA256_PREFIX.length());
System.arraycopy(salt, 0, result, SSHA256_PREFIX.length(), salt.length); System.arraycopy(salt, 0, result, SSHA256_PREFIX.length(), salt.length);
@ -213,7 +212,7 @@ public enum Hasher {
MessageDigest md = MessageDigests.sha256(); MessageDigest md = MessageDigests.sha256();
md.update(CharArrays.toUtf8Bytes(text.internalChars())); md.update(CharArrays.toUtf8Bytes(text.internalChars()));
md.update(new String(saltAndHash, 0, 8).getBytes(StandardCharsets.UTF_8)); md.update(new String(saltAndHash, 0, 8).getBytes(StandardCharsets.UTF_8));
String computedHash = Base64.encodeBytes(md.digest()); String computedHash = Base64.getEncoder().encodeToString(md.digest());
return SecuredString.constantTimeEquals(computedHash, new String(saltAndHash, 8, saltAndHash.length - 8)); return SecuredString.constantTimeEquals(computedHash, new String(saltAndHash, 8, saltAndHash.length - 8));
} }
}, },

View File

@ -5,13 +5,12 @@
*/ */
package org.elasticsearch.shield.authc.support; package org.elasticsearch.shield.authc.support;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.shield.authc.AuthenticationToken; import org.elasticsearch.shield.authc.AuthenticationToken;
import java.io.IOException;
import java.nio.CharBuffer; import java.nio.CharBuffer;
import java.util.Arrays; import java.util.Arrays;
import java.util.Base64;
import java.util.Objects; import java.util.Objects;
import static org.elasticsearch.shield.support.Exceptions.authenticationError; import static org.elasticsearch.shield.support.Exceptions.authenticationError;
@ -85,8 +84,8 @@ public class UsernamePasswordToken implements AuthenticationToken {
char[] userpasswd; char[] userpasswd;
try { try {
userpasswd = CharArrays.utf8BytesToChars(Base64.decode(headerValue.substring(BASIC_AUTH_PREFIX.length()).trim())); userpasswd = CharArrays.utf8BytesToChars(Base64.getDecoder().decode(headerValue.substring(BASIC_AUTH_PREFIX.length()).trim()));
} catch (IllegalArgumentException | IOException e) { } catch (IllegalArgumentException e) {
throw authenticationError("invalid basic authentication header encoding", e); throw authenticationError("invalid basic authentication header encoding", e);
} }
@ -109,7 +108,7 @@ public class UsernamePasswordToken implements AuthenticationToken {
chars.put(username).put(':').put(passwd.internalChars()); chars.put(username).put(':').put(passwd.internalChars());
//TODO we still have passwords in Strings in headers //TODO we still have passwords in Strings in headers
String basicToken = Base64.encodeBytes(CharArrays.toUtf8Bytes(chars.array())); String basicToken = Base64.getEncoder().encodeToString(CharArrays.toUtf8Bytes(chars.array()));
return "Basic " + basicToken; return "Basic " + basicToken;
} }
} }

View File

@ -17,7 +17,7 @@ public class KibanaRole extends Role {
private static final String[] CLUSTER_PRIVILEGES = new String[] { "monitor", MonitoringBulkAction.NAME}; private static final String[] CLUSTER_PRIVILEGES = new String[] { "monitor", MonitoringBulkAction.NAME};
private static final RoleDescriptor.IndicesPrivileges[] INDICES_PRIVILEGES = new RoleDescriptor.IndicesPrivileges[] { private static final RoleDescriptor.IndicesPrivileges[] INDICES_PRIVILEGES = new RoleDescriptor.IndicesPrivileges[] {
RoleDescriptor.IndicesPrivileges.builder().indices(".kibana").privileges("all").build() }; RoleDescriptor.IndicesPrivileges.builder().indices(".kibana*", ".reporting-*").privileges("all").build() };
public static final String NAME = "kibana"; public static final String NAME = "kibana";
public static final RoleDescriptor DESCRIPTOR = new RoleDescriptor(NAME, CLUSTER_PRIVILEGES, INDICES_PRIVILEGES, null); public static final RoleDescriptor DESCRIPTOR = new RoleDescriptor(NAME, CLUSTER_PRIVILEGES, INDICES_PRIVILEGES, null);

View File

@ -6,7 +6,6 @@
package org.elasticsearch.shield.crypto; package org.elasticsearch.shield.crypto;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
@ -39,6 +38,7 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Arrays; import java.util.Arrays;
import java.util.Base64;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -138,11 +138,7 @@ public class InternalCryptoService extends AbstractLifecycleComponent<InternalCr
keyFile = resolveSystemKey(settings, env); keyFile = resolveSystemKey(settings, env);
systemKey = readSystemKey(keyFile); systemKey = readSystemKey(keyFile);
randomKey = generateSecretKey(RANDOM_KEY_SIZE); randomKey = generateSecretKey(RANDOM_KEY_SIZE);
try { randomKeyBase64 = Base64.getUrlEncoder().encodeToString(randomKey.getEncoded());
randomKeyBase64 = Base64.encodeBytes(randomKey.getEncoded(), 0, randomKey.getEncoded().length, Base64.URL_SAFE);
} catch (IOException e) {
throw new ElasticsearchException("failed to encode key data as base64", e);
}
signingKey = createSigningKey(systemKey, randomKey); signingKey = createSigningKey(systemKey, randomKey);
@ -256,17 +252,17 @@ public class InternalCryptoService extends AbstractLifecycleComponent<InternalCr
} else { } else {
byte[] randomKeyBytes; byte[] randomKeyBytes;
try { try {
randomKeyBytes = Base64.decode(base64RandomKey, Base64.URL_SAFE); randomKeyBytes = Base64.getUrlDecoder().decode(base64RandomKey);
if (randomKeyBytes.length * 8 != RANDOM_KEY_SIZE) { } catch (IllegalArgumentException e) {
logger.debug("incorrect random key data length. received [{}] bytes", randomKeyBytes.length);
throw new IllegalArgumentException("tampered signed text");
}
SecretKey randomKey = new SecretKeySpec(randomKeyBytes, KEY_ALGO);
signingKey = createSigningKey(systemKey, randomKey);
} catch (IOException e) {
logger.error("error occurred while decoding key data", e); logger.error("error occurred while decoding key data", e);
throw new IllegalStateException("error while verifying the signed text"); throw new IllegalStateException("error while verifying the signed text");
} }
if (randomKeyBytes.length * 8 != RANDOM_KEY_SIZE) {
logger.debug("incorrect random key data length. received [{}] bytes", randomKeyBytes.length);
throw new IllegalArgumentException("tampered signed text");
}
SecretKey randomKey = new SecretKeySpec(randomKeyBytes, KEY_ALGO);
signingKey = createSigningKey(systemKey, randomKey);
} }
try { try {
@ -297,7 +293,7 @@ public class InternalCryptoService extends AbstractLifecycleComponent<InternalCr
} }
byte[] charBytes = CharArrays.toUtf8Bytes(chars); byte[] charBytes = CharArrays.toUtf8Bytes(chars);
String base64 = Base64.encodeBytes(encryptInternal(charBytes, key)); String base64 = Base64.getEncoder().encodeToString(encryptInternal(charBytes, key));
return ENCRYPTED_TEXT_PREFIX.concat(base64).toCharArray(); return ENCRYPTED_TEXT_PREFIX.concat(base64).toCharArray();
} }
@ -335,8 +331,8 @@ public class InternalCryptoService extends AbstractLifecycleComponent<InternalCr
String encrypted = new String(chars, ENCRYPTED_TEXT_PREFIX.length(), chars.length - ENCRYPTED_TEXT_PREFIX.length()); String encrypted = new String(chars, ENCRYPTED_TEXT_PREFIX.length(), chars.length - ENCRYPTED_TEXT_PREFIX.length());
byte[] bytes; byte[] bytes;
try { try {
bytes = Base64.decode(encrypted); bytes = Base64.getDecoder().decode(encrypted);
} catch (IOException e) { } catch (IllegalArgumentException e) {
throw new ElasticsearchException("unable to decode encrypted data", e); throw new ElasticsearchException("unable to decode encrypted data", e);
} }
@ -430,7 +426,7 @@ public class InternalCryptoService extends AbstractLifecycleComponent<InternalCr
private static String signInternal(String text, SecretKey key) throws IOException { private static String signInternal(String text, SecretKey key) throws IOException {
Mac mac = createMac(key); Mac mac = createMac(key);
byte[] sig = mac.doFinal(text.getBytes(StandardCharsets.UTF_8)); byte[] sig = mac.doFinal(text.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBytes(sig, 0, sig.length, Base64.URL_SAFE); return Base64.getUrlEncoder().encodeToString(sig);
} }

View File

@ -25,7 +25,7 @@ import static org.elasticsearch.shield.Security.setting;
*/ */
public class AnonymousUser extends ReservedUser { public class AnonymousUser extends ReservedUser {
public static final String DEFAULT_ANONYMOUS_USERNAME = "_es_anonymous_user"; public static final String DEFAULT_ANONYMOUS_USERNAME = "_anonymous";
public static final Setting<String> USERNAME_SETTING = public static final Setting<String> USERNAME_SETTING =
new Setting<>(setting("authc.anonymous.username"), DEFAULT_ANONYMOUS_USERNAME, s -> s, Property.NodeScope); new Setting<>(setting("authc.anonymous.username"), DEFAULT_ANONYMOUS_USERNAME, s -> s, Property.NodeScope);
public static final Setting<List<String>> ROLES_SETTING = public static final Setting<List<String>> ROLES_SETTING =

View File

@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.user;
import org.elasticsearch.shield.authz.permission.SuperuserRole;
import org.elasticsearch.shield.user.User.ReservedUser;
/**
* The reserved {@code elastic} superuser. As full permission/access to the cluster/indices and can
* run as any other user.
*/
public class ElasticUser extends ReservedUser {
public static final String NAME = "elastic";
public static final String ROLE_NAME = SuperuserRole.NAME;
public static final ElasticUser INSTANCE = new ElasticUser();
private ElasticUser() {
super(NAME, ROLE_NAME);
}
@Override
public boolean equals(Object o) {
return INSTANCE == o;
}
@Override
public int hashCode() {
return System.identityHashCode(this);
}
public static boolean is(User user) {
return INSTANCE.equals(user);
}
public static boolean is(String principal) {
return NAME.equals(principal);
}
}

View File

@ -16,8 +16,8 @@ import java.util.function.Predicate;
*/ */
public class SystemUser extends User { public class SystemUser extends User {
public static final String NAME = "__es_system_user"; public static final String NAME = "_system";
public static final String ROLE_NAME = "__es_system_role"; public static final String ROLE_NAME = "_system";
public static final User INSTANCE = new SystemUser(); public static final User INSTANCE = new SystemUser();
@ -41,6 +41,10 @@ public class SystemUser extends User {
return INSTANCE.equals(user); return INSTANCE.equals(user);
} }
public static boolean is(String principal) {
return NAME.equals(principal);
}
public static boolean isAuthorized(String action) { public static boolean isAuthorized(String action) {
return PREDICATE.test(action); return PREDICATE.test(action);
} }

View File

@ -187,12 +187,14 @@ public class User implements ToXContent {
public static User readFrom(StreamInput input) throws IOException { public static User readFrom(StreamInput input) throws IOException {
if (input.readBoolean()) { if (input.readBoolean()) {
String name = input.readString(); String name = input.readString();
if (SystemUser.NAME.equals(name)) { if (SystemUser.is(name)) {
return SystemUser.INSTANCE; return SystemUser.INSTANCE;
} else if (XPackUser.is(name)) {
return XPackUser.INSTANCE;
} }
User user = ReservedRealm.getUser(name); User user = ReservedRealm.getUser(name);
if (user == null) { if (user == null) {
throw new IllegalStateException("invalid internal user"); throw new IllegalStateException("invalid reserved user");
} }
return user; return user;
} }
@ -217,6 +219,9 @@ public class User implements ToXContent {
if (SystemUser.is(user)) { if (SystemUser.is(user)) {
output.writeBoolean(true); output.writeBoolean(true);
output.writeString(SystemUser.NAME); output.writeString(SystemUser.NAME);
} else if (XPackUser.is(user)) {
output.writeBoolean(true);
output.writeString(XPackUser.NAME);
} else if (ReservedRealm.isReserved(user.principal())) { } else if (ReservedRealm.isReserved(user.principal())) {
output.writeBoolean(true); output.writeBoolean(true);
output.writeString(user.principal()); output.writeString(user.principal());

View File

@ -12,9 +12,9 @@ import org.elasticsearch.shield.user.User.ReservedUser;
* XPack internal user that manages xpack. Has all cluster/indices permissions for watcher, * XPack internal user that manages xpack. Has all cluster/indices permissions for watcher,
* shield and monitoring to operate. * shield and monitoring to operate.
*/ */
public class XPackUser extends ReservedUser { public class XPackUser extends User {
public static final String NAME = "elastic"; public static final String NAME = "_xpack";
public static final String ROLE_NAME = SuperuserRole.NAME; public static final String ROLE_NAME = SuperuserRole.NAME;
public static final XPackUser INSTANCE = new XPackUser(); public static final XPackUser INSTANCE = new XPackUser();

View File

@ -9,8 +9,6 @@ import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.percolate.PercolateResponse;
import org.elasticsearch.action.percolate.PercolateSourceBuilder;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.termvectors.MultiTermVectorsResponse; import org.elasticsearch.action.termvectors.MultiTermVectorsResponse;
import org.elasticsearch.action.termvectors.TermVectorsRequest; import org.elasticsearch.action.termvectors.TermVectorsRequest;
@ -605,86 +603,6 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
assertThat(searchResponse.getHits().getAt(1).id(), equalTo("c2")); assertThat(searchResponse.getHits().getAt(1).id(), equalTo("c2"));
} }
public void testPercolateApi() {
assertAcked(client().admin().indices().prepareCreate("test")
.addMapping("query", "query", "type=percolator", "field1", "type=text", "field2", "type=text", "field3", "type=text")
);
client().prepareIndex("test", "query", "1")
.setSource("{\"query\" : { \"match_all\" : {} }, \"field1\" : \"value1\"}")
.setRefresh(true)
.get();
// Percolator without a query just evaluates all percolator queries that are loaded, so we have a match:
PercolateResponse response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
.preparePercolate()
.setDocumentType("query")
.setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
.get();
assertThat(response.getCount(), equalTo(1L));
assertThat(response.getMatches()[0].getId().string(), equalTo("1"));
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.preparePercolate()
.setDocumentType("query")
.setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
.get();
assertThat(response.getCount(), equalTo(0L));
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
.preparePercolate()
.setDocumentType("query")
.setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
.get();
assertThat(response.getCount(), equalTo(1L));
assertThat(response.getMatches()[0].getId().string(), equalTo("1"));
// Percolator with a query on a document that the current user can see. Percolator will have one query to evaluate, so there is a
// match:
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
.preparePercolate()
.setDocumentType("query")
.setPercolateQuery(termQuery("field1", "value1"))
.setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
.get();
assertThat(response.getCount(), equalTo(1L));
assertThat(response.getMatches()[0].getId().string(), equalTo("1"));
// Percolator with a query on a document that the current user can't see. Percolator will not have queries to evaluate, so there
// is no match:
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.preparePercolate()
.setDocumentType("query")
.setPercolateQuery(termQuery("field1", "value1"))
.setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
.get();
assertThat(response.getCount(), equalTo(0L));
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
.preparePercolate()
.setDocumentType("query")
.setPercolateQuery(termQuery("field1", "value1"))
.setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
.get();
assertThat(response.getCount(), equalTo(1L));
assertThat(response.getMatches()[0].getId().string(), equalTo("1"));
assertAcked(client().admin().indices().prepareClose("test"));
assertAcked(client().admin().indices().prepareOpen("test"));
ensureGreen("test");
// Ensure that the query loading that happens at startup has permissions to load the percolator queries:
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
.preparePercolate()
.setDocumentType("query")
.setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
.get();
assertThat(response.getCount(), equalTo(1L));
assertThat(response.getMatches()[0].getId().string(), equalTo("1"));
}
public void testScroll() throws Exception { public void testScroll() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test") assertAcked(client().admin().indices().prepareCreate("test")
.setSettings(Settings.builder().put(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING.getKey(), true)) .setSettings(Settings.builder().put(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING.getKey(), true))

View File

@ -10,8 +10,6 @@ import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.fieldstats.FieldStatsResponse; import org.elasticsearch.action.fieldstats.FieldStatsResponse;
import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.percolate.PercolateResponse;
import org.elasticsearch.action.percolate.PercolateSourceBuilder;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.termvectors.MultiTermVectorsResponse; import org.elasticsearch.action.termvectors.MultiTermVectorsResponse;
import org.elasticsearch.action.termvectors.TermVectorsRequest; import org.elasticsearch.action.termvectors.TermVectorsRequest;
@ -1122,49 +1120,6 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
assertThat(response.getResponses()[0].getResponse().getFields().terms("field2").size(), equalTo(1L)); assertThat(response.getResponses()[0].getResponse().getFields().terms("field2").size(), equalTo(1L));
} }
public void testPercolateApi() {
assertAcked(client().admin().indices().prepareCreate("test")
.addMapping("query", "query", "type=percolator", "field1", "type=text", "field2", "type=text")
);
client().prepareIndex("test", "query", "1")
.setSource("{\"query\" : { \"match_all\" : {} }, \"field1\" : \"value1\"}")
.setRefresh(true)
.get();
// Percolator without a query just evaluates all percolator queries that are loaded, so we have a match:
PercolateResponse response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.preparePercolate()
.setDocumentType("query")
.setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
.get();
assertThat(response.getCount(), equalTo(1L));
assertThat(response.getMatches()[0].getId().string(), equalTo("1"));
// Percolator with a query on a field that the current user can't see. Percolator will not have queries to evaluate, so there is
// no match:
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.preparePercolate()
.setDocumentType("query")
.setPercolateQuery(termQuery("field1", "value1"))
.setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
.get();
assertThat(response.getCount(), equalTo(0L));
assertAcked(client().admin().indices().prepareClose("test"));
assertAcked(client().admin().indices().prepareOpen("test"));
ensureGreen("test");
// Ensure that the query loading that happens at startup has permissions to load the percolator queries:
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.preparePercolate()
.setDocumentType("query")
.setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
.get();
assertThat(response.getCount(), equalTo(1L));
assertThat(response.getMatches()[0].getId().string(), equalTo("1"));
}
public void testParentChild() { public void testParentChild() {
assertAcked(prepareCreate("test") assertAcked(prepareCreate("test")
.addMapping("parent") .addMapping("parent")

View File

@ -11,10 +11,10 @@ import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.SecurityContext; import org.elasticsearch.shield.SecurityContext;
import org.elasticsearch.shield.user.ElasticUser;
import org.elasticsearch.shield.user.KibanaUser; import org.elasticsearch.shield.user.KibanaUser;
import org.elasticsearch.shield.user.SystemUser; import org.elasticsearch.shield.user.SystemUser;
import org.elasticsearch.shield.user.User; import org.elasticsearch.shield.user.User;
import org.elasticsearch.shield.user.XPackUser;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService; import org.elasticsearch.transport.TransportService;
@ -83,7 +83,7 @@ public class TransportAuthenticateActionTests extends ESTestCase {
} }
public void testValidUser() { public void testValidUser() {
final User user = randomFrom(XPackUser.INSTANCE, KibanaUser.INSTANCE, new User("joe")); final User user = randomFrom(ElasticUser.INSTANCE, KibanaUser.INSTANCE, new User("joe"));
SecurityContext securityContext = mock(SecurityContext.class); SecurityContext securityContext = mock(SecurityContext.class);
when(securityContext.getUser()).thenReturn(user); when(securityContext.getUser()).thenReturn(user);
TransportAuthenticateAction action = new TransportAuthenticateAction(Settings.EMPTY, mock(ThreadPool.class), TransportAuthenticateAction action = new TransportAuthenticateAction(Settings.EMPTY, mock(ThreadPool.class),

View File

@ -14,10 +14,10 @@ import org.elasticsearch.shield.authc.esnative.NativeUsersStore;
import org.elasticsearch.shield.authc.support.Hasher; import org.elasticsearch.shield.authc.support.Hasher;
import org.elasticsearch.shield.authc.support.SecuredString; import org.elasticsearch.shield.authc.support.SecuredString;
import org.elasticsearch.shield.user.AnonymousUser; import org.elasticsearch.shield.user.AnonymousUser;
import org.elasticsearch.shield.user.ElasticUser;
import org.elasticsearch.shield.user.KibanaUser; import org.elasticsearch.shield.user.KibanaUser;
import org.elasticsearch.shield.user.SystemUser; import org.elasticsearch.shield.user.SystemUser;
import org.elasticsearch.shield.user.User; import org.elasticsearch.shield.user.User;
import org.elasticsearch.shield.user.XPackUser;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService; import org.elasticsearch.transport.TransportService;
@ -109,7 +109,7 @@ public class TransportChangePasswordActionTests extends ESTestCase {
} }
public void testValidUser() { public void testValidUser() {
final User user = randomFrom(XPackUser.INSTANCE, KibanaUser.INSTANCE, new User("joe")); final User user = randomFrom(ElasticUser.INSTANCE, KibanaUser.INSTANCE, new User("joe"));
NativeUsersStore usersStore = mock(NativeUsersStore.class); NativeUsersStore usersStore = mock(NativeUsersStore.class);
ChangePasswordRequest request = new ChangePasswordRequest(); ChangePasswordRequest request = new ChangePasswordRequest();
request.username(user.principal()); request.username(user.principal());
@ -147,7 +147,7 @@ public class TransportChangePasswordActionTests extends ESTestCase {
} }
public void testException() { public void testException() {
final User user = randomFrom(XPackUser.INSTANCE, KibanaUser.INSTANCE, new User("joe")); final User user = randomFrom(ElasticUser.INSTANCE, KibanaUser.INSTANCE, new User("joe"));
NativeUsersStore usersStore = mock(NativeUsersStore.class); NativeUsersStore usersStore = mock(NativeUsersStore.class);
ChangePasswordRequest request = new ChangePasswordRequest(); ChangePasswordRequest request = new ChangePasswordRequest();
request.username(user.principal()); request.username(user.principal());

View File

@ -8,7 +8,6 @@ package org.elasticsearch.shield.authc;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
@ -37,6 +36,7 @@ import org.junit.Rule;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Base64;
import java.util.Collections; import java.util.Collections;
import static org.elasticsearch.shield.support.Exceptions.authenticationError; import static org.elasticsearch.shield.support.Exceptions.authenticationError;
@ -751,7 +751,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
User user = new User("username", "r1", "r2", "r3"); User user = new User("username", "r1", "r2", "r3");
String text = InternalAuthenticationService.encodeUser(user, null); String text = InternalAuthenticationService.encodeUser(user, null);
StreamInput input = StreamInput.wrap(Base64.decode(text)); StreamInput input = StreamInput.wrap(Base64.getDecoder().decode(text));
Version version = Version.readVersion(input); Version version = Version.readVersion(input);
assertThat(version, is(Version.CURRENT)); assertThat(version, is(Version.CURRENT));
} }

View File

@ -16,25 +16,25 @@ import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.RestStatus; import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.shield.ShieldTemplateService; import org.elasticsearch.shield.ShieldTemplateService;
import org.elasticsearch.shield.action.role.DeleteRoleResponse;
import org.elasticsearch.shield.action.role.GetRolesResponse;
import org.elasticsearch.shield.action.user.AuthenticateAction; import org.elasticsearch.shield.action.user.AuthenticateAction;
import org.elasticsearch.shield.action.user.AuthenticateRequest; import org.elasticsearch.shield.action.user.AuthenticateRequest;
import org.elasticsearch.shield.action.user.AuthenticateResponse; import org.elasticsearch.shield.action.user.AuthenticateResponse;
import org.elasticsearch.shield.action.user.ChangePasswordResponse; import org.elasticsearch.shield.action.user.ChangePasswordResponse;
import org.elasticsearch.shield.authz.permission.KibanaRole;
import org.elasticsearch.shield.authz.permission.SuperuserRole;
import org.elasticsearch.shield.user.AnonymousUser;
import org.elasticsearch.shield.user.KibanaUser;
import org.elasticsearch.shield.user.SystemUser;
import org.elasticsearch.shield.user.User;
import org.elasticsearch.shield.action.role.DeleteRoleResponse;
import org.elasticsearch.shield.action.role.GetRolesResponse;
import org.elasticsearch.shield.action.user.DeleteUserResponse; import org.elasticsearch.shield.action.user.DeleteUserResponse;
import org.elasticsearch.shield.action.user.GetUsersResponse; import org.elasticsearch.shield.action.user.GetUsersResponse;
import org.elasticsearch.shield.authc.support.SecuredString; import org.elasticsearch.shield.authc.support.SecuredString;
import org.elasticsearch.shield.authz.RoleDescriptor; import org.elasticsearch.shield.authz.RoleDescriptor;
import org.elasticsearch.shield.authz.permission.KibanaRole;
import org.elasticsearch.shield.authz.permission.Role; import org.elasticsearch.shield.authz.permission.Role;
import org.elasticsearch.shield.authz.permission.SuperuserRole;
import org.elasticsearch.shield.client.SecurityClient; import org.elasticsearch.shield.client.SecurityClient;
import org.elasticsearch.shield.user.XPackUser; import org.elasticsearch.shield.user.AnonymousUser;
import org.elasticsearch.shield.user.ElasticUser;
import org.elasticsearch.shield.user.KibanaUser;
import org.elasticsearch.shield.user.SystemUser;
import org.elasticsearch.shield.user.User;
import org.elasticsearch.test.NativeRealmIntegTestCase; import org.elasticsearch.test.NativeRealmIntegTestCase;
import org.elasticsearch.test.ShieldSettingsSource; import org.elasticsearch.test.ShieldSettingsSource;
import org.junit.BeforeClass; import org.junit.BeforeClass;
@ -457,7 +457,7 @@ public class NativeRealmIntegTests extends NativeRealmIntegTestCase {
} }
public void testOperationsOnReservedUsers() throws Exception { public void testOperationsOnReservedUsers() throws Exception {
final String username = randomFrom(XPackUser.NAME, KibanaUser.NAME); final String username = randomFrom(ElasticUser.NAME, KibanaUser.NAME);
IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, IllegalArgumentException exception = expectThrows(IllegalArgumentException.class,
() -> securityClient().preparePutUser(username, randomBoolean() ? "changeme".toCharArray() : null, "admin").get()); () -> securityClient().preparePutUser(username, randomBoolean() ? "changeme".toCharArray() : null, "admin").get());
assertThat(exception.getMessage(), containsString("user [" + username + "] is reserved")); assertThat(exception.getMessage(), containsString("user [" + username + "] is reserved"));

View File

@ -7,8 +7,8 @@ package org.elasticsearch.shield.authc.esnative;
import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
import org.elasticsearch.shield.user.ElasticUser;
import org.elasticsearch.shield.user.KibanaUser; import org.elasticsearch.shield.user.KibanaUser;
import org.elasticsearch.shield.user.XPackUser;
import org.elasticsearch.shield.action.user.ChangePasswordResponse; import org.elasticsearch.shield.action.user.ChangePasswordResponse;
import org.elasticsearch.shield.authc.support.SecuredString; import org.elasticsearch.shield.authc.support.SecuredString;
import org.elasticsearch.test.NativeRealmIntegTestCase; import org.elasticsearch.test.NativeRealmIntegTestCase;
@ -29,7 +29,7 @@ public class ReservedRealmIntegTests extends NativeRealmIntegTestCase {
private static final SecuredString DEFAULT_PASSWORD = new SecuredString("changeme".toCharArray()); private static final SecuredString DEFAULT_PASSWORD = new SecuredString("changeme".toCharArray());
public void testAuthenticate() { public void testAuthenticate() {
for (String username : Arrays.asList(XPackUser.NAME, KibanaUser.NAME)) { for (String username : Arrays.asList(ElasticUser.NAME, KibanaUser.NAME)) {
ClusterHealthResponse response = client() ClusterHealthResponse response = client()
.filterWithHeader(singletonMap("Authorization", basicAuthHeaderValue(username, DEFAULT_PASSWORD))) .filterWithHeader(singletonMap("Authorization", basicAuthHeaderValue(username, DEFAULT_PASSWORD)))
.admin() .admin()
@ -42,7 +42,7 @@ public class ReservedRealmIntegTests extends NativeRealmIntegTestCase {
} }
public void testChangingPassword() { public void testChangingPassword() {
String username = randomFrom(XPackUser.NAME, KibanaUser.NAME); String username = randomFrom(ElasticUser.NAME, KibanaUser.NAME);
final char[] newPassword = "supersecretvalue".toCharArray(); final char[] newPassword = "supersecretvalue".toCharArray();
if (randomBoolean()) { if (randomBoolean()) {

View File

@ -13,9 +13,9 @@ import org.elasticsearch.shield.authc.support.Hasher;
import org.elasticsearch.shield.authc.support.SecuredString; import org.elasticsearch.shield.authc.support.SecuredString;
import org.elasticsearch.shield.authc.support.UsernamePasswordToken; import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
import org.elasticsearch.shield.user.AnonymousUser; import org.elasticsearch.shield.user.AnonymousUser;
import org.elasticsearch.shield.user.ElasticUser;
import org.elasticsearch.shield.user.KibanaUser; import org.elasticsearch.shield.user.KibanaUser;
import org.elasticsearch.shield.user.User; import org.elasticsearch.shield.user.User;
import org.elasticsearch.shield.user.XPackUser;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.junit.Before; import org.junit.Before;
@ -49,7 +49,7 @@ public class ReservedRealmTests extends ESTestCase {
public void testUserStoreNotStarted() { public void testUserStoreNotStarted() {
when(usersStore.started()).thenReturn(false); when(usersStore.started()).thenReturn(false);
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore); final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore);
final String principal = randomFrom(XPackUser.NAME, KibanaUser.NAME); final String principal = randomFrom(ElasticUser.NAME, KibanaUser.NAME);
ElasticsearchSecurityException expected = expectThrows(ElasticsearchSecurityException.class, ElasticsearchSecurityException expected = expectThrows(ElasticsearchSecurityException.class,
() -> reservedRealm.doAuthenticate(new UsernamePasswordToken(principal, DEFAULT_PASSWORD))); () -> reservedRealm.doAuthenticate(new UsernamePasswordToken(principal, DEFAULT_PASSWORD)));
@ -65,7 +65,7 @@ public class ReservedRealmTests extends ESTestCase {
when(usersStore.shieldIndexExists()).thenReturn(true); when(usersStore.shieldIndexExists()).thenReturn(true);
} }
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore); final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore);
final User expected = randomFrom((User) XPackUser.INSTANCE, (User) KibanaUser.INSTANCE); final User expected = randomFrom((User) ElasticUser.INSTANCE, KibanaUser.INSTANCE);
final String principal = expected.principal(); final String principal = expected.principal();
final User authenticated = reservedRealm.doAuthenticate(new UsernamePasswordToken(principal, DEFAULT_PASSWORD)); final User authenticated = reservedRealm.doAuthenticate(new UsernamePasswordToken(principal, DEFAULT_PASSWORD));
@ -81,7 +81,7 @@ public class ReservedRealmTests extends ESTestCase {
public void testAuthenticationWithStoredPassword() throws Throwable { public void testAuthenticationWithStoredPassword() throws Throwable {
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore); final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore);
final User expectedUser = randomFrom((User) XPackUser.INSTANCE, (User) KibanaUser.INSTANCE); final User expectedUser = randomFrom((User) ElasticUser.INSTANCE, KibanaUser.INSTANCE);
final String principal = expectedUser.principal(); final String principal = expectedUser.principal();
final SecuredString newPassword = new SecuredString("foobar".toCharArray()); final SecuredString newPassword = new SecuredString("foobar".toCharArray());
when(usersStore.shieldIndexExists()).thenReturn(true); when(usersStore.shieldIndexExists()).thenReturn(true);
@ -107,7 +107,7 @@ public class ReservedRealmTests extends ESTestCase {
public void testLookup() { public void testLookup() {
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore); final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore);
final User expectedUser = randomFrom((User) XPackUser.INSTANCE, (User) KibanaUser.INSTANCE); final User expectedUser = randomFrom((User) ElasticUser.INSTANCE, KibanaUser.INSTANCE);
final String principal = expectedUser.principal(); final String principal = expectedUser.principal();
final User user = reservedRealm.doLookupUser(principal); final User user = reservedRealm.doLookupUser(principal);
@ -120,7 +120,7 @@ public class ReservedRealmTests extends ESTestCase {
} }
public void testHelperMethods() { public void testHelperMethods() {
final User expectedUser = randomFrom((User) XPackUser.INSTANCE, KibanaUser.INSTANCE); final User expectedUser = randomFrom((User) ElasticUser.INSTANCE, KibanaUser.INSTANCE);
final String principal = expectedUser.principal(); final String principal = expectedUser.principal();
assertThat(ReservedRealm.isReserved(principal), is(true)); assertThat(ReservedRealm.isReserved(principal), is(true));
assertThat(ReservedRealm.getUser(principal), sameInstance(expectedUser)); assertThat(ReservedRealm.getUser(principal), sameInstance(expectedUser));
@ -129,19 +129,20 @@ public class ReservedRealmTests extends ESTestCase {
assertThat(ReservedRealm.isReserved(notExpected), is(false)); assertThat(ReservedRealm.isReserved(notExpected), is(false));
assertThat(ReservedRealm.getUser(notExpected), nullValue()); assertThat(ReservedRealm.getUser(notExpected), nullValue());
assertThat(ReservedRealm.users(), containsInAnyOrder((User) XPackUser.INSTANCE, KibanaUser.INSTANCE)); assertThat(ReservedRealm.users(), containsInAnyOrder((User) ElasticUser.INSTANCE, KibanaUser.INSTANCE));
} }
public void testFailedAuthentication() { public void testFailedAuthentication() {
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore); final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore);
// maybe cache a successful auth // maybe cache a successful auth
if (randomBoolean()) { if (randomBoolean()) {
User user = reservedRealm.authenticate(new UsernamePasswordToken(XPackUser.NAME, new SecuredString("changeme".toCharArray()))); User user = reservedRealm.authenticate(
assertThat(user, sameInstance(XPackUser.INSTANCE)); new UsernamePasswordToken(ElasticUser.NAME, new SecuredString("changeme".toCharArray())));
assertThat(user, sameInstance(ElasticUser.INSTANCE));
} }
try { try {
reservedRealm.authenticate(new UsernamePasswordToken(XPackUser.NAME, new SecuredString("foobar".toCharArray()))); reservedRealm.authenticate(new UsernamePasswordToken(ElasticUser.NAME, new SecuredString("foobar".toCharArray())));
fail("authentication should throw an exception otherwise we may allow others to impersonate reserved users..."); fail("authentication should throw an exception otherwise we may allow others to impersonate reserved users...");
} catch (ElasticsearchSecurityException e) { } catch (ElasticsearchSecurityException e) {
assertThat(e.getMessage(), containsString("failed to authenticate")); assertThat(e.getMessage(), containsString("failed to authenticate"));

View File

@ -92,6 +92,7 @@ public class UsersToolTests extends CommandTestCase {
public static void closeJimfs() throws IOException { public static void closeJimfs() throws IOException {
if (jimfs != null) { if (jimfs != null) {
jimfs.close(); jimfs.close();
jimfs = null;
} }
} }

View File

@ -119,7 +119,7 @@ public class OpenLdapTests extends ESTestCase {
Map<String, Object> stats = realm.usageStats(); Map<String, Object> stats = realm.usageStats();
assertThat(stats, is(notNullValue())); assertThat(stats, is(notNullValue()));
assertThat(stats, hasEntry("size", "small")); assertThat(stats, hasEntry("size", "tiny"));
assertThat(stats, hasEntry("ssl", true)); assertThat(stats, hasEntry("ssl", true));
assertThat(stats, hasEntry("user_search", userSearch)); assertThat(stats, hasEntry("user_search", userSearch));
assertThat(stats, hasEntry("load_balance_type", loadBalanceType)); assertThat(stats, hasEntry("load_balance_type", loadBalanceType));

View File

@ -20,7 +20,7 @@ public class UsernamePasswordRealmTests extends ESTestCase {
int count = randomIntBetween(0, 1000); int count = randomIntBetween(0, 1000);
UsernamePasswordRealm.UserbaseSize size = UsernamePasswordRealm.UserbaseSize.resolve(count); UsernamePasswordRealm.UserbaseSize size = UsernamePasswordRealm.UserbaseSize.resolve(count);
if (count < 10) { if (count < 10) {
assertThat(size, is(UsernamePasswordRealm.UserbaseSize.SMALL)); assertThat(size, is(UsernamePasswordRealm.UserbaseSize.TINY));
} else if (count < 100) { } else if (count < 100) {
assertThat(size, is(UsernamePasswordRealm.UserbaseSize.SMALL)); assertThat(size, is(UsernamePasswordRealm.UserbaseSize.SMALL));
} else if (count < 500) { } else if (count < 500) {

View File

@ -6,7 +6,6 @@
package org.elasticsearch.shield.authc.support; package org.elasticsearch.shield.authc.support;
import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.common.Base64;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
@ -14,6 +13,7 @@ import org.junit.Rule;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Base64;
import static org.elasticsearch.test.ShieldTestsUtils.assertAuthenticationException; import static org.elasticsearch.test.ShieldTestsUtils.assertAuthenticationException;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ -35,7 +35,7 @@ public class UsernamePasswordTokenTests extends ESTestCase {
assertThat(header, notNullValue()); assertThat(header, notNullValue());
assertTrue(header.startsWith("Basic ")); assertTrue(header.startsWith("Basic "));
String token = header.substring("Basic ".length()); String token = header.substring("Basic ".length());
token = new String(Base64.decode(token), StandardCharsets.UTF_8); token = new String(Base64.getDecoder().decode(token), StandardCharsets.UTF_8);
int i = token.indexOf(":"); int i = token.indexOf(":");
assertTrue(i > 0); assertTrue(i > 0);
String username = token.substring(0, i); String username = token.substring(0, i);
@ -46,7 +46,7 @@ public class UsernamePasswordTokenTests extends ESTestCase {
public void testExtractToken() throws Exception { public void testExtractToken() throws Exception {
ThreadContext threadContext = new ThreadContext(Settings.EMPTY); ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
String header = "Basic " + Base64.encodeBytes("user1:test123".getBytes(StandardCharsets.UTF_8)); String header = "Basic " + Base64.getEncoder().encodeToString("user1:test123".getBytes(StandardCharsets.UTF_8));
threadContext.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, header); threadContext.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, header);
UsernamePasswordToken token = UsernamePasswordToken.extractToken(threadContext); UsernamePasswordToken token = UsernamePasswordToken.extractToken(threadContext);
assertThat(token, notNullValue()); assertThat(token, notNullValue());

View File

@ -22,6 +22,8 @@ import org.elasticsearch.shield.user.User;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.transport.TransportRequest; import org.elasticsearch.transport.TransportRequest;
import java.util.Arrays;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
/** /**
@ -45,17 +47,27 @@ public class KibanaRoleTests extends ESTestCase {
assertThat(KibanaRole.INSTANCE.runAs().isEmpty(), is(true)); assertThat(KibanaRole.INSTANCE.runAs().isEmpty(), is(true));
} }
public void testIndices() { public void testUnauthorizedIndices() {
final String kibanaIndex = ".kibana";
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher("indices:foo").test(kibanaIndex), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher("indices:bar").test(kibanaIndex), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(kibanaIndex), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(kibanaIndex), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(IndexAction.NAME).test(kibanaIndex), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(DeleteAction.NAME).test(kibanaIndex), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(kibanaIndex), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(IndexAction.NAME).test("foo"), is(false)); assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(IndexAction.NAME).test("foo"), is(false));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(IndexAction.NAME).test(".reporting"), is(false));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher("indices:foo").test(randomAsciiOfLengthBetween(8, 24)), is(false)); assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher("indices:foo").test(randomAsciiOfLengthBetween(8, 24)), is(false));
} }
public void testKibanaIndices() {
Arrays.asList(".kibana", ".kibana-devnull").forEach(this::testAllIndexAccess);
}
public void testReportingIndices() {
testAllIndexAccess(".reporting-" + randomAsciiOfLength(randomIntBetween(0, 13)));
}
private void testAllIndexAccess(String index) {
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher("indices:foo").test(index), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher("indices:bar").test(index), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(true));
assertThat(KibanaRole.INSTANCE.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(true));
}
} }

View File

@ -358,7 +358,7 @@ public class FileRolesStoreTests extends ESTestCase {
assertThat(messages, notNullValue()); assertThat(messages, notNullValue());
assertThat(messages, hasSize(4)); assertThat(messages, hasSize(4));
// the system role will always be checked first // the system role will always be checked first
assertThat(messages.get(0).text, containsString("role [__es_system_role] is reserved")); assertThat(messages.get(0).text, containsString("role [_system] is reserved"));
assertThat(messages.get(1).text, containsString("role [superuser] is reserved")); assertThat(messages.get(1).text, containsString("role [superuser] is reserved"));
assertThat(messages.get(2).text, containsString("role [kibana] is reserved")); assertThat(messages.get(2).text, containsString("role [kibana] is reserved"));
assertThat(messages.get(3).text, containsString("role [transport_client] is reserved")); assertThat(messages.get(3).text, containsString("role [transport_client] is reserved"));

View File

@ -9,10 +9,10 @@ import org.elasticsearch.shield.SecurityContext;
import org.elasticsearch.shield.authz.permission.KibanaRole; import org.elasticsearch.shield.authz.permission.KibanaRole;
import org.elasticsearch.shield.authz.permission.SuperuserRole; import org.elasticsearch.shield.authz.permission.SuperuserRole;
import org.elasticsearch.shield.authz.permission.TransportClientRole; import org.elasticsearch.shield.authz.permission.TransportClientRole;
import org.elasticsearch.shield.user.ElasticUser;
import org.elasticsearch.shield.user.KibanaUser; import org.elasticsearch.shield.user.KibanaUser;
import org.elasticsearch.shield.user.SystemUser; import org.elasticsearch.shield.user.SystemUser;
import org.elasticsearch.shield.user.User; import org.elasticsearch.shield.user.User;
import org.elasticsearch.shield.user.XPackUser;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.junit.Before; import org.junit.Before;
@ -41,7 +41,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
public void testRetrievingReservedRolesNonKibanaUser() { public void testRetrievingReservedRolesNonKibanaUser() {
if (randomBoolean()) { if (randomBoolean()) {
when(securityContext.getUser()).thenReturn(XPackUser.INSTANCE); when(securityContext.getUser()).thenReturn(ElasticUser.INSTANCE);
} }
assertThat(reservedRolesStore.role(SuperuserRole.NAME), sameInstance(SuperuserRole.INSTANCE)); assertThat(reservedRolesStore.role(SuperuserRole.NAME), sameInstance(SuperuserRole.INSTANCE));

View File

@ -10,6 +10,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.ByteBufferStreamInput; import org.elasticsearch.common.io.stream.ByteBufferStreamInput;
import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.XPackClient;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -58,7 +59,7 @@ public class UserTests extends ESTestCase {
assertThat(readFromRunAs.runAs(), is(nullValue())); assertThat(readFromRunAs.runAs(), is(nullValue()));
} }
public void testSystemReadAndWrite() throws Exception { public void testSystemUserReadAndWrite() throws Exception {
BytesStreamOutput output = new BytesStreamOutput(); BytesStreamOutput output = new BytesStreamOutput();
User.writeTo(SystemUser.INSTANCE, output); User.writeTo(SystemUser.INSTANCE, output);
@ -68,6 +69,16 @@ public class UserTests extends ESTestCase {
assertThat(readFrom.runAs(), is(nullValue())); assertThat(readFrom.runAs(), is(nullValue()));
} }
public void testXPackUserReadAndWrite() throws Exception {
BytesStreamOutput output = new BytesStreamOutput();
User.writeTo(XPackUser.INSTANCE, output);
User readFrom = User.readFrom(ByteBufferStreamInput.wrap(output.bytes()));
assertThat(readFrom, is(sameInstance(XPackUser.INSTANCE)));
assertThat(readFrom.runAs(), is(nullValue()));
}
public void testFakeInternalUserSerialization() throws Exception { public void testFakeInternalUserSerialization() throws Exception {
BytesStreamOutput output = new BytesStreamOutput(); BytesStreamOutput output = new BytesStreamOutput();
output.writeBoolean(true); output.writeBoolean(true);
@ -102,10 +113,10 @@ public class UserTests extends ESTestCase {
public void testReservedUserSerialization() throws Exception { public void testReservedUserSerialization() throws Exception {
BytesStreamOutput output = new BytesStreamOutput(); BytesStreamOutput output = new BytesStreamOutput();
User.writeTo(XPackUser.INSTANCE, output); User.writeTo(ElasticUser.INSTANCE, output);
User readFrom = User.readFrom(ByteBufferStreamInput.wrap(output.bytes())); User readFrom = User.readFrom(ByteBufferStreamInput.wrap(output.bytes()));
assertThat(readFrom, is(sameInstance(XPackUser.INSTANCE))); assertThat(readFrom, is(sameInstance(ElasticUser.INSTANCE)));
output = new BytesStreamOutput(); output = new BytesStreamOutput();
User.writeTo(KibanaUser.INSTANCE, output); User.writeTo(KibanaUser.INSTANCE, output);

View File

@ -5,7 +5,7 @@ admin:
- names: '*' - names: '*'
privileges: [ all ] privileges: [ all ]
__es_system_role: _system:
cluster: cluster:
- all - all
indices: indices:

View File

@ -59,10 +59,8 @@ indices:data/read/field_stats
indices:data/read/get indices:data/read/get
indices:data/read/xpack/graph/explore indices:data/read/xpack/graph/explore
indices:data/read/mget indices:data/read/mget
indices:data/read/mpercolate
indices:data/read/msearch indices:data/read/msearch
indices:data/read/mtv indices:data/read/mtv
indices:data/read/percolate
cluster:admin/script/get cluster:admin/script/get
indices:data/read/scroll indices:data/read/scroll
indices:data/read/scroll/clear indices:data/read/scroll/clear

View File

@ -37,6 +37,8 @@ import org.elasticsearch.xpack.common.secret.SecretModule;
import org.elasticsearch.xpack.extensions.XPackExtension; import org.elasticsearch.xpack.extensions.XPackExtension;
import org.elasticsearch.xpack.extensions.XPackExtensionsService; import org.elasticsearch.xpack.extensions.XPackExtensionsService;
import org.elasticsearch.xpack.notification.Notification; import org.elasticsearch.xpack.notification.Notification;
import org.elasticsearch.xpack.notification.email.Account;
import org.elasticsearch.xpack.notification.email.support.BodyPartSource;
import org.elasticsearch.xpack.rest.action.RestXPackInfoAction; import org.elasticsearch.xpack.rest.action.RestXPackInfoAction;
import org.elasticsearch.xpack.common.text.TextTemplateModule; import org.elasticsearch.xpack.common.text.TextTemplateModule;
import org.elasticsearch.xpack.rest.action.RestXPackUsageAction; import org.elasticsearch.xpack.rest.action.RestXPackUsageAction;
@ -84,6 +86,9 @@ public class XPackPlugin extends Plugin {
throw bogus; // some other bug throw bogus; // some other bug
} }
} }
// some classes need to have their own clinit blocks
BodyPartSource.init();
Account.init();
} }
protected final Settings settings; protected final Settings settings;

View File

@ -5,12 +5,12 @@
*/ */
package org.elasticsearch.xpack.common.http.auth.basic; package org.elasticsearch.xpack.common.http.auth.basic;
import org.elasticsearch.common.Base64;
import org.elasticsearch.xpack.common.http.auth.ApplicableHttpAuth; import org.elasticsearch.xpack.common.http.auth.ApplicableHttpAuth;
import org.elasticsearch.xpack.common.secret.SecretService; import org.elasticsearch.xpack.common.secret.SecretService;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Base64;
/** /**
*/ */
@ -24,7 +24,7 @@ public class ApplicableBasicAuth extends ApplicableHttpAuth<BasicAuth> {
} }
public static String headerValue(String username, char[] password) { public static String headerValue(String username, char[] password) {
return "Basic " + Base64.encodeBytes((username + ":" + new String(password)).getBytes(StandardCharsets.UTF_8)); return "Basic " + Base64.getEncoder().encodeToString((username + ":" + new String(password)).getBytes(StandardCharsets.UTF_8));
} }
public void apply(HttpURLConnection connection) { public void apply(HttpURLConnection connection) {

View File

@ -32,13 +32,6 @@ public class Account {
static final String SMTP_PROTOCOL = "smtp"; static final String SMTP_PROTOCOL = "smtp";
static { static {
// required as java doesn't always find the correct mailcap to properly handle mime types
final MailcapCommandMap mailcap = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mailcap.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mailcap.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mailcap.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mailcap.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mailcap.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
sm.checkPermission(new SpecialPermission()); sm.checkPermission(new SpecialPermission());
@ -46,12 +39,22 @@ public class Account {
AccessController.doPrivileged(new PrivilegedAction<Void>() { AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override @Override
public Void run() { public Void run() {
// required as java doesn't always find the correct mailcap to properly handle mime types
final MailcapCommandMap mailcap = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mailcap.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mailcap.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mailcap.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mailcap.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mailcap.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
CommandMap.setDefaultCommandMap(mailcap); CommandMap.setDefaultCommandMap(mailcap);
return null; return null;
} }
}); });
} }
// exists only to allow ensuring class is initialized
public static void init() {}
static final Settings DEFAULT_SMTP_TIMEOUT_SETTINGS = Settings.builder() static final Settings DEFAULT_SMTP_TIMEOUT_SETTINGS = Settings.builder()
.put("connection_timeout", TimeValue.timeValueMinutes(2)) .put("connection_timeout", TimeValue.timeValueMinutes(2))
.put("write_timeout", TimeValue.timeValueMinutes(2)) .put("write_timeout", TimeValue.timeValueMinutes(2))

View File

@ -5,18 +5,30 @@
*/ */
package org.elasticsearch.xpack.notification.email.support; package org.elasticsearch.xpack.notification.email.support;
import org.elasticsearch.SpecialPermission;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import javax.activation.CommandMap;
import javax.activation.FileTypeMap; import javax.activation.FileTypeMap;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeBodyPart;
import java.security.AccessController;
import java.security.PrivilegedAction;
/** /**
* *
*/ */
public abstract class BodyPartSource implements ToXContent { public abstract class BodyPartSource implements ToXContent {
protected static FileTypeMap fileTypeMap = FileTypeMap.getDefaultFileTypeMap(); protected static FileTypeMap fileTypeMap;
static {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
fileTypeMap = AccessController.doPrivileged(
(PrivilegedAction<FileTypeMap>)() -> FileTypeMap.getDefaultFileTypeMap());
}
protected final String id; protected final String id;
protected final String name; protected final String name;
@ -46,4 +58,7 @@ public abstract class BodyPartSource implements ToXContent {
public abstract MimeBodyPart bodyPart() throws MessagingException; public abstract MimeBodyPart bodyPart() throws MessagingException;
// exists only to allow ensuring class is initialized
public static void init() {}
} }

View File

@ -11,6 +11,8 @@ grant {
// to load the class with the application class loader // to load the class with the application class loader
permission java.lang.RuntimePermission "setContextClassLoader"; permission java.lang.RuntimePermission "setContextClassLoader";
permission java.lang.RuntimePermission "getClassLoader"; permission java.lang.RuntimePermission "getClassLoader";
// TODO: remove use of this jar as soon as possible!!!!
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.activation.registries";
// bouncy castle // bouncy castle
permission java.security.SecurityPermission "putProviderProperty.BC"; permission java.security.SecurityPermission "putProviderProperty.BC";

View File

@ -1,6 +1,6 @@
{ {
"xpack.info": { "xpack.info": {
"documentation": "Retrieve information about xpack, including buid number/timestamp and license status", "documentation": "Retrieve information about xpack, including build number/timestamp and license status",
"methods": [ "GET" ], "methods": [ "GET" ],
"url": { "url": {
"path": "/_xpack", "path": "/_xpack",

View File

@ -1,5 +1,5 @@
{ {
"xpack.info": { "xpack.usage": {
"documentation": "Retrieve information about xpack features usage", "documentation": "Retrieve information about xpack features usage",
"methods": [ "GET" ], "methods": [ "GET" ],
"url": { "url": {

View File

@ -1,6 +1,6 @@
# Integration tests xpack info API # Integration tests xpack info and usage API
# #
"X-Pack Info": "X-Pack Info and Usage":
- do: - do:
cluster.health: cluster.health:
@ -83,6 +83,17 @@
- is_true: features.monitoring.description - is_true: features.monitoring.description
- is_true: tagline - is_true: tagline
- do:
xpack.usage: {}
- is_true: watcher.enabled
- is_true: watcher.available
- is_true: security.enabled
- is_true: security.available
- is_true: graph.enabled
- is_true: graph.available
- is_true: monitoring.enabled
- is_true: monitoring.available
- do: - do:
xpack.info: xpack.info:
categories: "_none" categories: "_none"

View File

@ -5,7 +5,6 @@
*/ */
package org.elasticsearch.script; package org.elasticsearch.script;
import org.elasticsearch.script.ScriptMode;
import org.elasticsearch.xpack.common.text.DefaultTextTemplateEngine; import org.elasticsearch.xpack.common.text.DefaultTextTemplateEngine;
import java.util.Collections; import java.util.Collections;
@ -29,8 +28,7 @@ public class MockMustacheScriptEngine extends MockScriptEngine {
} }
public void onModule(ScriptModule module) { public void onModule(ScriptModule module) {
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(MockMustacheScriptEngine.class, module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(MockMustacheScriptEngine.class, NAME, true));
NAME, ScriptMode.ON));
} }
} }

View File

@ -7,7 +7,6 @@ package org.elasticsearch.script;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.ScriptMode;
import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SearchLookup;
import java.io.IOException; import java.io.IOException;
@ -39,7 +38,7 @@ public class SleepScriptEngine implements ScriptEngineService {
public void onModule(ScriptModule module) { public void onModule(ScriptModule module) {
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(SleepScriptEngine.class, module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(SleepScriptEngine.class,
SleepScriptEngine.NAME, ScriptMode.ON)); SleepScriptEngine.NAME, true));
} }
} }

View File

@ -6,6 +6,9 @@
package org.elasticsearch.xpack.watcher.history; package org.elasticsearch.xpack.watcher.history;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.Terms;
@ -15,6 +18,9 @@ import org.elasticsearch.xpack.watcher.execution.ExecutionState;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse; import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
import org.junit.After; import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms; import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource;
@ -32,14 +38,17 @@ import static org.hamcrest.Matchers.notNullValue;
* not analyzed so they can be used in aggregations * not analyzed so they can be used in aggregations
*/ */
public class HistoryTemplateEmailMappingsTests extends AbstractWatcherIntegrationTestCase { public class HistoryTemplateEmailMappingsTests extends AbstractWatcherIntegrationTestCase {
private static final ESLogger logger = Loggers.getLogger(HistoryTemplateEmailMappingsTests.class);
static final String USERNAME = "_user"; static final String USERNAME = "_user";
static final String PASSWORD = "_passwd"; static final String PASSWORD = "_passwd";
private EmailServer server; private static EmailServer server;
@After @AfterClass
public void cleanup() throws Exception { public static void cleanup() throws Exception {
server.stop(); if (server != null) {
server.stop();
}
} }
@Override @Override
@ -52,12 +61,16 @@ public class HistoryTemplateEmailMappingsTests extends AbstractWatcherIntegratio
return false; // remove shield noise from this test return false; // remove shield noise from this test
} }
@Override @BeforeClass
protected Settings nodeSettings(int nodeOrdinal) { public static void setupEmailServer() {
if(server == null) { if(server == null) {
//Need to construct the Email Server here as this happens before init() //Need to construct the Email Server here as this happens before init()
server = EmailServer.localhost("2500-2600", USERNAME, PASSWORD, logger); server = EmailServer.localhost("2500-2600", USERNAME, PASSWORD, logger);
} }
}
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder() return Settings.builder()
.put(super.nodeSettings(nodeOrdinal)) .put(super.nodeSettings(nodeOrdinal))