diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java index 9e5c7c3747a..add80930ff9 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java @@ -364,14 +364,6 @@ public class Security extends Plugin implements SystemIndexPlugin, IngestPlugin, return modules; } - // we can't load that at construction time since the license plugin might not have been loaded at that point - // which might not be the case during Plugin class instantiation. Once nodeModules are pulled - // everything should have been loaded - modules.add(b -> { - if (XPackSettings.AUDIT_ENABLED.get(settings)) { - b.bind(AuditTrail.class).to(AuditTrailService.class); // interface used by some actions... - } - }); return modules; } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java index ddf6d49a632..fb84df489ff 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditTrailService.java @@ -19,219 +19,280 @@ import java.net.InetAddress; import java.util.Collections; import java.util.List; -public class AuditTrailService implements AuditTrail { +public class AuditTrailService { + private static final AuditTrail NOOP_AUDIT_TRAIL = new NoopAuditTrail(); + private final CompositeAuditTrail compositeAuditTrail; private final XPackLicenseState licenseState; - private final List auditTrails; - - @Override - public String name() { - return "service"; - } public AuditTrailService(List auditTrails, XPackLicenseState licenseState) { - this.auditTrails = Collections.unmodifiableList(auditTrails); + this.compositeAuditTrail = new CompositeAuditTrail(Collections.unmodifiableList(auditTrails)); this.licenseState = licenseState; } - /** Returns the audit trail implementations that this service delegates to. */ - public List getAuditTrails() { - return auditTrails; + public AuditTrail get() { + if (compositeAuditTrail.isEmpty() == false && licenseState.isAuditingAllowed()) { + return compositeAuditTrail; + } else { + return NOOP_AUDIT_TRAIL; + } } - @Override - public void authenticationSuccess(String requestId, String realm, User user, RestRequest request) { - if (licenseState.isAuditingAllowed()) { + // TODO: this method only exists for access to LoggingAuditTrail in a Node for testing. + // DO NOT USE IT, IT WILL BE REMOVED IN THE FUTURE + public List getAuditTrails() { + return compositeAuditTrail.auditTrails; + } + + private static class NoopAuditTrail implements AuditTrail { + + @Override + public String name() { + return "noop"; + } + + @Override + public void authenticationSuccess(String requestId, String realm, User user, RestRequest request) {} + + @Override + public void authenticationSuccess(String requestId, String realm, User user, String action, TransportMessage message) {} + + @Override + public void anonymousAccessDenied(String requestId, String action, TransportMessage message) {} + + @Override + public void anonymousAccessDenied(String requestId, RestRequest request) {} + + @Override + public void authenticationFailed(String requestId, RestRequest request) {} + + @Override + public void authenticationFailed(String requestId, String action, TransportMessage message) {} + + @Override + public void authenticationFailed(String requestId, AuthenticationToken token, String action, TransportMessage message) {} + + @Override + public void authenticationFailed(String requestId, AuthenticationToken token, RestRequest request) {} + + @Override + public void authenticationFailed(String requestId, String realm, AuthenticationToken token, + String action, TransportMessage message) {} + + @Override + public void authenticationFailed(String requestId, String realm, AuthenticationToken token, RestRequest request) {} + + @Override + public void accessGranted(String requestId, Authentication authentication, String action, TransportMessage message, + AuthorizationInfo authorizationInfo) {} + + @Override + public void accessDenied(String requestId, Authentication authentication, String action, TransportMessage message, + AuthorizationInfo authorizationInfo) {} + + @Override + public void tamperedRequest(String requestId, RestRequest request) {} + + @Override + public void tamperedRequest(String requestId, String action, TransportMessage message) {} + + @Override + public void tamperedRequest(String requestId, User user, String action, TransportMessage request) {} + + @Override + public void connectionGranted(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) {} + + @Override + public void connectionDenied(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) {} + + @Override + public void runAsGranted(String requestId, Authentication authentication, String action, TransportMessage message, + AuthorizationInfo authorizationInfo) {} + + @Override + public void runAsDenied(String requestId, Authentication authentication, String action, TransportMessage message, + AuthorizationInfo authorizationInfo) {} + + @Override + public void runAsDenied(String requestId, Authentication authentication, RestRequest request, + AuthorizationInfo authorizationInfo) {} + + @Override + public void explicitIndexAccessEvent(String requestId, AuditLevel eventType, Authentication authentication, + String action, String indices, String requestName, TransportAddress remoteAddress, + AuthorizationInfo authorizationInfo) {} + } + + private static class CompositeAuditTrail implements AuditTrail { + + private final List auditTrails; + + private CompositeAuditTrail(List auditTrails) { + this.auditTrails = auditTrails; + } + + boolean isEmpty() { + return auditTrails.isEmpty(); + } + + @Override + public String name() { + return "service"; + } + + @Override + public void authenticationSuccess(String requestId, String realm, User user, RestRequest request) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationSuccess(requestId, realm, user, request); } } - } - @Override - public void authenticationSuccess(String requestId, String realm, User user, String action, TransportMessage message) { - if (licenseState.isAuditingAllowed()) { + @Override + public void authenticationSuccess(String requestId, String realm, User user, String action, TransportMessage message) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationSuccess(requestId, realm, user, action, message); } } - } - @Override - public void anonymousAccessDenied(String requestId, String action, TransportMessage message) { - if (licenseState.isAuditingAllowed()) { + @Override + public void anonymousAccessDenied(String requestId, String action, TransportMessage message) { for (AuditTrail auditTrail : auditTrails) { auditTrail.anonymousAccessDenied(requestId, action, message); } } - } - @Override - public void anonymousAccessDenied(String requestId, RestRequest request) { - if (licenseState.isAuditingAllowed()) { + @Override + public void anonymousAccessDenied(String requestId, RestRequest request) { for (AuditTrail auditTrail : auditTrails) { auditTrail.anonymousAccessDenied(requestId, request); } } - } - @Override - public void authenticationFailed(String requestId, RestRequest request) { - if (licenseState.isAuditingAllowed()) { + @Override + public void authenticationFailed(String requestId, RestRequest request) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(requestId, request); } } - } - @Override - public void authenticationFailed(String requestId, String action, TransportMessage message) { - if (licenseState.isAuditingAllowed()) { + @Override + public void authenticationFailed(String requestId, String action, TransportMessage message) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(requestId, action, message); } } - } - @Override - public void authenticationFailed(String requestId, AuthenticationToken token, String action, TransportMessage message) { - if (licenseState.isAuditingAllowed()) { + @Override + public void authenticationFailed(String requestId, AuthenticationToken token, String action, TransportMessage message) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(requestId, token, action, message); } } - } - @Override - public void authenticationFailed(String requestId, String realm, AuthenticationToken token, String action, TransportMessage message) { - if (licenseState.isAuditingAllowed()) { + @Override + public void authenticationFailed(String requestId, String realm, AuthenticationToken token, String action, + TransportMessage message) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(requestId, realm, token, action, message); } } - } - @Override - public void authenticationFailed(String requestId, AuthenticationToken token, RestRequest request) { - if (licenseState.isAuditingAllowed()) { + @Override + public void authenticationFailed(String requestId, AuthenticationToken token, RestRequest request) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(requestId, token, request); } } - } - @Override - public void authenticationFailed(String requestId, String realm, AuthenticationToken token, RestRequest request) { - if (licenseState.isAuditingAllowed()) { + @Override + public void authenticationFailed(String requestId, String realm, AuthenticationToken token, RestRequest request) { for (AuditTrail auditTrail : auditTrails) { auditTrail.authenticationFailed(requestId, realm, token, request); } } - } - @Override - public void accessGranted(String requestId, Authentication authentication, String action, TransportMessage msg, - AuthorizationInfo authorizationInfo) { - if (licenseState.isAuditingAllowed()) { + @Override + public void accessGranted(String requestId, Authentication authentication, String action, TransportMessage msg, + AuthorizationInfo authorizationInfo) { for (AuditTrail auditTrail : auditTrails) { auditTrail.accessGranted(requestId, authentication, action, msg, authorizationInfo); } } - } - @Override - public void accessDenied(String requestId, Authentication authentication, String action, TransportMessage message, - AuthorizationInfo authorizationInfo) { - if (licenseState.isAuditingAllowed()) { + @Override + public void accessDenied(String requestId, Authentication authentication, String action, TransportMessage message, + AuthorizationInfo authorizationInfo) { for (AuditTrail auditTrail : auditTrails) { auditTrail.accessDenied(requestId, authentication, action, message, authorizationInfo); } } - } - @Override - public void tamperedRequest(String requestId, RestRequest request) { - if (licenseState.isAuditingAllowed()) { + @Override + public void tamperedRequest(String requestId, RestRequest request) { for (AuditTrail auditTrail : auditTrails) { auditTrail.tamperedRequest(requestId, request); } } - } - @Override - public void tamperedRequest(String requestId, String action, TransportMessage message) { - if (licenseState.isAuditingAllowed()) { + @Override + public void tamperedRequest(String requestId, String action, TransportMessage message) { for (AuditTrail auditTrail : auditTrails) { auditTrail.tamperedRequest(requestId, action, message); } } - } - @Override - public void tamperedRequest(String requestId, User user, String action, TransportMessage request) { - if (licenseState.isAuditingAllowed()) { + @Override + public void tamperedRequest(String requestId, User user, String action, TransportMessage request) { for (AuditTrail auditTrail : auditTrails) { auditTrail.tamperedRequest(requestId, user, action, request); } } - } - @Override - public void connectionGranted(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) { - if (licenseState.isAuditingAllowed()) { + @Override + public void connectionGranted(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) { for (AuditTrail auditTrail : auditTrails) { auditTrail.connectionGranted(inetAddress, profile, rule); } } - } - @Override - public void connectionDenied(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) { - if (licenseState.isAuditingAllowed()) { + @Override + public void connectionDenied(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) { for (AuditTrail auditTrail : auditTrails) { auditTrail.connectionDenied(inetAddress, profile, rule); } } - } - @Override - public void runAsGranted(String requestId, Authentication authentication, String action, TransportMessage message, - AuthorizationInfo authorizationInfo) { - if (licenseState.isAuditingAllowed()) { + @Override + public void runAsGranted(String requestId, Authentication authentication, String action, TransportMessage message, + AuthorizationInfo authorizationInfo) { for (AuditTrail auditTrail : auditTrails) { auditTrail.runAsGranted(requestId, authentication, action, message, authorizationInfo); } } - } - @Override - public void runAsDenied(String requestId, Authentication authentication, String action, TransportMessage message, - AuthorizationInfo authorizationInfo) { - if (licenseState.isAuditingAllowed()) { + @Override + public void runAsDenied(String requestId, Authentication authentication, String action, TransportMessage message, + AuthorizationInfo authorizationInfo) { for (AuditTrail auditTrail : auditTrails) { auditTrail.runAsDenied(requestId, authentication, action, message, authorizationInfo); } } - } - @Override - public void runAsDenied(String requestId, Authentication authentication, RestRequest request, - AuthorizationInfo authorizationInfo) { - if (licenseState.isAuditingAllowed()) { + @Override + public void runAsDenied(String requestId, Authentication authentication, RestRequest request, + AuthorizationInfo authorizationInfo) { for (AuditTrail auditTrail : auditTrails) { auditTrail.runAsDenied(requestId, authentication, request, authorizationInfo); } } - } - @Override - public void explicitIndexAccessEvent(String requestId, AuditLevel eventType, Authentication authentication, String action, - String indices, String requestName, TransportAddress remoteAddress, - AuthorizationInfo authorizationInfo) { - if (licenseState.isAuditingAllowed()) { + @Override + public void explicitIndexAccessEvent(String requestId, AuditLevel eventType, Authentication authentication, String action, + String indices, String requestName, TransportAddress remoteAddress, + AuthorizationInfo authorizationInfo) { for (AuditTrail auditTrail : auditTrails) { auditTrail.explicitIndexAccessEvent(requestId, eventType, authentication, action, indices, requestName, remoteAddress, - authorizationInfo); + authorizationInfo); } } } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/AuthenticationService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/AuthenticationService.java index 8a9be8b5a9c..fe46d078ee1 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/AuthenticationService.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/AuthenticationService.java @@ -77,7 +77,7 @@ public class AuthenticationService { private static final Logger logger = LogManager.getLogger(AuthenticationService.class); private final Realms realms; - private final AuditTrail auditTrail; + private final AuditTrailService auditTrailService; private final AuthenticationFailureHandler failureHandler; private final ThreadContext threadContext; private final String nodeName; @@ -90,12 +90,12 @@ public class AuthenticationService { private final boolean isAnonymousUserEnabled; private final AuthenticationContextSerializer authenticationSerializer; - public AuthenticationService(Settings settings, Realms realms, AuditTrailService auditTrail, + public AuthenticationService(Settings settings, Realms realms, AuditTrailService auditTrailService, AuthenticationFailureHandler failureHandler, ThreadPool threadPool, AnonymousUser anonymousUser, TokenService tokenService, ApiKeyService apiKeyService) { this.nodeName = Node.NODE_NAME_SETTING.get(settings); this.realms = realms; - this.auditTrail = auditTrail; + this.auditTrailService = auditTrailService; this.failureHandler = failureHandler; this.threadContext = threadPool.getThreadContext(); this.anonymousUser = anonymousUser; @@ -274,16 +274,17 @@ public class AuthenticationService { private AuthenticationResult authenticationResult = null; Authenticator(RestRequest request, boolean fallbackToAnonymous, ActionListener listener) { - this(new AuditableRestRequest(auditTrail, failureHandler, threadContext, request), null, fallbackToAnonymous, listener); + this(new AuditableRestRequest(auditTrailService.get(), failureHandler, threadContext, request), + null, fallbackToAnonymous, listener); } Authenticator(String action, TransportMessage message, boolean fallbackToAnonymous, ActionListener listener) { - this(new AuditableTransportRequest(auditTrail, failureHandler, threadContext, action, message), + this(new AuditableTransportRequest(auditTrailService.get(), failureHandler, threadContext, action, message), null, fallbackToAnonymous, listener); } Authenticator(String action, TransportMessage message, User fallbackUser, ActionListener listener) { - this(new AuditableTransportRequest(auditTrail, failureHandler, threadContext, action, message), + this(new AuditableTransportRequest(auditTrailService.get(), failureHandler, threadContext, action, message), Objects.requireNonNull(fallbackUser, "Fallback user cannot be null"), false, listener); } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java index 40f5e4f711a..67d88efc0bc 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java @@ -63,6 +63,7 @@ import org.elasticsearch.xpack.core.security.user.User; import org.elasticsearch.xpack.core.security.user.XPackSecurityUser; import org.elasticsearch.xpack.core.security.user.XPackUser; import org.elasticsearch.xpack.security.audit.AuditLevel; +import org.elasticsearch.xpack.security.audit.AuditTrail; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.security.audit.AuditUtil; import org.elasticsearch.xpack.security.authc.ApiKeyService; @@ -101,7 +102,7 @@ public class AuthorizationService { private final Settings settings; private final ClusterService clusterService; - private final AuditTrailService auditTrail; + private final AuditTrailService auditTrailService; private final IndicesAndAliasesResolver indicesAndAliasesResolver; private final AuthenticationFailureHandler authcFailureHandler; private final ThreadContext threadContext; @@ -114,12 +115,12 @@ public class AuthorizationService { private final boolean anonymousAuthzExceptionEnabled; public AuthorizationService(Settings settings, CompositeRolesStore rolesStore, ClusterService clusterService, - AuditTrailService auditTrail, AuthenticationFailureHandler authcFailureHandler, + AuditTrailService auditTrailService, AuthenticationFailureHandler authcFailureHandler, ThreadPool threadPool, AnonymousUser anonymousUser, @Nullable AuthorizationEngine authorizationEngine, Set requestInterceptors, XPackLicenseState licenseState, IndexNameExpressionResolver resolver) { this.clusterService = clusterService; - this.auditTrail = auditTrail; + this.auditTrailService = auditTrailService; this.indicesAndAliasesResolver = new IndicesAndAliasesResolver(settings, clusterService, resolver); this.authcFailureHandler = authcFailureHandler; this.threadContext = threadPool.getThreadContext(); @@ -172,7 +173,7 @@ public class AuthorizationService { if (isInternalUser(authentication.getUser()) != false) { auditId = AuditUtil.getOrGenerateRequestId(threadContext); } else { - auditTrail.tamperedRequest(null, authentication.getUser(), action, originalRequest); + auditTrailService.get().tamperedRequest(null, authentication.getUser(), action, originalRequest); final String message = "Attempt to authorize action [" + action + "] for [" + authentication.getUser().principal() + "] without an existing request-id"; assert false : message; @@ -204,6 +205,7 @@ public class AuthorizationService { final TransportRequest request = requestInfo.getRequest(); final String action = requestInfo.getAction(); final boolean isRunAs = authentication.getUser().isRunAs(); + final AuditTrail auditTrail = auditTrailService.get(); if (isRunAs) { ActionListener runAsListener = wrapPreservingContext(ActionListener.wrap(result -> { if (result.isGranted()) { @@ -236,6 +238,7 @@ public class AuthorizationService { final TransportRequest request = requestInfo.getRequest(); final String action = requestInfo.getAction(); final AuthorizationEngine authzEngine = getAuthorizationEngine(authentication); + final AuditTrail auditTrail = auditTrailService.get(); if (ClusterPrivilegeResolver.isClusterAction(action)) { final ActionListener clusterAuthzListener = wrapPreservingContext(new AuthorizationResultListener<>(result -> { @@ -373,6 +376,7 @@ public class AuthorizationService { private void authorizeSystemUser(final Authentication authentication, final String action, final String requestId, final TransportRequest request, final ActionListener listener) { + final AuditTrail auditTrail = auditTrailService.get(); if (SystemUser.isAuthorized(action)) { putTransientIfNonExisting(AuthorizationServiceField.INDICES_PERMISSIONS_KEY, IndicesAccessControl.ALLOW_ALL); putTransientIfNonExisting(AUTHORIZATION_INFO_KEY, SYSTEM_AUTHZ_INFO); @@ -394,6 +398,7 @@ public class AuthorizationService { request = TransportActionProxy.unwrapRequest(originalRequest); final boolean isOriginalRequestProxyRequest = TransportActionProxy.isProxyRequest(originalRequest); final boolean isProxyAction = TransportActionProxy.isProxyAction(action); + final AuditTrail auditTrail = auditTrailService.get(); if (isProxyAction && isOriginalRequestProxyRequest == false) { IllegalStateException cause = new IllegalStateException("originalRequest is not a proxy request: [" + originalRequest + "] but action: [" + action + "] is a proxy action"); @@ -451,6 +456,7 @@ public class AuthorizationService { final Map resolvedIndexNames = new HashMap<>(); // Maps action -> resolved indices set final Map> actionToIndicesMap = new HashMap<>(); + final AuditTrail auditTrail = auditTrailService.get(); authorizedIndicesSupplier.getAsync(ActionListener.wrap(authorizedIndices -> { resolvedIndicesAsyncSupplier.getAsync(ActionListener.wrap(overallResolvedIndices -> { @@ -611,8 +617,8 @@ public class AuthorizationService { public void onResponse(T result) { if (result.isGranted()) { if (result.isAuditable()) { - auditTrail.accessGranted(requestId, requestInfo.getAuthentication(), requestInfo.getAction(), requestInfo.getRequest(), - authzInfo); + auditTrailService.get().accessGranted(requestId, requestInfo.getAuthentication(), + requestInfo.getAction(), requestInfo.getRequest(), authzInfo); } try { responseConsumer.accept(result); @@ -631,8 +637,8 @@ public class AuthorizationService { private void handleFailure(boolean audit, @Nullable Exception e) { if (audit) { - auditTrail.accessDenied(requestId, requestInfo.getAuthentication(), requestInfo.getAction(), requestInfo.getRequest(), - authzInfo); + auditTrailService.get().accessDenied(requestId, requestInfo.getAuthentication(), requestInfo.getAction(), + requestInfo.getRequest(), authzInfo); } failureConsumer.accept(denialException(requestInfo.getAuthentication(), requestInfo.getAction(), e)); } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/SecuritySearchOperationListener.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/SecuritySearchOperationListener.java index d898003a501..4ac73e9c9df 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/SecuritySearchOperationListener.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/SecuritySearchOperationListener.java @@ -99,7 +99,7 @@ public final class SecuritySearchOperationListener implements SearchOperationLis final boolean sameUser = samePrincipal && sameRealmType; if (sameUser == false) { - auditTrailService.accessDenied(requestId, current, action, request, authorizationInfo); + auditTrailService.get().accessDenied(requestId, current, action, request, authorizationInfo); throw new SearchContextMissingException(id); } } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java index cefa42eb0b9..1df0f3ae950 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java @@ -18,6 +18,7 @@ import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.RequestIn import org.elasticsearch.xpack.core.security.authz.AuthorizationServiceField; import org.elasticsearch.xpack.core.security.authz.accesscontrol.IndicesAccessControl; import org.elasticsearch.xpack.core.security.support.Exceptions; +import org.elasticsearch.xpack.security.audit.AuditTrail; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.security.audit.AuditUtil; @@ -48,6 +49,7 @@ public final class IndicesAliasesRequestInterceptor implements RequestIntercepto if (requestInfo.getRequest() instanceof IndicesAliasesRequest) { final IndicesAliasesRequest request = (IndicesAliasesRequest) requestInfo.getRequest(); final XPackLicenseState frozenLicenseState = licenseState.copyCurrentLicenseState(); + final AuditTrail auditTrail = auditTrailService.get(); if (frozenLicenseState.isAuthAllowed()) { if (frozenLicenseState.isDocumentAndFieldLevelSecurityAllowed()) { IndicesAccessControl indicesAccessControl = @@ -89,7 +91,7 @@ public final class IndicesAliasesRequestInterceptor implements RequestIntercepto // do not audit success again listener.onResponse(null); } else { - auditTrailService.accessDenied(AuditUtil.extractRequestId(threadContext), requestInfo.getAuthentication(), + auditTrail.accessDenied(AuditUtil.extractRequestId(threadContext), requestInfo.getAuthentication(), requestInfo.getAction(), request, authorizationInfo); listener.onFailure(Exceptions.authorizationError("Adding an alias is not allowed when the alias " + "has more permissions than any of the indices")); diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java index ba4f7a61faf..a1190482e0b 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java @@ -18,6 +18,7 @@ import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.RequestIn import org.elasticsearch.xpack.core.security.authz.AuthorizationServiceField; import org.elasticsearch.xpack.core.security.authz.accesscontrol.IndicesAccessControl; import org.elasticsearch.xpack.core.security.support.Exceptions; +import org.elasticsearch.xpack.security.audit.AuditTrail; import org.elasticsearch.xpack.security.audit.AuditTrailService; import java.util.Collections; @@ -44,6 +45,7 @@ public final class ResizeRequestInterceptor implements RequestInterceptor { if (requestInfo.getRequest() instanceof ResizeRequest) { final ResizeRequest request = (ResizeRequest) requestInfo.getRequest(); final XPackLicenseState frozenLicenseState = licenseState.copyCurrentLicenseState(); + final AuditTrail auditTrail = auditTrailService.get(); if (frozenLicenseState.isAuthAllowed()) { if (frozenLicenseState.isDocumentAndFieldLevelSecurityAllowed()) { IndicesAccessControl indicesAccessControl = @@ -68,7 +70,7 @@ public final class ResizeRequestInterceptor implements RequestInterceptor { listener.onResponse(null); } else { if (authzResult.isAuditable()) { - auditTrailService.accessDenied(extractRequestId(threadContext), requestInfo.getAuthentication(), + auditTrail.accessDenied(extractRequestId(threadContext), requestInfo.getAuthentication(), requestInfo.getAction(), request, authorizationInfo); } listener.onFailure(Exceptions.authorizationError("Resizing an index is not allowed when the target index " + diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java index c9f60dce95c..68478e6def1 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/transport/filter/IPFilter.java @@ -19,6 +19,7 @@ import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.transport.TransportSettings; +import org.elasticsearch.xpack.security.audit.AuditTrail; import org.elasticsearch.xpack.security.audit.AuditTrailService; import java.net.InetSocketAddress; @@ -98,7 +99,7 @@ public class IPFilter { private static final Logger logger = LogManager.getLogger(IPFilter.class); - private final AuditTrailService auditTrail; + private final AuditTrailService auditTrailService; private final XPackLicenseState licenseState; private final boolean alwaysAllowBoundAddresses; @@ -116,9 +117,9 @@ public class IPFilter { private final Map> profileAllowRules = Collections.synchronizedMap(new HashMap<>()); private final Map> profileDenyRules = Collections.synchronizedMap(new HashMap<>()); - public IPFilter(final Settings settings, AuditTrailService auditTrail, ClusterSettings clusterSettings, + public IPFilter(final Settings settings, AuditTrailService auditTrailService, ClusterSettings clusterSettings, XPackLicenseState licenseState) { - this.auditTrail = auditTrail; + this.auditTrailService = auditTrailService; this.licenseState = licenseState; this.alwaysAllowBoundAddresses = ALLOW_BOUND_ADDRESSES_SETTING.get(settings); httpDenyFilter = HTTP_FILTER_DENY_SETTING.get(settings); @@ -207,6 +208,7 @@ public class IPFilter { return true; } + AuditTrail auditTrail = auditTrailService.get(); for (SecurityIpFilterRule rule : rules.get(profile)) { if (rule.matches(peerAddress)) { boolean isAllowed = rule.ruleType() == IpFilterRuleType.ACCEPT; diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java index fb194ecefc6..f8951f7a43a 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/AuditTrailServiceTests.java @@ -58,7 +58,7 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailed() throws Exception { final String requestId = randomAlphaOfLengthBetween(6, 12); - service.authenticationFailed(requestId, token, "_action", message); + service.get().authenticationFailed(requestId, token, "_action", message); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -71,7 +71,7 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailedNoToken() throws Exception { final String requestId = randomAlphaOfLengthBetween(6, 12); - service.authenticationFailed(requestId, "_action", message); + service.get().authenticationFailed(requestId, "_action", message); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -84,7 +84,7 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailedRestNoToken() throws Exception { final String requestId = randomAlphaOfLengthBetween(6, 12); - service.authenticationFailed(requestId, restRequest); + service.get().authenticationFailed(requestId, restRequest); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -97,7 +97,7 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailedRest() throws Exception { final String requestId = randomAlphaOfLengthBetween(6, 12); - service.authenticationFailed(requestId, token, restRequest); + service.get().authenticationFailed(requestId, token, restRequest); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -110,7 +110,7 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailedRealm() throws Exception { final String requestId = randomAlphaOfLengthBetween(6, 12); - service.authenticationFailed(requestId, "_realm", token, "_action", message); + service.get().authenticationFailed(requestId, "_realm", token, "_action", message); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -123,7 +123,7 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAuthenticationFailedRestRealm() throws Exception { final String requestId = randomAlphaOfLengthBetween(6, 12); - service.authenticationFailed(requestId, "_realm", token, restRequest); + service.get().authenticationFailed(requestId, "_realm", token, restRequest); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -136,7 +136,7 @@ public class AuditTrailServiceTests extends ESTestCase { public void testAnonymousAccess() throws Exception { final String requestId = randomAlphaOfLengthBetween(6, 12); - service.anonymousAccessDenied(requestId, "_action", message); + service.get().anonymousAccessDenied(requestId, "_action", message); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -153,7 +153,7 @@ public class AuditTrailServiceTests extends ESTestCase { AuthorizationInfo authzInfo = () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, new String[] { randomAlphaOfLengthBetween(1, 6) }); final String requestId = randomAlphaOfLengthBetween(6, 12); - service.accessGranted(requestId, authentication, "_action", message, authzInfo); + service.get().accessGranted(requestId, authentication, "_action", message, authzInfo); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -170,7 +170,7 @@ public class AuditTrailServiceTests extends ESTestCase { AuthorizationInfo authzInfo = () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, new String[] { randomAlphaOfLengthBetween(1, 6) }); final String requestId = randomAlphaOfLengthBetween(6, 12); - service.accessDenied(requestId, authentication, "_action", message, authzInfo); + service.get().accessDenied(requestId, authentication, "_action", message, authzInfo); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -184,7 +184,7 @@ public class AuditTrailServiceTests extends ESTestCase { public void testConnectionGranted() throws Exception { InetAddress inetAddress = InetAddress.getLoopbackAddress(); SecurityIpFilterRule rule = randomBoolean() ? SecurityIpFilterRule.ACCEPT_ALL : IPFilter.DEFAULT_PROFILE_ACCEPT_ALL; - service.connectionGranted(inetAddress, "client", rule); + service.get().connectionGranted(inetAddress, "client", rule); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -198,7 +198,7 @@ public class AuditTrailServiceTests extends ESTestCase { public void testConnectionDenied() throws Exception { InetAddress inetAddress = InetAddress.getLoopbackAddress(); SecurityIpFilterRule rule = new SecurityIpFilterRule(false, "_all"); - service.connectionDenied(inetAddress, "client", rule); + service.get().connectionDenied(inetAddress, "client", rule); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -213,7 +213,7 @@ public class AuditTrailServiceTests extends ESTestCase { User user = new User("_username", "r1"); String realm = "_realm"; final String requestId = randomAlphaOfLengthBetween(6, 12); - service.authenticationSuccess(requestId, realm, user, restRequest); + service.get().authenticationSuccess(requestId, realm, user, restRequest); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { @@ -228,7 +228,7 @@ public class AuditTrailServiceTests extends ESTestCase { User user = new User("_username", "r1"); String realm = "_realm"; final String requestId = randomAlphaOfLengthBetween(6, 12); - service.authenticationSuccess(requestId, realm, user, "_action", message); + service.get().authenticationSuccess(requestId, realm, user, "_action", message); verify(licenseState).isAuditingAllowed(); if (isAuditingAllowed) { for (AuditTrail auditTrail : auditTrails) { diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java index bc2151886c2..a1927d08121 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/AuthenticationServiceTests.java @@ -75,6 +75,7 @@ import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames; import org.elasticsearch.xpack.core.security.user.AnonymousUser; import org.elasticsearch.xpack.core.security.user.SystemUser; import org.elasticsearch.xpack.core.security.user.User; +import org.elasticsearch.xpack.security.audit.AuditTrail; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.security.audit.AuditUtil; import org.elasticsearch.xpack.security.authc.AuthenticationService.Authenticator; @@ -147,7 +148,8 @@ public class AuthenticationServiceTests extends ESTestCase { private Realms realms; private Realm firstRealm; private Realm secondRealm; - private AuditTrailService auditTrail; + private AuditTrail auditTrail; + private AuditTrailService auditTrailService; private AuthenticationToken token; private ThreadPool threadPool; private ThreadContext threadContext; @@ -190,6 +192,7 @@ public class AuthenticationServiceTests extends ESTestCase { when(licenseState.isAuthAllowed()).thenReturn(true); when(licenseState.isApiKeyServiceAllowed()).thenReturn(true); when(licenseState.isTokenServiceAllowed()).thenReturn(true); + when(licenseState.isAuditingAllowed()).thenReturn(true); ReservedRealm reservedRealm = mock(ReservedRealm.class); when(reservedRealm.type()).thenReturn("reserved"); when(reservedRealm.name()).thenReturn("reserved_realm"); @@ -197,7 +200,8 @@ public class AuthenticationServiceTests extends ESTestCase { licenseState, threadContext, reservedRealm, Arrays.asList(firstRealm, secondRealm), Collections.singletonList(firstRealm))); - auditTrail = mock(AuditTrailService.class); + auditTrail = mock(AuditTrail.class); + auditTrailService = new AuditTrailService(Collections.singletonList(auditTrail), licenseState); client = mock(Client.class); threadPool = new ThreadPool(settings, new FixedExecutorBuilder(settings, TokenService.THREAD_POOL_NAME, 1, 1000, "xpack.security.authc.token.thread_pool")); @@ -237,7 +241,8 @@ public class AuthenticationServiceTests extends ESTestCase { apiKeyService = new ApiKeyService(settings, Clock.systemUTC(), client, licenseState, securityIndex, clusterService, threadPool); tokenService = new TokenService(settings, Clock.systemUTC(), client, licenseState, securityContext, securityIndex, securityIndex, clusterService); - service = new AuthenticationService(settings, realms, auditTrail, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), + service = new AuthenticationService(settings, realms, auditTrailService, + new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, new AnonymousUser(settings), tokenService, apiKeyService); } @@ -421,7 +426,7 @@ public class AuthenticationServiceTests extends ESTestCase { final Settings settings = Settings.builder() .put(AuthenticationService.SUCCESS_AUTH_CACHE_ENABLED.getKey(), false) .build(); - service = new AuthenticationService(settings, realms, auditTrail, + service = new AuthenticationService(settings, realms, auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, new AnonymousUser(Settings.EMPTY), tokenService, apiKeyService); User user = new User("_username", "r1"); @@ -686,7 +691,7 @@ public class AuthenticationServiceTests extends ESTestCase { ThreadPool threadPool1 = new TestThreadPool("testAutheticateTransportContextAndHeader1"); try { ThreadContext threadContext1 = threadPool1.getThreadContext(); - service = new AuthenticationService(Settings.EMPTY, realms, auditTrail, + service = new AuthenticationService(Settings.EMPTY, realms, auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool1, new AnonymousUser(Settings.EMPTY), tokenService, apiKeyService); @@ -710,7 +715,7 @@ public class AuthenticationServiceTests extends ESTestCase { ThreadContext threadContext2 = threadPool2.getThreadContext(); final String header; try (ThreadContext.StoredContext ignore = threadContext2.stashContext()) { - service = new AuthenticationService(Settings.EMPTY, realms, auditTrail, + service = new AuthenticationService(Settings.EMPTY, realms, auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool2, new AnonymousUser(Settings.EMPTY), tokenService, apiKeyService); threadContext2.putHeader(AuthenticationField.AUTHENTICATION_KEY, authHeaderRef.get()); @@ -724,7 +729,7 @@ public class AuthenticationServiceTests extends ESTestCase { } threadPool2.getThreadContext().putHeader(AuthenticationField.AUTHENTICATION_KEY, header); - service = new AuthenticationService(Settings.EMPTY, realms, auditTrail, + service = new AuthenticationService(Settings.EMPTY, realms, auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool2, new AnonymousUser(Settings.EMPTY), tokenService, apiKeyService); service.authenticate("_action", new InternalMessage(), SystemUser.INSTANCE, ActionListener.wrap(result -> { @@ -763,7 +768,7 @@ public class AuthenticationServiceTests extends ESTestCase { } Settings anonymousEnabledSettings = builder.build(); final AnonymousUser anonymousUser = new AnonymousUser(anonymousEnabledSettings); - service = new AuthenticationService(anonymousEnabledSettings, realms, auditTrail, + service = new AuthenticationService(anonymousEnabledSettings, realms, auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, anonymousUser, tokenService, apiKeyService); try (ThreadContext.StoredContext ignore = threadContext.stashContext()) { @@ -786,7 +791,7 @@ public class AuthenticationServiceTests extends ESTestCase { } Settings anonymousEnabledSettings = builder.build(); final AnonymousUser anonymousUser = new AnonymousUser(anonymousEnabledSettings); - service = new AuthenticationService(anonymousEnabledSettings, realms, auditTrail, + service = new AuthenticationService(anonymousEnabledSettings, realms, auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, anonymousUser, tokenService, apiKeyService); doAnswer(invocationOnMock -> { final GetRequest request = (GetRequest) invocationOnMock.getArguments()[0]; @@ -816,7 +821,8 @@ public class AuthenticationServiceTests extends ESTestCase { } Settings settings = builder.build(); final AnonymousUser anonymousUser = new AnonymousUser(settings); - service = new AuthenticationService(settings, realms, auditTrail, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), + service = new AuthenticationService(settings, realms, auditTrailService, + new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, anonymousUser, tokenService, apiKeyService); RestRequest request = new FakeRestRequest(); @@ -841,7 +847,8 @@ public class AuthenticationServiceTests extends ESTestCase { Settings settings = builder.build(); final AnonymousUser anonymousUser = new AnonymousUser(settings); - service = new AuthenticationService(settings, realms, auditTrail, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), + service = new AuthenticationService(settings, realms, auditTrailService, + new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, anonymousUser, tokenService, apiKeyService); RestRequest request = new FakeRestRequest(); @@ -863,7 +870,8 @@ public class AuthenticationServiceTests extends ESTestCase { .putList(AnonymousUser.ROLES_SETTING.getKey(), "r1", "r2", "r3") .build(); final AnonymousUser anonymousUser = new AnonymousUser(settings); - service = new AuthenticationService(settings, realms, auditTrail, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), + service = new AuthenticationService(settings, realms, auditTrailService, + new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, anonymousUser, tokenService, apiKeyService); InternalMessage message = new InternalMessage(); @@ -879,7 +887,8 @@ public class AuthenticationServiceTests extends ESTestCase { .putList(AnonymousUser.ROLES_SETTING.getKey(), "r1", "r2", "r3") .build(); final AnonymousUser anonymousUser = new AnonymousUser(settings); - service = new AuthenticationService(settings, realms, auditTrail, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), + service = new AuthenticationService(settings, realms, auditTrailService, + new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, anonymousUser, tokenService, apiKeyService); InternalMessage message = new InternalMessage(); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/SecondaryAuthenticatorTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/SecondaryAuthenticatorTests.java index 8dbe311a202..eb471ac584a 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/SecondaryAuthenticatorTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/SecondaryAuthenticatorTests.java @@ -96,7 +96,7 @@ public class SecondaryAuthenticatorTests extends ESTestCase { when(realms.asList()).thenReturn(Collections.singletonList(realm)); when(realms.getUnlicensedRealms()).thenReturn(Collections.emptyList()); - final AuditTrailService auditTrail = mock(AuditTrailService.class); + final AuditTrailService auditTrail = new AuditTrailService(Collections.emptyList(), null); final AuthenticationFailureHandler failureHandler = new DefaultAuthenticationFailureHandler(Collections.emptyMap()); final AnonymousUser anonymous = new AnonymousUser(settings); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java index ba0150c7fd4..02fd0e631d3 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java @@ -130,6 +130,7 @@ import org.elasticsearch.xpack.core.security.user.User; import org.elasticsearch.xpack.core.security.user.XPackSecurityUser; import org.elasticsearch.xpack.core.security.user.XPackUser; import org.elasticsearch.xpack.security.audit.AuditLevel; +import org.elasticsearch.xpack.security.audit.AuditTrail; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.security.audit.AuditUtil; import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore; @@ -180,7 +181,8 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; public class AuthorizationServiceTests extends ESTestCase { - private AuditTrailService auditTrail; + private AuditTrail auditTrail; + private AuditTrailService auditTrailService; private ClusterService clusterService; private AuthorizationService authorizationService; private ThreadContext threadContext; @@ -199,7 +201,10 @@ public class AuthorizationServiceTests extends ESTestCase { final ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); when(clusterService.getClusterSettings()).thenReturn(clusterSettings); when(clusterService.state()).thenReturn(ClusterState.EMPTY_STATE); - auditTrail = mock(AuditTrailService.class); + auditTrail = mock(AuditTrail.class); + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isAuditingAllowed()).thenReturn(true); + auditTrailService = new AuditTrailService(Collections.singletonList(auditTrail), licenseState); threadContext = new ThreadContext(settings); threadPool = mock(ThreadPool.class); when(threadPool.getThreadContext()).thenReturn(threadContext); @@ -240,8 +245,8 @@ public class AuthorizationServiceTests extends ESTestCase { }).when(rolesStore).getRoles(any(User.class), any(Authentication.class), any(ActionListener.class)); roleMap.put(ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName(), ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR); authorizationService = new AuthorizationService(settings, rolesStore, clusterService, - auditTrail, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, new AnonymousUser(settings), null, - Collections.emptySet(), new XPackLicenseState(settings), new IndexNameExpressionResolver()); + auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, new AnonymousUser(settings), + null, Collections.emptySet(), licenseState, new IndexNameExpressionResolver()); } private void authorize(Authentication authentication, String action, TransportRequest request) { @@ -680,7 +685,7 @@ public class AuthorizationServiceTests extends ESTestCase { ClusterState state = mockEmptyMetaData(); Settings settings = Settings.builder().put(AnonymousUser.ROLES_SETTING.getKey(), "a_all").build(); final AnonymousUser anonymousUser = new AnonymousUser(settings); - authorizationService = new AuthorizationService(settings, rolesStore, clusterService, auditTrail, + authorizationService = new AuthorizationService(settings, rolesStore, clusterService, auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, anonymousUser, null, Collections.emptySet(), new XPackLicenseState(settings), new IndexNameExpressionResolver()); @@ -708,7 +713,7 @@ public class AuthorizationServiceTests extends ESTestCase { .put(AuthorizationService.ANONYMOUS_AUTHORIZATION_EXCEPTION_SETTING.getKey(), false) .build(); final Authentication authentication = createAuthentication(new AnonymousUser(settings)); - authorizationService = new AuthorizationService(settings, rolesStore, clusterService, auditTrail, + authorizationService = new AuthorizationService(settings, rolesStore, clusterService, auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, new AnonymousUser(settings), null, Collections.emptySet(), new XPackLicenseState(settings), new IndexNameExpressionResolver()); @@ -1451,8 +1456,8 @@ public class AuthorizationServiceTests extends ESTestCase { XPackLicenseState licenseState = mock(XPackLicenseState.class); when(licenseState.isAuthorizationEngineAllowed()).thenReturn(true); authorizationService = new AuthorizationService(Settings.EMPTY, rolesStore, clusterService, - auditTrail, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, new AnonymousUser(Settings.EMPTY), - engine, Collections.emptySet(), licenseState, new IndexNameExpressionResolver()); + auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, + new AnonymousUser(Settings.EMPTY), engine, Collections.emptySet(), licenseState, new IndexNameExpressionResolver()); Authentication authentication; try (ThreadContext.StoredContext ignore = threadContext.stashContext()) { authentication = createAuthentication(new User("test user", "a_all")); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SecuritySearchOperationListenerTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SecuritySearchOperationListenerTests.java index c766ab211c1..833d787275b 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SecuritySearchOperationListenerTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SecuritySearchOperationListenerTests.java @@ -25,13 +25,13 @@ import org.elasticsearch.xpack.core.security.SecurityContext; import org.elasticsearch.xpack.core.security.authc.Authentication; import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef; import org.elasticsearch.xpack.core.security.authc.AuthenticationField; -import org.elasticsearch.xpack.core.security.user.User; -import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.AuthorizationInfo; +import org.elasticsearch.xpack.core.security.user.User; +import org.elasticsearch.xpack.security.audit.AuditTrail; +import org.elasticsearch.xpack.security.audit.AuditTrailService; import java.util.Collections; -import static org.elasticsearch.mock.orig.Mockito.verifyNoMoreInteractions; import static org.elasticsearch.xpack.security.audit.logfile.LoggingAuditTrail.PRINCIPAL_ROLES_FIELD_NAME; import static org.elasticsearch.xpack.security.authz.AuthorizationService.AUTHORIZATION_INFO_KEY; import static org.elasticsearch.xpack.security.authz.AuthorizationService.ORIGINATING_ACTION_KEY; @@ -41,6 +41,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; @@ -94,9 +95,11 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { testSearchContext.scrollContext().scroll = new Scroll(TimeValue.timeValueSeconds(2L)); XPackLicenseState licenseState = mock(XPackLicenseState.class); when(licenseState.isAuthAllowed()).thenReturn(true); + when(licenseState.isAuditingAllowed()).thenReturn(true); ThreadContext threadContext = new ThreadContext(Settings.EMPTY); final SecurityContext securityContext = new SecurityContext(Settings.EMPTY, threadContext); - AuditTrailService auditTrailService = mock(AuditTrailService.class); + AuditTrail auditTrail = mock(AuditTrail.class); + AuditTrailService auditTrailService = new AuditTrailService(Collections.singletonList(auditTrail), licenseState); SecuritySearchOperationListener listener = new SecuritySearchOperationListener(securityContext, licenseState, auditTrailService); try (StoredContext ignore = threadContext.newStoredContext(false)) { @@ -104,7 +107,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { authentication.writeToContext(threadContext); listener.validateSearchContext(testSearchContext, Empty.INSTANCE); verify(licenseState).isAuthAllowed(); - verifyZeroInteractions(auditTrailService); + verifyZeroInteractions(auditTrail); } try (StoredContext ignore = threadContext.newStoredContext(false)) { @@ -114,7 +117,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { authentication.writeToContext(threadContext); listener.validateSearchContext(testSearchContext, Empty.INSTANCE); verify(licenseState, times(2)).isAuthAllowed(); - verifyZeroInteractions(auditTrailService); + verifyZeroInteractions(auditTrail); } try (StoredContext ignore = threadContext.newStoredContext(false)) { @@ -131,7 +134,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { expectThrows(SearchContextMissingException.class, () -> listener.validateSearchContext(testSearchContext, request)); assertEquals(testSearchContext.id(), expected.contextId()); verify(licenseState, times(3)).isAuthAllowed(); - verify(auditTrailService).accessDenied(eq(null), eq(authentication), eq("action"), eq(request), + verify(auditTrail).accessDenied(eq(null), eq(authentication), eq("action"), eq(request), authzInfoRoles(authentication.getUser().roles())); } @@ -148,7 +151,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { final InternalScrollSearchRequest request = new InternalScrollSearchRequest(); listener.validateSearchContext(testSearchContext, request); verify(licenseState, times(4)).isAuthAllowed(); - verifyNoMoreInteractions(auditTrailService); + verifyNoMoreInteractions(auditTrail); } // the user that authenticated for the run as request @@ -167,7 +170,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { expectThrows(SearchContextMissingException.class, () -> listener.validateSearchContext(testSearchContext, request)); assertEquals(testSearchContext.id(), expected.contextId()); verify(licenseState, times(5)).isAuthAllowed(); - verify(auditTrailService).accessDenied(eq(null), eq(authentication), eq("action"), eq(request), + verify(auditTrail).accessDenied(eq(null), eq(authentication), eq("action"), eq(request), authzInfoRoles(authentication.getUser().roles())); } } @@ -179,10 +182,14 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { SearchContextId contextId = new SearchContextId(UUIDs.randomBase64UUID(), randomLong()); final String action = randomAlphaOfLength(4); TransportRequest request = Empty.INSTANCE; - AuditTrailService auditTrail = mock(AuditTrailService.class); + XPackLicenseState licenseState = mock(XPackLicenseState.class); + when(licenseState.isAuthAllowed()).thenReturn(true); + when(licenseState.isAuditingAllowed()).thenReturn(true); + AuditTrail auditTrail = mock(AuditTrail.class); + AuditTrailService auditTrailService = new AuditTrailService(Collections.singletonList(auditTrail), licenseState); final String auditId = randomAlphaOfLengthBetween(8, 20); - ensureAuthenticatedUserIsSame(original, current, auditTrail, contextId, action, request, auditId, + ensureAuthenticatedUserIsSame(original, current, auditTrailService, contextId, action, request, auditId, () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, original.getUser().roles())); verifyZeroInteractions(auditTrail); @@ -190,7 +197,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { User user = new User(new User("test", "role"), new User("authenticated", "runas")); current = new Authentication(user, new RealmRef("realm", "file", "node"), new RealmRef(randomAlphaOfLengthBetween(1, 16), "file", "node")); - ensureAuthenticatedUserIsSame(original, current, auditTrail, contextId, action, request, auditId, + ensureAuthenticatedUserIsSame(original, current, auditTrailService, contextId, action, request, auditId, () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, original.getUser().roles())); verifyZeroInteractions(auditTrail); @@ -198,7 +205,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { current = new Authentication(user, new RealmRef("realm", "file", "node"), new RealmRef(randomAlphaOfLengthBetween(1, 16), "file", "node")); Authentication runAs = current; - ensureAuthenticatedUserIsSame(runAs, current, auditTrail, contextId, action, request, auditId, + ensureAuthenticatedUserIsSame(runAs, current, auditTrailService, contextId, action, request, auditId, () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, original.getUser().roles())); verifyZeroInteractions(auditTrail); @@ -206,7 +213,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { Authentication differentRealmType = new Authentication(new User("test", "role"), new RealmRef("realm", randomAlphaOfLength(5), "node"), null); SearchContextMissingException e = expectThrows(SearchContextMissingException.class, - () -> ensureAuthenticatedUserIsSame(original, differentRealmType, auditTrail, contextId, action, request, auditId, + () -> ensureAuthenticatedUserIsSame(original, differentRealmType, auditTrailService, contextId, action, request, auditId, () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, original.getUser().roles()))); assertEquals(contextId, e.contextId()); verify(auditTrail).accessDenied(eq(auditId), eq(differentRealmType), eq(action), eq(request), @@ -216,7 +223,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { Authentication differentUser = new Authentication(new User("test2", "role"), new RealmRef("realm", "realm", "node"), null); e = expectThrows(SearchContextMissingException.class, - () -> ensureAuthenticatedUserIsSame(original, differentUser, auditTrail, contextId, action, request, auditId, + () -> ensureAuthenticatedUserIsSame(original, differentUser, auditTrailService, contextId, action, request, auditId, () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, original.getUser().roles()))); assertEquals(contextId, e.contextId()); verify(auditTrail).accessDenied(eq(auditId), eq(differentUser), eq(action), eq(request), @@ -226,7 +233,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { Authentication diffRunAs = new Authentication(new User(new User("test2", "role"), new User("authenticated", "runas")), new RealmRef("realm", "file", "node1"), new RealmRef("realm", "file", "node1")); e = expectThrows(SearchContextMissingException.class, - () -> ensureAuthenticatedUserIsSame(original, diffRunAs, auditTrail, contextId, action, request, auditId, + () -> ensureAuthenticatedUserIsSame(original, diffRunAs, auditTrailService, contextId, action, request, auditId, () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, original.getUser().roles()))); assertEquals(contextId, e.contextId()); verify(auditTrail).accessDenied(eq(auditId), eq(diffRunAs), eq(action), eq(request), authzInfoRoles(original.getUser().roles())); @@ -235,7 +242,7 @@ public class SecuritySearchOperationListenerTests extends ESTestCase { Authentication runAsDiffType = new Authentication(user, new RealmRef("realm", "file", "node"), new RealmRef(randomAlphaOfLengthBetween(1, 16), randomAlphaOfLengthBetween(5, 12), "node")); e = expectThrows(SearchContextMissingException.class, - () -> ensureAuthenticatedUserIsSame(runAs, runAsDiffType, auditTrail, contextId, action, request, auditId, + () -> ensureAuthenticatedUserIsSame(runAs, runAsDiffType, auditTrailService, contextId, action, request, auditId, () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, original.getUser().roles()))); assertEquals(contextId, e.contextId()); verify(auditTrail).accessDenied(eq(auditId), eq(runAsDiffType), eq(action), eq(request), diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java index 255379916b9..5f5db887298 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/filter/IPFilterTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.test.junit.annotations.Network; import org.elasticsearch.transport.Transport; import org.elasticsearch.xpack.core.XPackSettings; import org.elasticsearch.xpack.security.LocalStateSecurity; +import org.elasticsearch.xpack.security.audit.AuditTrail; import org.elasticsearch.xpack.security.audit.AuditTrailService; import org.junit.Before; import org.mockito.ArgumentCaptor; @@ -50,7 +51,8 @@ import static org.mockito.Mockito.when; public class IPFilterTests extends ESTestCase { private IPFilter ipFilter; private XPackLicenseState licenseState; - private AuditTrailService auditTrail; + private AuditTrail auditTrail; + private AuditTrailService auditTrailService; private Transport transport; private HttpServerTransport httpTransport; private ClusterSettings clusterSettings; @@ -59,7 +61,9 @@ public class IPFilterTests extends ESTestCase { public void init() { licenseState = mock(XPackLicenseState.class); when(licenseState.isIpFilteringAllowed()).thenReturn(true); - auditTrail = mock(AuditTrailService.class); + when(licenseState.isAuditingAllowed()).thenReturn(true); + auditTrail = mock(AuditTrail.class); + auditTrailService = new AuditTrailService(Collections.singletonList(auditTrail), licenseState); clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList( IPFilter.HTTP_FILTER_ALLOW_SETTING, IPFilter.HTTP_FILTER_DENY_SETTING, @@ -91,7 +95,7 @@ public class IPFilterTests extends ESTestCase { .put("xpack.security.transport.filter.allow", "127.0.0.1") .put("xpack.security.transport.filter.deny", "10.0.0.0/8") .build(); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("127.0.0.1"); assertAddressIsDenied("10.2.3.4"); @@ -104,7 +108,7 @@ public class IPFilterTests extends ESTestCase { .put("xpack.security.transport.filter.allow", "2001:0db8:1234::/48") .putList("xpack.security.transport.filter.deny", "1234:db8:85a3:0:0:8a2e:370:7334", "4321:db8:1234::/48") .build(); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("2001:0db8:1234:0000:0000:8a2e:0370:7334"); @@ -119,7 +123,7 @@ public class IPFilterTests extends ESTestCase { .put("xpack.security.transport.filter.allow", "127.0.0.1") .put("xpack.security.transport.filter.deny", "*.google.com") .build(); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("127.0.0.1"); @@ -130,7 +134,7 @@ public class IPFilterTests extends ESTestCase { Settings settings = Settings.builder() .put("xpack.security.transport.filter.allow", "_all") .build(); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("127.0.0.1"); assertAddressIsAllowed("173.194.70.100"); @@ -143,7 +147,7 @@ public class IPFilterTests extends ESTestCase { .put("transport.profiles.client.xpack.security.filter.allow", "192.168.0.1") .put("transport.profiles.client.xpack.security.filter.deny", "_all") .build(); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("127.0.0.1"); // when "localhost" is used, ES considers all local addresses see PatternRule#isLocalhost() @@ -159,7 +163,7 @@ public class IPFilterTests extends ESTestCase { .put("transport.profiles.client.xpack.security.filter.allow", "192.168.0.1") .put("transport.profiles.client.xpack.security.filter.deny", "_all") .build(); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); Settings newSettings = Settings.builder().putList("transport.profiles.client.xpack.security.filter.allow", "192.168.0.1", "192.168.0.2") @@ -179,7 +183,7 @@ public class IPFilterTests extends ESTestCase { .put("xpack.security.transport.filter.allow", "10.0.0.1") .put("xpack.security.transport.filter.deny", "10.0.0.0/8") .build(); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("10.0.0.1"); assertAddressIsDenied("10.0.0.2"); @@ -187,7 +191,7 @@ public class IPFilterTests extends ESTestCase { public void testDefaultAllow() throws Exception { Settings settings = Settings.builder().build(); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("10.0.0.1"); assertAddressIsAllowed("10.0.0.2"); @@ -200,7 +204,7 @@ public class IPFilterTests extends ESTestCase { .put("xpack.security.http.filter.allow", "10.0.0.0/8") .put("xpack.security.http.filter.deny", "192.168.0.1") .build(); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundHttpTransportAddress(httpTransport.boundAddress()); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowedForProfile(IPFilter.HTTP_PROFILE_NAME, "10.2.3.4"); @@ -212,7 +216,7 @@ public class IPFilterTests extends ESTestCase { .put("xpack.security.transport.filter.allow", "127.0.0.1") .put("xpack.security.transport.filter.deny", "10.0.0.0/8") .build(); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundHttpTransportAddress(httpTransport.boundAddress()); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); @@ -233,7 +237,7 @@ public class IPFilterTests extends ESTestCase { } else { settings = Settings.builder().put("xpack.security.transport.filter.deny", "_all").build(); } - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); ipFilter.setBoundHttpTransportAddress(httpTransport.boundAddress()); @@ -248,7 +252,7 @@ public class IPFilterTests extends ESTestCase { .put("xpack.security.transport.filter.deny", "_all") .build(); when(licenseState.isIpFilteringAllowed()).thenReturn(false); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); // don't use the assert helper because we don't want the audit trail to be invoked here @@ -259,7 +263,7 @@ public class IPFilterTests extends ESTestCase { // for sanity enable license and check that it is denied when(licenseState.isIpFilteringAllowed()).thenReturn(true); - ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter = new IPFilter(settings, auditTrailService, clusterSettings, licenseState); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsDeniedForProfile("default", "8.8.8.8");