This is an automated email from the ASF dual-hosted git repository. alexpl pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push: new 4b8c00f IGNITE-12345 Remote listener of IgniteMessaging has to run inside the Ignite Sandbox - Fixes #7666. 4b8c00f is described below commit 4b8c00f3598de5a7d6d026fc438963985717dc70 Author: sbt-garus-dg <garus....@gmail.com> AuthorDate: Thu Apr 30 15:41:01 2020 +0300 IGNITE-12345 Remote listener of IgniteMessaging has to run inside the Ignite Sandbox - Fixes #7666. Signed-off-by: Aleksey Plekhanov <plehanov.a...@gmail.com> --- .../ignite/internal/SecurityAwareBiPredicate.java | 17 ++- .../main/resources/META-INF/classnames.properties | 1 + .../security/sandbox/MessagingSandboxTest.java | 120 +++++++++++++++++++++ .../ignite/testsuites/SecurityTestSuite.java | 3 + 4 files changed, 139 insertions(+), 2 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/SecurityAwareBiPredicate.java b/modules/core/src/main/java/org/apache/ignite/internal/SecurityAwareBiPredicate.java index d5edca7..5d87d59 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/SecurityAwareBiPredicate.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/SecurityAwareBiPredicate.java @@ -17,9 +17,12 @@ package org.apache.ignite.internal; +import java.security.AccessControlException; import java.util.UUID; import org.apache.ignite.internal.processors.security.AbstractSecurityAwareExternalizable; +import org.apache.ignite.internal.processors.security.IgniteSecurity; import org.apache.ignite.internal.processors.security.OperationSecurityContext; +import org.apache.ignite.internal.processors.security.sandbox.IgniteSandbox; import org.apache.ignite.lang.IgniteBiPredicate; import org.apache.ignite.resources.IgniteInstanceResource; @@ -52,8 +55,18 @@ public class SecurityAwareBiPredicate<E1, E2> extends AbstractSecurityAwareExter /** {@inheritDoc} */ @Override public boolean apply(E1 e1, E2 e2) { - try (OperationSecurityContext c = ignite.context().security().withContext(subjectId)) { - return original.apply(e1, e2); + IgniteSecurity security = ignite.context().security(); + + try (OperationSecurityContext c = security.withContext(subjectId)) { + IgniteSandbox sandbox = security.sandbox(); + + return sandbox.enabled() ? sandbox.execute(() -> original.apply(e1, e2)) : original.apply(e1, e2); + } + catch (AccessControlException e) { + ignite.context().log(getClass()).error("The operation can't be executed because the current subject " + + "doesn't have appropriate permission [subjectId=" + subjectId + "].", e); + + throw e; } } } diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties index a4bd1ef..3772c76 100644 --- a/modules/core/src/main/resources/META-INF/classnames.properties +++ b/modules/core/src/main/resources/META-INF/classnames.properties @@ -271,6 +271,7 @@ org.apache.ignite.internal.IgnitionEx$IgniteNamedInstance$4 org.apache.ignite.internal.IgnitionEx$IgniteNamedInstance$5 org.apache.ignite.internal.NodeStoppingException org.apache.ignite.internal.SecurityCredentialsAttrFilterPredicate +org.apache.ignite.internal.SecurityAwareBiPredicate org.apache.ignite.internal.TransactionMetricsMxBeanImpl org.apache.ignite.internal.UnregisteredBinaryTypeException org.apache.ignite.internal.UnregisteredClassException diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/sandbox/MessagingSandboxTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/sandbox/MessagingSandboxTest.java new file mode 100644 index 0000000..4e48295 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/sandbox/MessagingSandboxTest.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.security.sandbox; + +import java.security.AccessControlException; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.function.BiFunction; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteMessaging; +import org.apache.ignite.lang.IgniteBiPredicate; +import org.apache.ignite.testframework.GridTestUtils; +import org.junit.Test; + +import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.ALLOW_ALL; + +/** + * Checks that a remote listener for IgniteMessaging is executed inside the sandbox. + */ +public class MessagingSandboxTest extends AbstractSandboxTest { + /** Node to send messages. */ + private static final String SRV_SENDER = "srv_sender"; + + /** Latch. */ + private static volatile CountDownLatch latch; + + /** Error. */ + private static volatile AccessControlException error; + + + /** {@inheritDoc} */ + @Override protected void prepareCluster() throws Exception { + startGrid(SRV_SENDER, ALLOW_ALL, false); + + super.prepareCluster(); + } + + /** */ + @Test + public void testRemoteListen() { + testMessaging((m, t) -> m.remoteListen(t, listener())); + } + + /** */ + @Test + public void testRemoteListenAsync() { + testMessaging((m, t) -> m.remoteListenAsync(t, listener()).get()); + } + + /** */ + private void testMessaging(BiFunction<IgniteMessaging, String, UUID> func) { + execute(grid(CLNT_ALLOWED_WRITE_PROP), func, false); + execute(grid(CLNT_FORBIDDEN_WRITE_PROP), func, true); + } + + /** */ + private void execute(Ignite node, BiFunction<IgniteMessaging, String, UUID> func, boolean isForbiddenCase) { + final String topic = "test_topic"; + + IgniteMessaging messaging = node.message(node.cluster().forNodeId(grid(SRV).localNode().id())); + + UUID listenerId = func.apply(messaging, topic); + + try { + GridTestUtils.RunnableX r = () -> { + error = null; + + latch = new CountDownLatch(1); + + grid(SRV_SENDER).message().send(topic, "Hello!"); + + latch.await(10, TimeUnit.SECONDS); + + if (error != null) + throw error; + }; + + if (isForbiddenCase) + runForbiddenOperation(r, AccessControlException.class); + else + runOperation(r); + } + finally { + messaging.stopRemoteListen(listenerId); + } + } + + /** */ + private IgniteBiPredicate<UUID, ?> listener() { + return (uuid, o) -> { + try { + controlAction(); + } + catch (AccessControlException e) { + error = e; + } + finally { + latch.countDown(); + } + + return false; + }; + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/SecurityTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/SecurityTestSuite.java index 252dc2a..a0da3ec 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/SecurityTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/SecurityTestSuite.java @@ -50,6 +50,7 @@ import org.apache.ignite.internal.processors.security.sandbox.ComputeSandboxTest import org.apache.ignite.internal.processors.security.sandbox.DataStreamerSandboxTest; import org.apache.ignite.internal.processors.security.sandbox.DoPrivilegedOnRemoteNodeTest; import org.apache.ignite.internal.processors.security.sandbox.IgniteOperationsInsideSandboxTest; +import org.apache.ignite.internal.processors.security.sandbox.MessagingSandboxTest; import org.apache.ignite.internal.processors.security.sandbox.IgnitionComponentProxyTest; import org.apache.ignite.internal.processors.security.sandbox.SecuritySubjectPermissionsTest; import org.apache.ignite.ssl.MultipleSSLContextsTest; @@ -97,6 +98,8 @@ import org.junit.runners.Suite; AccessToClassesInsideInternalPackageTest.class, SecuritySubjectPermissionsTest.class, IgnitionComponentProxyTest.class, + MessagingSandboxTest.class, + IgniteSecurityProcessorTest.class, GridCommandHandlerSslWithSecurityTest.class, MultipleSSLContextsTest.class