remove signing of authentication information

Now that TLS is required for node to node communication, we no longer need to sign the
authentication information to prevent tampering.

Original commit: elastic/x-pack-elasticsearch@1f86cf2395
This commit is contained in:
jaymode 2017-02-12 10:39:56 -05:00
parent b3d72af644
commit c8b5be186d
22 changed files with 86 additions and 351 deletions

View File

@ -245,7 +245,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
List<Object> components = new ArrayList<>(); List<Object> components = new ArrayList<>();
components.add(sslService); components.add(sslService);
final InternalClient internalClient = new InternalClient(settings, threadPool, client, security.getCryptoService()); final InternalClient internalClient = new InternalClient(settings, threadPool, client);
components.add(internalClient); components.add(internalClient);
LicenseService licenseService = new LicenseService(settings, clusterService, getClock(), LicenseService licenseService = new LicenseService(settings, clusterService, getClock(),

View File

@ -44,6 +44,6 @@ public class ClientProxy {
public static InternalClient fromClient(Client client) { public static InternalClient fromClient(Client client) {
return client instanceof InternalClient ? (InternalClient) client : return client instanceof InternalClient ? (InternalClient) client :
new InternalClient(client.settings(), client.threadPool(), client, null); new InternalClient(client.settings(), client.threadPool(), client);
} }
} }

View File

@ -25,9 +25,8 @@ import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.node.Node; import org.elasticsearch.node.Node;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.xpack.XPackSettings;
import org.elasticsearch.xpack.security.authc.Authentication; import org.elasticsearch.xpack.security.authc.Authentication;
import org.elasticsearch.xpack.security.authc.AuthenticationService;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.security.user.XPackUser; import org.elasticsearch.xpack.security.user.XPackUser;
import java.io.IOException; import java.io.IOException;
@ -47,19 +46,17 @@ import java.util.function.Supplier;
*/ */
public class InternalClient extends FilterClient { public class InternalClient extends FilterClient {
private final CryptoService cryptoService;
private final boolean signUserHeader;
private final String nodeName; private final String nodeName;
private final boolean securityEnabled;
/** /**
* Constructs an InternalClient. * Constructs an InternalClient.
* If {@code cryptoService} is non-null, the client is secure. Otherwise this client is a passthrough. * If {@code cryptoService} is non-null, the client is secure. Otherwise this client is a passthrough.
*/ */
public InternalClient(Settings settings, ThreadPool threadPool, Client in, CryptoService cryptoService) { public InternalClient(Settings settings, ThreadPool threadPool, Client in) {
super(settings, threadPool, in); super(settings, threadPool, in);
this.cryptoService = cryptoService;
this.signUserHeader = AuthenticationService.SIGN_USER_HEADER.get(settings);
this.nodeName = Node.NODE_NAME_SETTING.get(settings); this.nodeName = Node.NODE_NAME_SETTING.get(settings);
this.securityEnabled = XPackSettings.SECURITY_ENABLED.get(settings);
} }
@Override @Override
@ -67,11 +64,7 @@ public class InternalClient extends FilterClient {
ActionRequestBuilder<Request, Response, RequestBuilder>> void doExecute( ActionRequestBuilder<Request, Response, RequestBuilder>> void doExecute(
Action<Request, Response, RequestBuilder> action, Request request, ActionListener<Response> listener) { Action<Request, Response, RequestBuilder> action, Request request, ActionListener<Response> listener) {
if (cryptoService == null) { if (securityEnabled) {
super.doExecute(action, request, listener);
return;
}
final ThreadContext threadContext = threadPool().getThreadContext(); final ThreadContext threadContext = threadPool().getThreadContext();
final Supplier<ThreadContext.StoredContext> storedContext = threadContext.newRestorableContext(true); final Supplier<ThreadContext.StoredContext> storedContext = threadContext.newRestorableContext(true);
// we need to preserve the context here otherwise we execute the response with the XPack user which we can cause problems // we need to preserve the context here otherwise we execute the response with the XPack user which we can cause problems
@ -80,13 +73,16 @@ public class InternalClient extends FilterClient {
processContext(threadContext); processContext(threadContext);
super.doExecute(action, request, new ContextPreservingActionListener<>(storedContext, listener)); super.doExecute(action, request, new ContextPreservingActionListener<>(storedContext, listener));
} }
} else {
super.doExecute(action, request, listener);
}
} }
protected void processContext(ThreadContext threadContext) { protected void processContext(ThreadContext threadContext) {
try { try {
Authentication authentication = new Authentication(XPackUser.INSTANCE, Authentication authentication = new Authentication(XPackUser.INSTANCE,
new Authentication.RealmRef("__attach", "__attach", nodeName), null); new Authentication.RealmRef("__attach", "__attach", nodeName), null);
authentication.writeToContext(threadContext, cryptoService, signUserHeader); authentication.writeToContext(threadContext);
} catch (IOException ioe) { } catch (IOException ioe) {
throw new ElasticsearchException("failed to attach internal user to request", ioe); throw new ElasticsearchException("failed to attach internal user to request", ioe);
} }

View File

@ -253,7 +253,7 @@ public class Security implements ActionPlugin, IngestPlugin, NetworkPlugin {
} }
threadContext.set(threadPool.getThreadContext()); threadContext.set(threadPool.getThreadContext());
List<Object> components = new ArrayList<>(); List<Object> components = new ArrayList<>();
securityContext.set(new SecurityContext(settings, threadPool.getThreadContext(), cryptoService)); securityContext.set(new SecurityContext(settings, threadPool.getThreadContext()));
components.add(securityContext.get()); components.add(securityContext.get());
// realms construction // realms construction
@ -321,8 +321,7 @@ public class Security implements ActionPlugin, IngestPlugin, NetworkPlugin {
logger.debug("Using authentication failure handler from extension [" + extensionName + "]"); logger.debug("Using authentication failure handler from extension [" + extensionName + "]");
} }
authcService.set(new AuthenticationService(settings, realms, auditTrailService, authcService.set(new AuthenticationService(settings, realms, auditTrailService, failureHandler, threadPool, anonymousUser));
cryptoService, failureHandler, threadPool, anonymousUser));
components.add(authcService.get()); components.add(authcService.get());
final FileRolesStore fileRolesStore = new FileRolesStore(settings, env, resourceWatcherService, licenseState); final FileRolesStore fileRolesStore = new FileRolesStore(settings, env, resourceWatcherService, licenseState);

View File

@ -12,8 +12,6 @@ import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.common.util.concurrent.ThreadContext.StoredContext; import org.elasticsearch.common.util.concurrent.ThreadContext.StoredContext;
import org.elasticsearch.node.Node; import org.elasticsearch.node.Node;
import org.elasticsearch.xpack.security.authc.Authentication; import org.elasticsearch.xpack.security.authc.Authentication;
import org.elasticsearch.xpack.security.authc.AuthenticationService;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.user.User;
import java.io.IOException; import java.io.IOException;
@ -27,8 +25,6 @@ public class SecurityContext {
private final Logger logger; private final Logger logger;
private final ThreadContext threadContext; private final ThreadContext threadContext;
private final CryptoService cryptoService;
private final boolean signUserHeader;
private final String nodeName; private final String nodeName;
/** /**
@ -36,11 +32,9 @@ public class SecurityContext {
* If cryptoService is null, security is disabled and {@link #getUser()} * If cryptoService is null, security is disabled and {@link #getUser()}
* and {@link #getAuthentication()} will always return null. * and {@link #getAuthentication()} will always return null.
*/ */
public SecurityContext(Settings settings, ThreadContext threadContext, CryptoService cryptoService) { public SecurityContext(Settings settings, ThreadContext threadContext) {
this.logger = Loggers.getLogger(getClass(), settings); this.logger = Loggers.getLogger(getClass(), settings);
this.threadContext = threadContext; this.threadContext = threadContext;
this.cryptoService = cryptoService;
this.signUserHeader = AuthenticationService.SIGN_USER_HEADER.get(settings);
this.nodeName = Node.NODE_NAME_SETTING.get(settings); this.nodeName = Node.NODE_NAME_SETTING.get(settings);
} }
@ -53,7 +47,7 @@ public class SecurityContext {
/** Returns the authentication information, or null if the current request has no authentication info. */ /** Returns the authentication information, or null if the current request has no authentication info. */
public Authentication getAuthentication() { public Authentication getAuthentication() {
try { try {
return Authentication.readFromContext(threadContext, cryptoService, signUserHeader); return Authentication.readFromContext(threadContext);
} catch (IOException e) { } catch (IOException e) {
// TODO: this seems bogus, the only way to get an ioexception here is from a corrupt or tampered // TODO: this seems bogus, the only way to get an ioexception here is from a corrupt or tampered
// auth header, which should be be audited? // auth header, which should be be audited?
@ -78,7 +72,7 @@ public class SecurityContext {
try { try {
Authentication authentication = Authentication authentication =
new Authentication(user, new Authentication.RealmRef("__attach", "__attach", nodeName), lookedUpBy); new Authentication(user, new Authentication.RealmRef("__attach", "__attach", nodeName), lookedUpBy);
authentication.writeToContext(threadContext, cryptoService, signUserHeader); authentication.writeToContext(threadContext);
} catch (IOException e) { } catch (IOException e) {
throw new AssertionError("how can we have a IOException with a user we set", e); throw new AssertionError("how can we have a IOException with a user we set", e);
} }

View File

@ -24,8 +24,6 @@ import org.elasticsearch.xpack.security.user.User;
public class AuditTrailService extends AbstractComponent implements AuditTrail { public class AuditTrailService extends AbstractComponent implements AuditTrail {
public static final Map<String, Object> DISABLED_USAGE_STATS = Collections.singletonMap("enabled", false);
private final XPackLicenseState licenseState; private final XPackLicenseState licenseState;
final List<AuditTrail> auditTrails; final List<AuditTrail> auditTrails;

View File

@ -11,7 +11,6 @@ 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.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.user.User;
import java.io.IOException; import java.io.IOException;
@ -77,7 +76,7 @@ public class Authentication {
return version; return version;
} }
public static Authentication readFromContext(ThreadContext ctx, CryptoService cryptoService, boolean sign) public static Authentication readFromContext(ThreadContext ctx)
throws IOException, IllegalArgumentException { throws IOException, IllegalArgumentException {
Authentication authentication = ctx.getTransient(AUTHENTICATION_KEY); Authentication authentication = ctx.getTransient(AUTHENTICATION_KEY);
if (authentication != null) { if (authentication != null) {
@ -89,19 +88,16 @@ public class Authentication {
if (authenticationHeader == null) { if (authenticationHeader == null) {
return null; return null;
} }
return deserializeHeaderAndPutInContext(authenticationHeader, ctx, cryptoService, sign); return deserializeHeaderAndPutInContext(authenticationHeader, ctx);
} }
public static Authentication getAuthentication(ThreadContext context) { public static Authentication getAuthentication(ThreadContext context) {
return context.getTransient(Authentication.AUTHENTICATION_KEY); return context.getTransient(Authentication.AUTHENTICATION_KEY);
} }
static Authentication deserializeHeaderAndPutInContext(String header, ThreadContext ctx, CryptoService cryptoService, boolean sign) static Authentication deserializeHeaderAndPutInContext(String header, ThreadContext ctx)
throws IOException, IllegalArgumentException { throws IOException, IllegalArgumentException {
assert ctx.getTransient(AUTHENTICATION_KEY) == null; assert ctx.getTransient(AUTHENTICATION_KEY) == null;
if (sign) {
header = cryptoService.unsignAndVerify(header);
}
byte[] bytes = Base64.getDecoder().decode(header); byte[] bytes = Base64.getDecoder().decode(header);
StreamInput input = StreamInput.wrap(bytes); StreamInput input = StreamInput.wrap(bytes);
@ -112,7 +108,7 @@ public class Authentication {
return authentication; return authentication;
} }
void writeToContextIfMissing(ThreadContext context, CryptoService cryptoService, boolean sign) void writeToContextIfMissing(ThreadContext context)
throws IOException, IllegalArgumentException { throws IOException, IllegalArgumentException {
if (context.getTransient(AUTHENTICATION_KEY) != null) { if (context.getTransient(AUTHENTICATION_KEY) != null) {
if (context.getHeader(AUTHENTICATION_KEY) == null) { if (context.getHeader(AUTHENTICATION_KEY) == null) {
@ -122,9 +118,9 @@ public class Authentication {
} }
if (context.getHeader(AUTHENTICATION_KEY) != null) { if (context.getHeader(AUTHENTICATION_KEY) != null) {
deserializeHeaderAndPutInContext(context.getHeader(AUTHENTICATION_KEY), context, cryptoService, sign); deserializeHeaderAndPutInContext(context.getHeader(AUTHENTICATION_KEY), context);
} else { } else {
writeToContext(context, cryptoService, sign); writeToContext(context);
} }
} }
@ -132,13 +128,10 @@ public class Authentication {
* Writes the authentication to the context. There must not be an existing authentication in the context and if there is an * Writes the authentication to the context. There must not be an existing authentication in the context and if there is an
* {@link IllegalStateException} will be thrown * {@link IllegalStateException} will be thrown
*/ */
public void writeToContext(ThreadContext ctx, CryptoService cryptoService, boolean sign) public void writeToContext(ThreadContext ctx)
throws IOException, IllegalArgumentException { throws IOException, IllegalArgumentException {
ensureContextDoesNotContainAuthentication(ctx); ensureContextDoesNotContainAuthentication(ctx);
String header = encode(); String header = encode();
if (sign) {
header = cryptoService.sign(header);
}
ctx.putTransient(AUTHENTICATION_KEY, this); ctx.putTransient(AUTHENTICATION_KEY, this);
ctx.putHeader(AUTHENTICATION_KEY, header); ctx.putHeader(AUTHENTICATION_KEY, header);
} }

View File

@ -50,26 +50,22 @@ public class AuthenticationService extends AbstractComponent {
private final Realms realms; private final Realms realms;
private final AuditTrail auditTrail; private final AuditTrail auditTrail;
private final CryptoService cryptoService;
private final AuthenticationFailureHandler failureHandler; private final AuthenticationFailureHandler failureHandler;
private final ThreadContext threadContext; private final ThreadContext threadContext;
private final String nodeName; private final String nodeName;
private final AnonymousUser anonymousUser; private final AnonymousUser anonymousUser;
private final boolean signUserHeader;
private final boolean runAsEnabled; private final boolean runAsEnabled;
private final boolean isAnonymousUserEnabled; private final boolean isAnonymousUserEnabled;
public AuthenticationService(Settings settings, Realms realms, AuditTrailService auditTrail, CryptoService cryptoService, public AuthenticationService(Settings settings, Realms realms, AuditTrailService auditTrail,
AuthenticationFailureHandler failureHandler, ThreadPool threadPool, AnonymousUser anonymousUser) { AuthenticationFailureHandler failureHandler, ThreadPool threadPool, AnonymousUser anonymousUser) {
super(settings); super(settings);
this.nodeName = Node.NODE_NAME_SETTING.get(settings); this.nodeName = Node.NODE_NAME_SETTING.get(settings);
this.realms = realms; this.realms = realms;
this.auditTrail = auditTrail; this.auditTrail = auditTrail;
this.cryptoService = cryptoService;
this.failureHandler = failureHandler; this.failureHandler = failureHandler;
this.threadContext = threadPool.getThreadContext(); this.threadContext = threadPool.getThreadContext();
this.anonymousUser = anonymousUser; this.anonymousUser = anonymousUser;
this.signUserHeader = SIGN_USER_HEADER.get(settings);
this.runAsEnabled = RUN_AS_ENABLED.get(settings); this.runAsEnabled = RUN_AS_ENABLED.get(settings);
this.isAnonymousUserEnabled = AnonymousUser.isAnonymousEnabled(settings); this.isAnonymousUserEnabled = AnonymousUser.isAnonymousEnabled(settings);
} }
@ -110,7 +106,7 @@ public class AuthenticationService extends AbstractComponent {
*/ */
void attachUserIfMissing(User user) throws IOException { void attachUserIfMissing(User user) throws IOException {
Authentication authentication = new Authentication(user, new RealmRef("__attach", "__attach", nodeName), null); Authentication authentication = new Authentication(user, new RealmRef("__attach", "__attach", nodeName), null);
authentication.writeToContextIfMissing(threadContext, cryptoService, signUserHeader); authentication.writeToContextIfMissing(threadContext);
} }
// pkg private method for testing // pkg private method for testing
@ -182,7 +178,7 @@ public class AuthenticationService extends AbstractComponent {
private void lookForExistingAuthentication(Consumer<Authentication> authenticationConsumer) { private void lookForExistingAuthentication(Consumer<Authentication> authenticationConsumer) {
Runnable action; Runnable action;
try { try {
final Authentication authentication = Authentication.readFromContext(threadContext, cryptoService, signUserHeader); final Authentication authentication = Authentication.readFromContext(threadContext);
if (authentication != null && request instanceof AuditableRestRequest) { if (authentication != null && request instanceof AuditableRestRequest) {
action = () -> listener.onFailure(request.tamperedRequest()); action = () -> listener.onFailure(request.tamperedRequest());
} else { } else {
@ -293,7 +289,7 @@ public class AuthenticationService extends AbstractComponent {
Runnable action; Runnable action;
if (authentication != null) { if (authentication != null) {
try { try {
authentication.writeToContext(threadContext, cryptoService, signUserHeader); authentication.writeToContext(threadContext);
request.authenticationSuccess(authentication.getAuthenticatedBy().getName(), authentication.getUser()); request.authenticationSuccess(authentication.getAuthenticatedBy().getName(), authentication.getUser());
action = () -> listener.onResponse(authentication); action = () -> listener.onResponse(authentication);
} catch (Exception e) { } catch (Exception e) {
@ -377,7 +373,7 @@ public class AuthenticationService extends AbstractComponent {
final Authentication finalAuth = new Authentication(finalUser, authenticatedBy, lookedupBy); final Authentication finalAuth = new Authentication(finalUser, authenticatedBy, lookedupBy);
Runnable action = () -> listener.onResponse(finalAuth); Runnable action = () -> listener.onResponse(finalAuth);
try { try {
finalAuth.writeToContext(threadContext, cryptoService, signUserHeader); finalAuth.writeToContext(threadContext);
} catch (Exception e) { } catch (Exception e) {
action = () -> listener.onFailure(request.exceptionProcessingRequest(e, authenticationToken)); action = () -> listener.onFailure(request.exceptionProcessingRequest(e, authenticationToken));
} }

View File

@ -15,22 +15,18 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; 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.security.InvalidKeyException;
import java.security.MessageDigest; 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.Base64;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Setting.Property;
@ -56,10 +52,8 @@ public class CryptoService extends AbstractComponent {
static final String DEFAULT_KEY_ALGORITH = "AES"; static final String DEFAULT_KEY_ALGORITH = "AES";
static final String ENCRYPTED_TEXT_PREFIX = "::es_encrypted::"; static final String ENCRYPTED_TEXT_PREFIX = "::es_encrypted::";
static final int DEFAULT_KEY_LENGTH = 128; static final int DEFAULT_KEY_LENGTH = 128;
static final int RANDOM_KEY_SIZE = 128;
private static final Pattern SIG_PATTERN = Pattern.compile("^\\$\\$[0-9]+\\$\\$[^\\$]*\\$\\$.+"); private static final Pattern SIG_PATTERN = Pattern.compile("^\\$\\$[0-9]+\\$\\$[^\\$]*\\$\\$.+");
private static final byte[] HKDF_APP_INFO = "es-security-crypto-service".getBytes(StandardCharsets.UTF_8);
private static final Setting<Boolean> SYSTEM_KEY_REQUIRED_SETTING = private static final Setting<Boolean> SYSTEM_KEY_REQUIRED_SETTING =
Setting.boolSetting(setting("system_key.required"), false, Property.NodeScope); Setting.boolSetting(setting("system_key.required"), false, Property.NodeScope);
@ -72,36 +66,27 @@ public class CryptoService extends AbstractComponent {
private final SecureRandom secureRandom = new SecureRandom(); private final SecureRandom secureRandom = new SecureRandom();
private final String encryptionAlgorithm; private final String encryptionAlgorithm;
private final String keyAlgorithm;
private final int keyLength;
private final int ivLength; private final int ivLength;
/*
private final Path keyFile; * Scroll ids are signed using the system key to authenticate them as we currently do not have a proper way to authorize these requests
* and the key is also used for encrypting sensitive data stored in watches. The encryption key is derived from the system key.
private final SecretKey randomKey; */
private final String randomKeyBase64;
private final SecretKey encryptionKey; private final SecretKey encryptionKey;
private final SecretKey systemKey; private final SecretKey systemKey;
private final SecretKey signingKey;
public CryptoService(Settings settings, Environment env) throws IOException { public CryptoService(Settings settings, Environment env) throws IOException {
super(settings); super(settings);
this.encryptionAlgorithm = ENCRYPTION_ALGO_SETTING.get(settings); this.encryptionAlgorithm = ENCRYPTION_ALGO_SETTING.get(settings);
this.keyLength = ENCRYPTION_KEY_LENGTH_SETTING.get(settings); final int keyLength = ENCRYPTION_KEY_LENGTH_SETTING.get(settings);
this.ivLength = keyLength / 8; this.ivLength = keyLength / 8;
this.keyAlgorithm = ENCRYPTION_KEY_ALGO_SETTING.get(settings); String keyAlgorithm = ENCRYPTION_KEY_ALGO_SETTING.get(settings);
if (keyLength % 8 != 0) { if (keyLength % 8 != 0) {
throw new IllegalArgumentException("invalid key length [" + keyLength + "]. value must be a multiple of 8"); throw new IllegalArgumentException("invalid key length [" + keyLength + "]. value must be a multiple of 8");
} }
keyFile = resolveSystemKey(env); Path keyFile = resolveSystemKey(env);
systemKey = readSystemKey(keyFile, SYSTEM_KEY_REQUIRED_SETTING.get(settings)); systemKey = readSystemKey(keyFile, SYSTEM_KEY_REQUIRED_SETTING.get(settings));
randomKey = generateSecretKey(RANDOM_KEY_SIZE);
randomKeyBase64 = Base64.getUrlEncoder().encodeToString(randomKey.getEncoded());
signingKey = createSigningKey(systemKey, randomKey);
try { try {
encryptionKey = encryptionKey(systemKey, keyLength, keyAlgorithm); encryptionKey = encryptionKey(systemKey, keyLength, keyAlgorithm);
@ -131,18 +116,6 @@ public class CryptoService extends AbstractComponent {
return XPackPlugin.resolveConfigFile(env, FILE_NAME); return XPackPlugin.resolveConfigFile(env, FILE_NAME);
} }
static SecretKey createSigningKey(@Nullable SecretKey systemKey, SecretKey randomKey) {
assert randomKey != null;
if (systemKey != null) {
return systemKey;
} else {
// the random key is only 128 bits so we use HKDF to expand to 1024 bits with some application specific data mixed in
byte[] keyBytes = HmacSHA1HKDF.extractAndExpand(null, randomKey.getEncoded(), HKDF_APP_INFO, (KEY_SIZE / 8));
assert keyBytes.length * 8 == KEY_SIZE;
return new SecretKeySpec(keyBytes, KEY_ALGO);
}
}
private static SecretKey readSystemKey(Path file, boolean required) throws IOException { private static SecretKey readSystemKey(Path file, boolean required) throws IOException {
if (Files.exists(file)) { if (Files.exists(file)) {
byte[] bytes = Files.readAllBytes(file); byte[] bytes = Files.readAllBytes(file);
@ -161,8 +134,12 @@ public class CryptoService extends AbstractComponent {
* @param text the string to sign * @param text the string to sign
*/ */
public String sign(String text) throws IOException { public String sign(String text) throws IOException {
String sigStr = signInternal(text, signingKey); if (systemKey != null) {
return "$$" + sigStr.length() + "$$" + (systemKey == signingKey ? "" : randomKeyBase64) + "$$" + sigStr + text; String sigStr = signInternal(text, systemKey);
return "$$" + sigStr.length() + "$$$$" + sigStr + text;
} else {
return text;
}
} }
/** /**
@ -171,22 +148,24 @@ public class CryptoService extends AbstractComponent {
* @param signedText the string to unsign and verify * @param signedText the string to unsign and verify
*/ */
public String unsignAndVerify(String signedText) { public String unsignAndVerify(String signedText) {
if (systemKey == null) {
return signedText;
}
if (!signedText.startsWith("$$") || signedText.length() < 2) { if (!signedText.startsWith("$$") || signedText.length() < 2) {
throw new IllegalArgumentException("tampered signed text"); throw new IllegalArgumentException("tampered signed text");
} }
// $$34$$randomKeyBase64$$sigtext // $$34$$$$sigtext
String[] pieces = signedText.split("\\$\\$"); String[] pieces = signedText.split("\\$\\$");
if (pieces.length != 4 || !pieces[0].equals("")) { if (pieces.length != 4 || pieces[0].isEmpty() == false || pieces[2].isEmpty() == false) {
logger.debug("received signed text [{}] with [{}] parts", signedText, pieces.length); logger.debug("received signed text [{}] with [{}] parts", signedText, pieces.length);
throw new IllegalArgumentException("tampered signed text"); throw new IllegalArgumentException("tampered signed text");
} }
String text; String text;
String base64RandomKey;
String receivedSignature; String receivedSignature;
try { try {
int length = Integer.parseInt(pieces[1]); int length = Integer.parseInt(pieces[1]);
base64RandomKey = pieces[2];
receivedSignature = pieces[3].substring(0, length); receivedSignature = pieces[3].substring(0, length);
text = pieces[3].substring(length); text = pieces[3].substring(length);
} catch (Exception e) { } catch (Exception e) {
@ -194,36 +173,8 @@ public class CryptoService extends AbstractComponent {
throw new IllegalArgumentException("tampered signed text"); throw new IllegalArgumentException("tampered signed text");
} }
SecretKey signingKey;
// no random key, so we must have a system key
if (base64RandomKey.isEmpty()) {
if (systemKey == null) {
logger.debug("received signed text without random key information and no system key is present");
throw new IllegalArgumentException("tampered signed text");
}
signingKey = systemKey;
} else if (systemKey != null) {
// we have a system key and there is some random key data, this is an error
logger.debug("received signed text with random key information but a system key is present");
throw new IllegalArgumentException("tampered signed text");
} else {
byte[] randomKeyBytes;
try { try {
randomKeyBytes = Base64.getUrlDecoder().decode(base64RandomKey); String sig = signInternal(text, systemKey);
} catch (IllegalArgumentException e) {
logger.error("error occurred while decoding key data", e);
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 {
String sig = signInternal(text, signingKey);
if (constantTimeEquals(sig, receivedSignature)) { if (constantTimeEquals(sig, receivedSignature)) {
return text; return text;
} }
@ -409,90 +360,6 @@ public class CryptoService extends AbstractComponent {
} }
/**
* Simplified implementation of HKDF using the HmacSHA1 algortihm.
*
* @see <a href=https://tools.ietf.org/html/rfc5869>RFC 5869</a>
*/
private static class HmacSHA1HKDF {
private static final int HMAC_SHA1_BYTE_LENGTH = 20;
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
/**
* This method performs the <code>extract</code> and <code>expand</code> steps of HKDF in one call with the given
* data. The output of the extract step is used as the input to the expand step
*
* @param salt optional salt value (a non-secret random value); if not provided, it is set to a string of HashLen zeros.
* @param ikm the input keying material
* @param info optional context and application specific information; if not provided a zero length byte[] is used
* @param outputLength length of output keying material in octets (&lt;= 255*HashLen)
* @return the output keying material
*/
static byte[] extractAndExpand(@Nullable SecretKey salt, byte[] ikm, @Nullable byte[] info, int outputLength) {
// arg checking
Objects.requireNonNull(ikm, "the input keying material must not be null");
if (outputLength < 1) {
throw new IllegalArgumentException("output length must be positive int >= 1");
}
if (outputLength > 255 * HMAC_SHA1_BYTE_LENGTH) {
throw new IllegalArgumentException("output length must be <= 255*" + HMAC_SHA1_BYTE_LENGTH);
}
if (salt == null) {
salt = new SecretKeySpec(new byte[HMAC_SHA1_BYTE_LENGTH], HMAC_SHA1_ALGORITHM);
}
if (info == null) {
info = new byte[0];
}
// extract
Mac mac = createMac(salt);
byte[] keyBytes = mac.doFinal(ikm);
final SecretKey pseudoRandomKey = new SecretKeySpec(keyBytes, HMAC_SHA1_ALGORITHM);
/*
* The output OKM is calculated as follows:
* N = ceil(L/HashLen)
* T = T(1) | T(2) | T(3) | ... | T(N)
* OKM = first L octets of T
*
* where:
* T(0) = empty string (zero length)
* T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
* T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
* T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
* ...
*
* (where the constant concatenated to the end of each T(n) is a single octet.)
*/
int n = (outputLength % HMAC_SHA1_BYTE_LENGTH == 0) ?
outputLength / HMAC_SHA1_BYTE_LENGTH :
(outputLength / HMAC_SHA1_BYTE_LENGTH) + 1;
byte[] hashRound = new byte[0];
ByteBuffer generatedBytes = ByteBuffer.allocate(Math.multiplyExact(n, HMAC_SHA1_BYTE_LENGTH));
try {
// initiliaze the mac with the new key
mac.init(pseudoRandomKey);
} catch (InvalidKeyException e) {
throw new ElasticsearchException("failed to initialize the mac", e);
}
for (int roundNum = 1; roundNum <= n; roundNum++) {
mac.reset();
mac.update(hashRound);
mac.update(info);
mac.update((byte) roundNum);
hashRound = mac.doFinal();
generatedBytes.put(hashRound);
}
byte[] result = new byte[outputLength];
generatedBytes.rewind();
generatedBytes.get(result, 0, outputLength);
return result;
}
}
public static void addSettings(List<Setting<?>> settings) { public static void addSettings(List<Setting<?>> settings) {
settings.add(ENCRYPTION_KEY_LENGTH_SETTING); settings.add(ENCRYPTION_KEY_LENGTH_SETTING);
settings.add(ENCRYPTION_KEY_ALGO_SETTING); settings.add(ENCRYPTION_KEY_ALGO_SETTING);

View File

@ -64,7 +64,7 @@ public class WatcherClientProxy extends ClientProxy {
*/ */
public static WatcherClientProxy of(Client client) { public static WatcherClientProxy of(Client client) {
return new WatcherClientProxy(Settings.EMPTY, client instanceof InternalClient ? (InternalClient) client : return new WatcherClientProxy(Settings.EMPTY, client instanceof InternalClient ? (InternalClient) client :
new InternalClient(client.settings(), client.threadPool(), client, null)); new InternalClient(client.settings(), client.threadPool(), client));
} }
public IndexResponse index(IndexRequest request, TimeValue timeout) { public IndexResponse index(IndexRequest request, TimeValue timeout) {

View File

@ -14,14 +14,11 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.FilterClient; import org.elasticsearch.client.FilterClient;
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.env.Environment;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.TestThreadPool; import org.elasticsearch.threadpool.TestThreadPool;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -51,9 +48,7 @@ public class InternalClientTests extends ESTestCase {
} }
}; };
Path tempDir = createTempDir(); InternalClient client = new InternalClient(Settings.EMPTY, threadPool, dummy) {
InternalClient client = new InternalClient(Settings.EMPTY, threadPool, dummy, new CryptoService(Settings.EMPTY,
new Environment(Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), tempDir.toString()).build()))) {
@Override @Override
protected void processContext(ThreadContext threadContext) { protected void processContext(ThreadContext threadContext) {
threadContext.putTransient("foo", "boom"); threadContext.putTransient("foo", "boom");
@ -104,9 +99,7 @@ public class InternalClientTests extends ESTestCase {
} }
}; };
Path tempDir = createTempDir(); InternalClient client = new InternalClient(Settings.EMPTY, threadPool, dummy) {
InternalClient client = new InternalClient(Settings.EMPTY, threadPool, dummy, new CryptoService(Settings.EMPTY,
new Environment(Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), tempDir.toString()).build()))) {
@Override @Override
protected void processContext(ThreadContext threadContext) { protected void processContext(ThreadContext threadContext) {
threadContext.putTransient("foo", "boom"); threadContext.putTransient("foo", "boom");

View File

@ -8,12 +8,9 @@ package org.elasticsearch.xpack.security;
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.common.util.concurrent.ThreadContext.StoredContext; import org.elasticsearch.common.util.concurrent.ThreadContext.StoredContext;
import org.elasticsearch.env.Environment;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.security.authc.Authentication; import org.elasticsearch.xpack.security.authc.Authentication;
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef; import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
import org.elasticsearch.xpack.security.authc.AuthenticationService;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.security.user.SystemUser; import org.elasticsearch.xpack.security.user.SystemUser;
import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.user.User;
import org.junit.Before; import org.junit.Before;
@ -23,22 +20,17 @@ import java.util.concurrent.atomic.AtomicReference;
public class SecurityContextTests extends ESTestCase { public class SecurityContextTests extends ESTestCase {
private boolean signHeader;
private Settings settings; private Settings settings;
private ThreadContext threadContext; private ThreadContext threadContext;
private CryptoService cryptoService;
private SecurityContext securityContext; private SecurityContext securityContext;
@Before @Before
public void buildSecurityContext() throws IOException { public void buildSecurityContext() throws IOException {
signHeader = randomBoolean();
settings = Settings.builder() settings = Settings.builder()
.put("path.home", createTempDir()) .put("path.home", createTempDir())
.put(AuthenticationService.SIGN_USER_HEADER.getKey(), signHeader)
.build(); .build();
threadContext = new ThreadContext(settings); threadContext = new ThreadContext(settings);
cryptoService = new CryptoService(settings, new Environment(settings)); securityContext = new SecurityContext(settings, threadContext);
securityContext = new SecurityContext(settings, threadContext, cryptoService);
} }
public void testGetAuthenticationAndUserInEmptyContext() throws IOException { public void testGetAuthenticationAndUserInEmptyContext() throws IOException {
@ -49,7 +41,7 @@ public class SecurityContextTests extends ESTestCase {
public void testGetAuthenticationAndUser() throws IOException { public void testGetAuthenticationAndUser() throws IOException {
final User user = new User("test"); final User user = new User("test");
final Authentication authentication = new Authentication(user, new RealmRef("ldap", "foo", "node1"), null); final Authentication authentication = new Authentication(user, new RealmRef("ldap", "foo", "node1"), null);
authentication.writeToContext(threadContext, cryptoService, signHeader); authentication.writeToContext(threadContext);
assertEquals(authentication, securityContext.getAuthentication()); assertEquals(authentication, securityContext.getAuthentication());
assertEquals(user, securityContext.getUser()); assertEquals(user, securityContext.getUser());
@ -72,7 +64,7 @@ public class SecurityContextTests extends ESTestCase {
if (randomBoolean()) { if (randomBoolean()) {
original = new User("test"); original = new User("test");
final Authentication authentication = new Authentication(original, new RealmRef("ldap", "foo", "node1"), null); final Authentication authentication = new Authentication(original, new RealmRef("ldap", "foo", "node1"), null);
authentication.writeToContext(threadContext, cryptoService, signHeader); authentication.writeToContext(threadContext);
} else { } else {
original = null; original = null;
} }

View File

@ -81,7 +81,7 @@ public class SecurityTemplateServiceTests extends ESTestCase {
transportClient = new MockTransportClient(Settings.EMPTY); transportClient = new MockTransportClient(Settings.EMPTY);
class IClient extends InternalClient { class IClient extends InternalClient {
IClient(Client transportClient) { IClient(Client transportClient) {
super(Settings.EMPTY, null, transportClient, null); super(Settings.EMPTY, null, transportClient);
} }
@Override @Override

View File

@ -82,7 +82,7 @@ public class SecurityActionFilterTests extends ESTestCase {
DestructiveOperations destructiveOperations = new DestructiveOperations(settings, DestructiveOperations destructiveOperations = new DestructiveOperations(settings,
new ClusterSettings(settings, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING))); new ClusterSettings(settings, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)));
SecurityContext securityContext = new SecurityContext(settings, threadContext, cryptoService); SecurityContext securityContext = new SecurityContext(settings, threadContext);
filter = new SecurityActionFilter(Settings.EMPTY, authcService, authzService, cryptoService, auditTrail, filter = new SecurityActionFilter(Settings.EMPTY, authcService, authzService, cryptoService, auditTrail,
licenseState, new HashSet<>(), threadPool, securityContext, destructiveOperations); licenseState, new HashSet<>(), threadPool, securityContext, destructiveOperations);
} }

View File

@ -63,7 +63,7 @@ public class IndexAuditTrailMutedTests extends ESTestCase {
clientCalled = new AtomicBoolean(false); clientCalled = new AtomicBoolean(false);
class IClient extends InternalClient { class IClient extends InternalClient {
IClient(Client transportClient){ IClient(Client transportClient){
super(Settings.EMPTY, null, transportClient, null); super(Settings.EMPTY, null, transportClient);
} }
@Override @Override
protected <Request extends ActionRequest, Response extends ActionResponse, RequestBuilder extends protected <Request extends ActionRequest, Response extends ActionResponse, RequestBuilder extends

View File

@ -33,7 +33,6 @@ import org.elasticsearch.xpack.security.authc.Realm.Factory;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm; import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
import org.elasticsearch.xpack.security.authc.support.SecuredString; import org.elasticsearch.xpack.security.authc.support.SecuredString;
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken; import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.security.user.AnonymousUser; import org.elasticsearch.xpack.security.user.AnonymousUser;
import org.elasticsearch.xpack.security.user.SystemUser; import org.elasticsearch.xpack.security.user.SystemUser;
import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.user.User;
@ -74,7 +73,6 @@ public class AuthenticationServiceTests extends ESTestCase {
private Realm secondRealm; private Realm secondRealm;
private AuditTrailService auditTrail; private AuditTrailService auditTrail;
private AuthenticationToken token; private AuthenticationToken token;
private CryptoService cryptoService;
private ThreadPool threadPool; private ThreadPool threadPool;
private ThreadContext threadContext; private ThreadContext threadContext;
@ -98,14 +96,12 @@ public class AuthenticationServiceTests extends ESTestCase {
when(licenseState.isAuthAllowed()).thenReturn(true); when(licenseState.isAuthAllowed()).thenReturn(true);
realms = new TestRealms(Settings.EMPTY, new Environment(settings), Collections.<String, Realm.Factory>emptyMap(), realms = new TestRealms(Settings.EMPTY, new Environment(settings), Collections.<String, Realm.Factory>emptyMap(),
licenseState, mock(ReservedRealm.class), Arrays.asList(firstRealm, secondRealm), Collections.singletonList(firstRealm)); licenseState, mock(ReservedRealm.class), Arrays.asList(firstRealm, secondRealm), Collections.singletonList(firstRealm));
cryptoService = mock(CryptoService.class);
auditTrail = mock(AuditTrailService.class); auditTrail = mock(AuditTrailService.class);
threadPool = mock(ThreadPool.class); threadPool = mock(ThreadPool.class);
threadContext = new ThreadContext(Settings.EMPTY); threadContext = new ThreadContext(Settings.EMPTY);
when(threadPool.getThreadContext()).thenReturn(threadContext); when(threadPool.getThreadContext()).thenReturn(threadContext);
when(cryptoService.sign(any(String.class))).thenReturn("_signed_auth"); service = new AuthenticationService(settings, realms, auditTrail,
service = new AuthenticationService(settings, realms, auditTrail, cryptoService,
new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(settings)); new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(settings));
} }
@ -156,7 +152,6 @@ public class AuthenticationServiceTests extends ESTestCase {
assertThat(result.getLookedUpBy(), is(nullValue())); assertThat(result.getLookedUpBy(), is(nullValue()));
assertThat(result.getAuthenticatedBy(), is(notNullValue())); // TODO implement equals assertThat(result.getAuthenticatedBy(), is(notNullValue())); // TODO implement equals
verify(auditTrail).authenticationFailed(firstRealm.name(), token, "_action", message); verify(auditTrail).authenticationFailed(firstRealm.name(), token, "_action", message);
verify(cryptoService).sign(any(String.class));
assertThreadContextContainsAuthentication(result); assertThreadContextContainsAuthentication(result);
} }
@ -178,7 +173,7 @@ public class AuthenticationServiceTests extends ESTestCase {
public void testAuthenticateCached() throws Exception { public void testAuthenticateCached() throws Exception {
final Authentication authentication = new Authentication(new User("_username", "r1"), new RealmRef("test", "cached", "foo"), null); final Authentication authentication = new Authentication(new User("_username", "r1"), new RealmRef("test", "cached", "foo"), null);
authentication.writeToContext(threadContext, cryptoService, true); authentication.writeToContext(threadContext);
Authentication result = authenticateBlocking("_action", message, null); Authentication result = authenticateBlocking("_action", message, null);
@ -187,7 +182,6 @@ public class AuthenticationServiceTests extends ESTestCase {
verifyZeroInteractions(auditTrail); verifyZeroInteractions(auditTrail);
verifyZeroInteractions(firstRealm); verifyZeroInteractions(firstRealm);
verifyZeroInteractions(secondRealm); verifyZeroInteractions(secondRealm);
verify(cryptoService).sign(any(String.class));
} }
public void testAuthenticateNonExistentRestRequestUserThrowsAuthenticationException() throws Exception { public void testAuthenticateNonExistentRestRequestUserThrowsAuthenticationException() throws Exception {
@ -337,7 +331,7 @@ public class AuthenticationServiceTests extends ESTestCase {
InternalMessage message1 = new InternalMessage(); InternalMessage message1 = new InternalMessage();
ThreadContext threadContext1 = new ThreadContext(Settings.EMPTY); ThreadContext threadContext1 = new ThreadContext(Settings.EMPTY);
when(threadPool.getThreadContext()).thenReturn(threadContext1); when(threadPool.getThreadContext()).thenReturn(threadContext1);
service = new AuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, service = new AuthenticationService(Settings.EMPTY, realms, auditTrail,
new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(Settings.EMPTY)); new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(Settings.EMPTY));
threadContext1.putTransient(Authentication.AUTHENTICATION_KEY, threadContext.getTransient(Authentication.AUTHENTICATION_KEY)); threadContext1.putTransient(Authentication.AUTHENTICATION_KEY, threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
@ -350,57 +344,9 @@ public class AuthenticationServiceTests extends ESTestCase {
// checking authentication from the user header // checking authentication from the user header
threadContext1 = new ThreadContext(Settings.EMPTY); threadContext1 = new ThreadContext(Settings.EMPTY);
when(threadPool.getThreadContext()).thenReturn(threadContext1); when(threadPool.getThreadContext()).thenReturn(threadContext1);
service = new AuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, service = new AuthenticationService(Settings.EMPTY, realms, auditTrail,
new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(Settings.EMPTY)); new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(Settings.EMPTY));
threadContext1.putHeader(Authentication.AUTHENTICATION_KEY, threadContext.getHeader(Authentication.AUTHENTICATION_KEY)); threadContext1.putHeader(Authentication.AUTHENTICATION_KEY, threadContext.getHeader(Authentication.AUTHENTICATION_KEY));
when(cryptoService.unsignAndVerify("_signed_auth")).thenReturn(authentication.encode());
BytesStreamOutput output = new BytesStreamOutput();
threadContext1.writeTo(output);
StreamInput input = output.bytes().streamInput();
threadContext1 = new ThreadContext(Settings.EMPTY);
threadContext1.readHeaders(input);
when(threadPool.getThreadContext()).thenReturn(threadContext1);
service = new AuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService,
new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(Settings.EMPTY));
Authentication result = authenticateBlocking("_action", new InternalMessage(), SystemUser.INSTANCE);
assertThat(result, notNullValue());
assertThat(result.getUser(), equalTo(user1));
verifyZeroInteractions(firstRealm);
}
public void testAuthenticateTransportContextAndHeaderNoSigning() throws Exception {
Settings settings = Settings.builder().put(AuthenticationService.SIGN_USER_HEADER.getKey(), false).build();
service = new AuthenticationService(settings, realms, auditTrail, cryptoService,
new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(Settings.EMPTY));
User user1 = new User("username", "r1", "r2");
when(firstRealm.supports(token)).thenReturn(true);
when(firstRealm.token(threadContext)).thenReturn(token);
mockAuthenticate(firstRealm, token, user1);
Authentication authentication = authenticateBlocking("_action", message, SystemUser.INSTANCE);
assertThat(authentication, notNullValue());
assertThat(authentication.getUser(), sameInstance(user1));
assertThreadContextContainsAuthentication(authentication, false);
reset(firstRealm);
// checking authentication from the context
InternalMessage message1 = new InternalMessage();
ThreadContext threadContext1 = new ThreadContext(Settings.EMPTY);
when(threadPool.getThreadContext()).thenReturn(threadContext1);
service = new AuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService,
new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(Settings.EMPTY));
threadContext1.putTransient(Authentication.AUTHENTICATION_KEY, threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
threadContext1.putHeader(Authentication.AUTHENTICATION_KEY, threadContext.getHeader(Authentication.AUTHENTICATION_KEY));
Authentication ctxAuth = authenticateBlocking("_action", message1, SystemUser.INSTANCE);
assertThat(ctxAuth, sameInstance(authentication));
verifyZeroInteractions(firstRealm);
reset(firstRealm);
// checking authentication from the user header
threadContext1 = new ThreadContext(Settings.EMPTY);
threadContext1.putHeader(Authentication.AUTHENTICATION_KEY, threadContext.getHeader(Authentication.AUTHENTICATION_KEY));
BytesStreamOutput output = new BytesStreamOutput(); BytesStreamOutput output = new BytesStreamOutput();
threadContext1.writeTo(output); threadContext1.writeTo(output);
@ -409,21 +355,17 @@ public class AuthenticationServiceTests extends ESTestCase {
threadContext1.readHeaders(input); threadContext1.readHeaders(input);
when(threadPool.getThreadContext()).thenReturn(threadContext1); when(threadPool.getThreadContext()).thenReturn(threadContext1);
service = new AuthenticationService(settings, realms, auditTrail, cryptoService, service = new AuthenticationService(Settings.EMPTY, realms, auditTrail,
new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(Settings.EMPTY)); new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(Settings.EMPTY));
Authentication result = authenticateBlocking("_action", new InternalMessage(), SystemUser.INSTANCE); Authentication result = authenticateBlocking("_action", new InternalMessage(), SystemUser.INSTANCE);
assertThat(result, notNullValue()); assertThat(result, notNullValue());
assertThat(result.getUser(), equalTo(user1)); assertThat(result.getUser(), equalTo(user1));
verifyZeroInteractions(firstRealm); verifyZeroInteractions(firstRealm);
verifyZeroInteractions(cryptoService);
} }
public void testAuthenticateTamperedUser() throws Exception { public void testAuthenticateTamperedUser() throws Exception {
InternalMessage message = new InternalMessage(); InternalMessage message = new InternalMessage();
threadContext.putHeader(Authentication.AUTHENTICATION_KEY, "_signed_auth"); threadContext.putHeader(Authentication.AUTHENTICATION_KEY, "_signed_auth");
when(cryptoService.unsignAndVerify("_signed_auth")).thenThrow(
randomFrom(new RuntimeException(), new IllegalArgumentException(), new IllegalStateException()));
try { try {
authenticateBlocking("_action", message, randomBoolean() ? SystemUser.INSTANCE : null); authenticateBlocking("_action", message, randomBoolean() ? SystemUser.INSTANCE : null);
@ -452,13 +394,13 @@ public class AuthenticationServiceTests extends ESTestCase {
assertThat(authentication.getAuthenticatedBy().getName(), is("__attach")); assertThat(authentication.getAuthenticatedBy().getName(), is("__attach"));
assertThat(authentication.getAuthenticatedBy().getType(), is("__attach")); assertThat(authentication.getAuthenticatedBy().getType(), is("__attach"));
assertThat(authentication.getAuthenticatedBy().getNodeName(), is("authc_test")); assertThat(authentication.getAuthenticatedBy().getNodeName(), is("authc_test"));
assertThat(threadContext.getHeader(Authentication.AUTHENTICATION_KEY), equalTo((Object) "_signed_auth")); assertThat(threadContext.getHeader(Authentication.AUTHENTICATION_KEY), equalTo((Object) authentication.encode()));
} }
public void testAttachIfMissingExists() throws Exception { public void testAttachIfMissingExists() throws Exception {
Authentication authentication = new Authentication(new User("username", "r1", "r2"), new RealmRef("test", "test", "foo"), null); Authentication authentication = new Authentication(new User("username", "r1", "r2"), new RealmRef("test", "test", "foo"), null);
threadContext.putTransient(Authentication.AUTHENTICATION_KEY, authentication); threadContext.putTransient(Authentication.AUTHENTICATION_KEY, authentication);
threadContext.putHeader(Authentication.AUTHENTICATION_KEY, "_signed_auth"); threadContext.putHeader(Authentication.AUTHENTICATION_KEY, authentication.encode());
service.attachUserIfMissing(new User("username2", "r3", "r4")); service.attachUserIfMissing(new User("username2", "r3", "r4"));
assertThreadContextContainsAuthentication(authentication); assertThreadContextContainsAuthentication(authentication);
} }
@ -472,7 +414,7 @@ public class AuthenticationServiceTests extends ESTestCase {
} }
Settings settings = builder.build(); Settings settings = builder.build();
final AnonymousUser anonymousUser = new AnonymousUser(settings); final AnonymousUser anonymousUser = new AnonymousUser(settings);
service = new AuthenticationService(settings, realms, auditTrail, cryptoService, new DefaultAuthenticationFailureHandler(), service = new AuthenticationService(settings, realms, auditTrail, new DefaultAuthenticationFailureHandler(),
threadPool, anonymousUser); threadPool, anonymousUser);
RestRequest request = new FakeRestRequest(); RestRequest request = new FakeRestRequest();
@ -490,7 +432,7 @@ public class AuthenticationServiceTests extends ESTestCase {
.putArray(AnonymousUser.ROLES_SETTING.getKey(), "r1", "r2", "r3") .putArray(AnonymousUser.ROLES_SETTING.getKey(), "r1", "r2", "r3")
.build(); .build();
final AnonymousUser anonymousUser = new AnonymousUser(settings); final AnonymousUser anonymousUser = new AnonymousUser(settings);
service = new AuthenticationService(settings, realms, auditTrail, cryptoService, service = new AuthenticationService(settings, realms, auditTrail,
new DefaultAuthenticationFailureHandler(), threadPool, anonymousUser); new DefaultAuthenticationFailureHandler(), threadPool, anonymousUser);
InternalMessage message = new InternalMessage(); InternalMessage message = new InternalMessage();
@ -505,7 +447,7 @@ public class AuthenticationServiceTests extends ESTestCase {
.putArray(AnonymousUser.ROLES_SETTING.getKey(), "r1", "r2", "r3") .putArray(AnonymousUser.ROLES_SETTING.getKey(), "r1", "r2", "r3")
.build(); .build();
final AnonymousUser anonymousUser = new AnonymousUser(settings); final AnonymousUser anonymousUser = new AnonymousUser(settings);
service = new AuthenticationService(settings, realms, auditTrail, cryptoService, service = new AuthenticationService(settings, realms, auditTrail,
new DefaultAuthenticationFailureHandler(), threadPool, anonymousUser); new DefaultAuthenticationFailureHandler(), threadPool, anonymousUser);
InternalMessage message = new InternalMessage(); InternalMessage message = new InternalMessage();
@ -778,19 +720,11 @@ public class AuthenticationServiceTests extends ESTestCase {
} }
void assertThreadContextContainsAuthentication(Authentication authentication) throws IOException { void assertThreadContextContainsAuthentication(Authentication authentication) throws IOException {
assertThreadContextContainsAuthentication(authentication, true);
}
void assertThreadContextContainsAuthentication(Authentication authentication, boolean sign) throws IOException {
Authentication contextAuth = threadContext.getTransient(Authentication.AUTHENTICATION_KEY); Authentication contextAuth = threadContext.getTransient(Authentication.AUTHENTICATION_KEY);
assertThat(contextAuth, notNullValue()); assertThat(contextAuth, notNullValue());
assertThat(contextAuth, is(authentication)); assertThat(contextAuth, is(authentication));
if (sign) {
assertThat(threadContext.getHeader(Authentication.AUTHENTICATION_KEY), equalTo((Object) "_signed_auth"));
} else {
assertThat(threadContext.getHeader(Authentication.AUTHENTICATION_KEY), equalTo((Object) authentication.encode())); assertThat(threadContext.getHeader(Authentication.AUTHENTICATION_KEY), equalTo((Object) authentication.encode()));
} }
}
private void mockAuthenticate(Realm realm, AuthenticationToken token, User user) { private void mockAuthenticate(Realm realm, AuthenticationToken token, User user) {
doAnswer((i) -> { doAnswer((i) -> {

View File

@ -33,7 +33,6 @@ import org.elasticsearch.common.collect.MapBuilder;
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.common.xcontent.json.JsonXContent; import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.env.Environment;
import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
@ -45,7 +44,6 @@ import org.elasticsearch.xpack.security.SecurityTemplateService;
import org.elasticsearch.xpack.security.action.realm.ClearRealmCacheAction; import org.elasticsearch.xpack.security.action.realm.ClearRealmCacheAction;
import org.elasticsearch.xpack.security.action.realm.ClearRealmCacheRequest; import org.elasticsearch.xpack.security.action.realm.ClearRealmCacheRequest;
import org.elasticsearch.xpack.security.authc.support.Hasher; import org.elasticsearch.xpack.security.authc.support.Hasher;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.security.user.ElasticUser; import org.elasticsearch.xpack.security.user.ElasticUser;
import org.elasticsearch.xpack.security.user.KibanaUser; import org.elasticsearch.xpack.security.user.KibanaUser;
import org.elasticsearch.xpack.security.user.LogstashSystemUser; import org.elasticsearch.xpack.security.user.LogstashSystemUser;
@ -82,8 +80,7 @@ public class NativeRealmMigratorTests extends ESTestCase {
ThreadPool threadPool = mock(ThreadPool.class); ThreadPool threadPool = mock(ThreadPool.class);
when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY)); when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY));
internalClient = new InternalClient(Settings.EMPTY, threadPool, mockClient, internalClient = new InternalClient(Settings.EMPTY, threadPool, mockClient);
new CryptoService(Settings.EMPTY, new Environment(Settings.builder().put("path.home", createTempDir()).build())));
doAnswer(invocationOnMock -> { doAnswer(invocationOnMock -> {
SearchRequest request = (SearchRequest) invocationOnMock.getArguments()[1]; SearchRequest request = (SearchRequest) invocationOnMock.getArguments()[1];
ActionListener listener = (ActionListener) invocationOnMock.getArguments()[2]; ActionListener listener = (ActionListener) invocationOnMock.getArguments()[2];

View File

@ -49,7 +49,7 @@ public class NativeUsersStoreTests extends ESTestCase {
@Before @Before
public void setupMocks() { public void setupMocks() {
internalClient = new InternalClient(Settings.EMPTY, null, null, null) { internalClient = new InternalClient(Settings.EMPTY, null, null) {
@Override @Override
protected < protected <

View File

@ -5,8 +5,6 @@
*/ */
package org.elasticsearch.xpack.security.crypto; package org.elasticsearch.xpack.security.crypto;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -21,7 +19,6 @@ import org.junit.Before;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
@ -46,8 +43,6 @@ public class CryptoServiceTests extends ESTestCase {
} }
public void testSigned() throws Exception { public void testSigned() throws Exception {
// randomize whether to use a system key or not
Settings settings = randomBoolean() ? this.settings : Settings.EMPTY;
CryptoService service = new CryptoService(settings, env); CryptoService service = new CryptoService(settings, env);
String text = randomAsciiOfLength(10); String text = randomAsciiOfLength(10);
String signed = service.sign(text); String signed = service.sign(text);
@ -64,11 +59,11 @@ public class CryptoServiceTests extends ESTestCase {
} }
public void testSignAndUnsignNoKeyFile() throws Exception { public void testSignAndUnsignNoKeyFile() throws Exception {
Files.delete(keyFile);
CryptoService service = new CryptoService(Settings.EMPTY, env); CryptoService service = new CryptoService(Settings.EMPTY, env);
final String text = randomAsciiOfLength(10); final String text = randomAsciiOfLength(10);
String signed = service.sign(text); String signed = service.sign(text);
// we always have some sort of key to sign with assertThat(text, equalTo(signed));
assertThat(text, not(equalTo(signed)));
String unsigned = service.unsignAndVerify(signed); String unsigned = service.unsignAndVerify(signed);
assertThat(unsigned, equalTo(text)); assertThat(unsigned, equalTo(text));
} }
@ -182,17 +177,6 @@ public class CryptoServiceTests extends ESTestCase {
assertThat(service.isEncrypted(service.encrypt(randomAsciiOfLength(10).toCharArray())), is(true)); assertThat(service.isEncrypted(service.encrypt(randomAsciiOfLength(10).toCharArray())), is(true));
} }
public void testSigningKeyCanBeRecomputedConsistently() {
final SecretKey systemKey = new SecretKeySpec(CryptoService.generateKey(), CryptoService.KEY_ALGO);
final SecretKey randomKey = CryptoService.generateSecretKey(CryptoService.RANDOM_KEY_SIZE);
int iterations = randomInt(100);
final SecretKey signingKey = CryptoService.createSigningKey(systemKey, randomKey);
for (int i = 0; i < iterations; i++) {
SecretKey regenerated = CryptoService.createSigningKey(systemKey, randomKey);
assertThat(regenerated, equalTo(signingKey));
}
}
public void testSystemKeyFileRequired() throws Exception { public void testSystemKeyFileRequired() throws Exception {
Files.delete(keyFile); Files.delete(keyFile);
Settings customSettings = Settings.builder().put(settings).put("xpack.security.system_key.required", true).build(); Settings customSettings = Settings.builder().put(settings).put("xpack.security.system_key.required", true).build();

View File

@ -10,7 +10,6 @@ import org.elasticsearch.action.support.DestructiveOperations;
import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.ClusterSettings;
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.env.Environment;
import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
@ -29,7 +28,6 @@ import org.elasticsearch.xpack.security.authc.Authentication;
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef; import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
import org.elasticsearch.xpack.security.authc.AuthenticationService; import org.elasticsearch.xpack.security.authc.AuthenticationService;
import org.elasticsearch.xpack.security.authz.AuthorizationService; import org.elasticsearch.xpack.security.authz.AuthorizationService;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.security.user.KibanaUser; import org.elasticsearch.xpack.security.user.KibanaUser;
import org.elasticsearch.xpack.security.user.SystemUser; import org.elasticsearch.xpack.security.user.SystemUser;
import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.user.User;
@ -57,7 +55,6 @@ public class SecurityServerTransportInterceptorTests extends ESTestCase {
private ThreadPool threadPool; private ThreadPool threadPool;
private ThreadContext threadContext; private ThreadContext threadContext;
private XPackLicenseState xPackLicenseState; private XPackLicenseState xPackLicenseState;
private CryptoService cryptoService;
private SecurityContext securityContext; private SecurityContext securityContext;
@Override @Override
@ -67,8 +64,7 @@ public class SecurityServerTransportInterceptorTests extends ESTestCase {
threadPool = mock(ThreadPool.class); threadPool = mock(ThreadPool.class);
threadContext = new ThreadContext(settings); threadContext = new ThreadContext(settings);
when(threadPool.getThreadContext()).thenReturn(threadContext); when(threadPool.getThreadContext()).thenReturn(threadContext);
cryptoService = new CryptoService(settings, new Environment(settings)); securityContext = spy(new SecurityContext(settings, threadPool.getThreadContext()));
securityContext = spy(new SecurityContext(settings, threadPool.getThreadContext(), cryptoService));
xPackLicenseState = mock(XPackLicenseState.class); xPackLicenseState = mock(XPackLicenseState.class);
when(xPackLicenseState.isAuthAllowed()).thenReturn(true); when(xPackLicenseState.isAuthAllowed()).thenReturn(true);
} }
@ -99,7 +95,7 @@ public class SecurityServerTransportInterceptorTests extends ESTestCase {
public void testSendAsync() throws Exception { public void testSendAsync() throws Exception {
final User user = new User("test"); final User user = new User("test");
final Authentication authentication = new Authentication(user, new RealmRef("ldap", "foo", "node1"), null); final Authentication authentication = new Authentication(user, new RealmRef("ldap", "foo", "node1"), null);
authentication.writeToContext(threadContext, cryptoService, AuthenticationService.SIGN_USER_HEADER.get(settings)); authentication.writeToContext(threadContext);
SecurityServerTransportInterceptor interceptor = new SecurityServerTransportInterceptor(settings, threadPool, SecurityServerTransportInterceptor interceptor = new SecurityServerTransportInterceptor(settings, threadPool,
mock(AuthenticationService.class), mock(AuthorizationService.class), xPackLicenseState, mock(SSLService.class), mock(AuthenticationService.class), mock(AuthorizationService.class), xPackLicenseState, mock(SSLService.class),
securityContext, new DestructiveOperations(Settings.EMPTY, new ClusterSettings(Settings.EMPTY, securityContext, new DestructiveOperations(Settings.EMPTY, new ClusterSettings(Settings.EMPTY,
@ -131,7 +127,7 @@ public class SecurityServerTransportInterceptorTests extends ESTestCase {
public void testSendAsyncSwitchToSystem() throws Exception { public void testSendAsyncSwitchToSystem() throws Exception {
final User user = new User("test"); final User user = new User("test");
final Authentication authentication = new Authentication(user, new RealmRef("ldap", "foo", "node1"), null); final Authentication authentication = new Authentication(user, new RealmRef("ldap", "foo", "node1"), null);
authentication.writeToContext(threadContext, cryptoService, AuthenticationService.SIGN_USER_HEADER.get(settings)); authentication.writeToContext(threadContext);
threadContext.putTransient(AuthorizationService.ORIGINATING_ACTION_KEY, "indices:foo"); threadContext.putTransient(AuthorizationService.ORIGINATING_ACTION_KEY, "indices:foo");
SecurityServerTransportInterceptor interceptor = new SecurityServerTransportInterceptor(settings, threadPool, SecurityServerTransportInterceptor interceptor = new SecurityServerTransportInterceptor(settings, threadPool,
@ -189,7 +185,7 @@ public class SecurityServerTransportInterceptorTests extends ESTestCase {
public void testSendWithKibanaUser() throws Exception { public void testSendWithKibanaUser() throws Exception {
final User user = new KibanaUser(true); final User user = new KibanaUser(true);
final Authentication authentication = new Authentication(user, new RealmRef("reserved", "reserved", "node1"), null); final Authentication authentication = new Authentication(user, new RealmRef("reserved", "reserved", "node1"), null);
authentication.writeToContext(threadContext, cryptoService, AuthenticationService.SIGN_USER_HEADER.get(settings)); authentication.writeToContext(threadContext);
threadContext.putTransient(AuthorizationService.ORIGINATING_ACTION_KEY, "indices:foo"); threadContext.putTransient(AuthorizationService.ORIGINATING_ACTION_KEY, "indices:foo");
SecurityServerTransportInterceptor interceptor = new SecurityServerTransportInterceptor(settings, threadPool, SecurityServerTransportInterceptor interceptor = new SecurityServerTransportInterceptor(settings, threadPool,

View File

@ -18,7 +18,6 @@ import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.ClusterSettings;
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.env.Environment;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.transport.TransportChannel; import org.elasticsearch.transport.TransportChannel;
import org.elasticsearch.transport.TransportRequest; import org.elasticsearch.transport.TransportRequest;
@ -30,7 +29,6 @@ import org.elasticsearch.xpack.security.authc.AuthenticationService;
import org.elasticsearch.xpack.security.authz.AuthorizationService; import org.elasticsearch.xpack.security.authz.AuthorizationService;
import org.elasticsearch.xpack.security.authz.permission.Role; import org.elasticsearch.xpack.security.authz.permission.Role;
import org.elasticsearch.xpack.security.authz.store.ReservedRolesStore; import org.elasticsearch.xpack.security.authz.store.ReservedRolesStore;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.security.user.KibanaUser; import org.elasticsearch.xpack.security.user.KibanaUser;
import org.elasticsearch.xpack.security.user.SystemUser; import org.elasticsearch.xpack.security.user.SystemUser;
import org.elasticsearch.xpack.security.user.User; import org.elasticsearch.xpack.security.user.User;
@ -273,15 +271,13 @@ public class ServerTransportFilterTests extends ESTestCase {
Settings settings = Settings.builder().put("path.home", createTempDir()).build(); Settings settings = Settings.builder().put("path.home", createTempDir()).build();
ThreadContext threadContext = new ThreadContext(settings); ThreadContext threadContext = new ThreadContext(settings);
return new ServerTransportFilter.ClientProfile(authcService, authzService, threadContext, false, destructiveOperations, return new ServerTransportFilter.ClientProfile(authcService, authzService, threadContext, false, destructiveOperations,
reservedRealmEnabled, reservedRealmEnabled, new SecurityContext(settings, threadContext));
new SecurityContext(settings, threadContext, new CryptoService(Settings.EMPTY, new Environment(settings))));
} }
private ServerTransportFilter.NodeProfile getNodeFilter(boolean reservedRealmEnabled) throws IOException { private ServerTransportFilter.NodeProfile getNodeFilter(boolean reservedRealmEnabled) throws IOException {
Settings settings = Settings.builder().put("path.home", createTempDir()).build(); Settings settings = Settings.builder().put("path.home", createTempDir()).build();
ThreadContext threadContext = new ThreadContext(settings); ThreadContext threadContext = new ThreadContext(settings);
return new ServerTransportFilter.NodeProfile(authcService, authzService, threadContext, false, destructiveOperations, return new ServerTransportFilter.NodeProfile(authcService, authzService, threadContext, false, destructiveOperations,
reservedRealmEnabled, reservedRealmEnabled, new SecurityContext(settings, threadContext));
new SecurityContext(settings, threadContext, new CryptoService(Settings.EMPTY, new Environment(settings))));
} }
} }

View File

@ -203,7 +203,7 @@ public class IndexActionTests extends ESIntegTestCase {
} }
builder.endObject(); builder.endObject();
Client client = client(); Client client = client();
InternalClient internalClient = new InternalClient(client.settings(), client.threadPool(), client, null); InternalClient internalClient = new InternalClient(client.settings(), client.threadPool(), client);
IndexActionFactory actionParser = new IndexActionFactory(Settings.EMPTY, internalClient); IndexActionFactory actionParser = new IndexActionFactory(Settings.EMPTY, internalClient);
XContentParser parser = createParser(builder); XContentParser parser = createParser(builder);
@ -234,7 +234,7 @@ public class IndexActionTests extends ESIntegTestCase {
} }
builder.endObject(); builder.endObject();
Client client = client(); Client client = client();
InternalClient internalClient = new InternalClient(client.settings(), client.threadPool(), client, null); InternalClient internalClient = new InternalClient(client.settings(), client.threadPool(), client);
IndexActionFactory actionParser = new IndexActionFactory(Settings.EMPTY, internalClient); IndexActionFactory actionParser = new IndexActionFactory(Settings.EMPTY, internalClient);
XContentParser parser = createParser(builder); XContentParser parser = createParser(builder);