Updated Branches: refs/heads/master ff2eb3bc9 -> f7356e71e
Reorganize the SSH command security itests a little. Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/f7356e71 Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/f7356e71 Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/f7356e71 Branch: refs/heads/master Commit: f7356e71ed8ce438e1bf16fee91b2bd1b1ac3802 Parents: ff2eb3b Author: David Bosschaert <dav...@apache.org> Authored: Tue Jan 7 16:41:10 2014 +0000 Committer: David Bosschaert <dav...@apache.org> Committed: Tue Jan 7 16:41:10 2014 +0000 ---------------------------------------------------------------------- .../itests/BundleSshCommandSecurityTest.java | 74 +++++ .../itests/ConfigSshCommandSecurityTest.java | 127 ++++++++ .../karaf/itests/SshCommandSecurityTest.java | 305 ------------------- .../apache/karaf/itests/SshCommandTestBase.java | 155 ++++++++++ 4 files changed, 356 insertions(+), 305 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/f7356e71/itests/src/test/java/org/apache/karaf/itests/BundleSshCommandSecurityTest.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/karaf/itests/BundleSshCommandSecurityTest.java b/itests/src/test/java/org/apache/karaf/itests/BundleSshCommandSecurityTest.java new file mode 100644 index 0000000..5a74d92 --- /dev/null +++ b/itests/src/test/java/org/apache/karaf/itests/BundleSshCommandSecurityTest.java @@ -0,0 +1,74 @@ +/* + * Licensed 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.karaf.itests; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.ops4j.pax.exam.junit.PaxExam; +import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; +import org.ops4j.pax.exam.spi.reactors.PerClass; + +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerClass.class) +public class BundleSshCommandSecurityTest extends SshCommandTestBase { + private static int counter = 0; + + @Test + public void testBundleCommandSecurityViaSsh() throws Exception { + String manageruser = "man" + System.nanoTime() + "_" + counter++; + String vieweruser = "view" + System.nanoTime() + "_" + counter++; + + addUsers(manageruser, vieweruser); + + assertCommand(vieweruser, "bundle:refresh 999", Result.NOT_FOUND); + assertCommand(manageruser, "bundle:refresh -f 999", Result.NO_CREDENTIALS); + assertCommand(manageruser, "bundle:refresh 999", Result.OK); + assertCommand("karaf", "bundle:refresh -f 999", Result.OK); + assertCommand("karaf", "bundle:refresh 999", Result.OK); + + assertCommand(vieweruser, "bundle:restart 999", Result.NOT_FOUND); + assertCommand(manageruser, "bundle:restart -f 999", Result.NO_CREDENTIALS); + assertCommand(manageruser, "bundle:restart 999", Result.OK); + assertCommand("karaf", "bundle:restart -f 999", Result.OK); + assertCommand("karaf", "bundle:restart 999", Result.OK); + + assertCommand(vieweruser, "bundle:start 999", Result.NOT_FOUND); + assertCommand(manageruser, "bundle:start -f 999", Result.NO_CREDENTIALS); + assertCommand(manageruser, "bundle:start 999", Result.OK); + assertCommand("karaf", "bundle:start -f 999", Result.OK); + assertCommand("karaf", "bundle:start 999", Result.OK); + + assertCommand(vieweruser, "bundle:stop 999", Result.NOT_FOUND); + assertCommand(manageruser, "bundle:stop -f 999", Result.NO_CREDENTIALS); + assertCommand(manageruser, "bundle:stop 999", Result.OK); + assertCommand("karaf", "bundle:stop -f 999", Result.OK); + assertCommand("karaf", "bundle:stop 999", Result.OK); + + assertCommand(vieweruser, "bundle:uninstall 999", Result.NOT_FOUND); + assertCommand(manageruser, "bundle:uninstall -f 999", Result.NO_CREDENTIALS); + assertCommand(manageruser, "bundle:uninstall 999", Result.OK); + assertCommand("karaf", "bundle:uninstall -f 999", Result.OK); + assertCommand("karaf", "bundle:uninstall 999", Result.OK); + + assertCommand(vieweruser, "bundle:update 999", Result.NOT_FOUND); + assertCommand(manageruser, "bundle:update -f 999", Result.NO_CREDENTIALS); + assertCommand(manageruser, "bundle:update 999", Result.OK); + assertCommand("karaf", "bundle:update -f 999", Result.OK); + assertCommand("karaf", "bundle:update 999", Result.OK); + + assertCommand(vieweruser, "bundle:install xyz", Result.NOT_FOUND); + assertCommand(manageruser, "bundle:install xyz", Result.NOT_FOUND); + assertCommand("karaf", "bundle:install xyz", Result.OK); + } +} http://git-wip-us.apache.org/repos/asf/karaf/blob/f7356e71/itests/src/test/java/org/apache/karaf/itests/ConfigSshCommandSecurityTest.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/karaf/itests/ConfigSshCommandSecurityTest.java b/itests/src/test/java/org/apache/karaf/itests/ConfigSshCommandSecurityTest.java new file mode 100644 index 0000000..81d50a1 --- /dev/null +++ b/itests/src/test/java/org/apache/karaf/itests/ConfigSshCommandSecurityTest.java @@ -0,0 +1,127 @@ +/* + * Licensed 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.karaf.itests; + +import java.io.IOException; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.ops4j.pax.exam.junit.PaxExam; +import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; +import org.ops4j.pax.exam.spi.reactors.PerClass; + +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerClass.class) +public class ConfigSshCommandSecurityTest extends SshCommandTestBase { + private static int counter = 0; + @Test + public void testConfigCommandSecurityViaSsh() throws Exception { + String manageruser = "man" + System.nanoTime() + "_" + counter++; + String vieweruser = "view" + System.nanoTime() + "_" + counter++; + + addUsers(manageruser, vieweruser); + + // A viewer cannot do anything to ConfigAdmin + assertCommand(vieweruser, "config:edit cfg." + vieweruser, Result.NOT_FOUND); + assertCommand(vieweruser, "config:delete cfg." + vieweruser, Result.NOT_FOUND); + + testConfigEdits(manageruser, Result.OK, "cfg." + manageruser, false); + testConfigEdits(manageruser, Result.NO_CREDENTIALS, "jmx.acl.test_" + counter++, false); + testConfigEdits(manageruser, Result.NO_CREDENTIALS, "org.apache.karaf.command.acl.test_" + counter++, false); + testConfigEdits(manageruser, Result.NO_CREDENTIALS, "org.apache.karaf.service.acl.test_" + counter++, false); + testConfigEdits("karaf", Result.OK, "cfg.karaf_" + counter++, true); + testConfigEdits("karaf", Result.OK, "jmx.acl.test_" + counter++, true); + testConfigEdits("karaf", Result.OK, "org.apache.karaf.command.acl.test_" + counter++, true); + testConfigEdits("karaf", Result.OK, "org.apache.karaf.service.acl.test_" + counter++, true); + } + + private void testConfigEdits(String user, Result expectedEditResult, String pid, boolean isAdmin) throws Exception, IOException { + assertCommand(user, "config:edit " + pid + "\n" + + "config:property-set x y\n" + + "config:property-set a b\n" + + "config:property-append x z\n" + + "config:update", expectedEditResult); + if (expectedEditResult != Result.OK) + // If we're expecting failure, don't continue any further... + return; + + String result = assertCommand(user, "config:edit " + pid + "\n" + + "config:property-list\n" + + "config:cancel", Result.OK); + Assert.assertTrue(result.contains("x = yz")); + Assert.assertTrue(result.contains("a = b")); + String result2 = assertCommand(user, "config:edit " + pid + "\n" + + "config:property-delete a\n" + + "config:property-list\n" + + "config:update", Result.OK); + Assert.assertTrue(result2.contains("x = yz")); + Assert.assertFalse(result2.contains("a = b")); + + if (isAdmin) { + assertCommand(user, "config:delete " + pid, Result.OK); + String result3 = assertCommand(user, "config:edit " + pid + "\n" + + "config:property-list", Result.OK); + Assert.assertFalse(result3.contains("x = yz")); + Assert.assertFalse(result3.contains("a = b")); + } else { + assertCommand(user, "config:delete " + pid, Result.NOT_FOUND); + String result3 = assertCommand(user, "config:edit " + pid + "\n" + + "config:property-list", Result.OK); + Assert.assertTrue("The delete command should have had no effect", result3.contains("x = yz")); + Assert.assertFalse(result3.contains("a = b")); + } + } + + @Test + public void testConfigCommandSecurityWithoutEditSessionViaSsh() throws Exception { + String manageruser = "man" + System.nanoTime() + "_" + counter++; + String vieweruser = "view" + System.nanoTime() + "_" + counter++; + + addUsers(manageruser, vieweruser); + + // Test the viewer user. Since the viewer cannot modify anything wrt Config Admin + // the commands should not even be found... + testConfigEditsNoSession(vieweruser, Result.NOT_FOUND, "cfg." + vieweruser); + testConfigEditsNoSession(vieweruser, Result.NOT_FOUND, "jmx.acl.test_" + counter++); + testConfigEditsNoSession(vieweruser, Result.NOT_FOUND, "org.apache.karaf.command.acl.test_" + counter++); + testConfigEditsNoSession(vieweruser, Result.NOT_FOUND, "org.apache.karaf.service.acl.test_" + counter++); + + // Test the manager user. The manager can modify some properties, but not the ones associated with security + // Therefore the config: commands will be found, but in some cases the manager is denied access + testConfigEditsNoSession(manageruser, Result.OK, "cfg." + manageruser); + testConfigEditsNoSession(manageruser, Result.NO_CREDENTIALS, "jmx.acl.test_" + counter++); + testConfigEditsNoSession(manageruser, Result.NO_CREDENTIALS, "org.apache.karaf.command.acl.test_" + counter++); + testConfigEditsNoSession(manageruser, Result.NO_CREDENTIALS, "org.apache.karaf.service.acl.test_" + counter++); + + // The admin user can modify everything. + testConfigEditsNoSession("karaf", Result.OK, "cfg.karaf.test_" + counter++); + testConfigEditsNoSession("karaf", Result.OK, "jmx.acl.test_" + counter++); + testConfigEditsNoSession("karaf", Result.OK, "org.apache.karaf.command.acl.test_" + counter++); + testConfigEditsNoSession("karaf", Result.OK, "org.apache.karaf.service.acl.test_" + counter++); + } + + private void testConfigEditsNoSession(String user, Result expectedResult, String pid) throws Exception, IOException { + assertCommand(user, "config:property-set -p " + pid + " a.b.c d.e.f", expectedResult); + assertCommand(user, "config:property-append -p " + pid + " a.b.c .g.h", expectedResult); + + if (expectedResult == Result.OK) { + Assert.assertTrue(assertCommand(user, "config:property-list -p " + pid, Result.OK).contains("a.b.c = d.e.f.g.h")); + } + assertCommand(user, "config:property-delete -p " + pid + " a.b.c", expectedResult); + if (expectedResult == Result.OK) { + Assert.assertFalse(assertCommand(user, "config:property-list -p " + pid, Result.OK).contains("a.b.c")); + } + } +} http://git-wip-us.apache.org/repos/asf/karaf/blob/f7356e71/itests/src/test/java/org/apache/karaf/itests/SshCommandSecurityTest.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/karaf/itests/SshCommandSecurityTest.java b/itests/src/test/java/org/apache/karaf/itests/SshCommandSecurityTest.java deleted file mode 100644 index 5a0636d..0000000 --- a/itests/src/test/java/org/apache/karaf/itests/SshCommandSecurityTest.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Licensed 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.karaf.itests; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.util.Arrays; -import java.util.HashSet; - -import junit.framework.Assert; - -import org.apache.karaf.features.Feature; -import org.apache.sshd.ClientChannel; -import org.apache.sshd.ClientSession; -import org.apache.sshd.SshClient; -import org.apache.sshd.client.future.ConnectFuture; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.ops4j.pax.exam.junit.PaxExam; -import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; -import org.ops4j.pax.exam.spi.reactors.PerClass; - -@RunWith(PaxExam.class) -@ExamReactorStrategy(PerClass.class) -public class SshCommandSecurityTest extends KarafTestSupport { - private enum Result { OK, NOT_FOUND, NO_CREDENTIALS }; - - private static int counter = 0; - - private HashSet<Feature> featuresBefore; - private SshClient client; - private ClientSession session; - private ClientChannel channel; - - @Before - public void installSshFeature() throws Exception { - featuresBefore = new HashSet<Feature>(Arrays.asList(featureService.listInstalledFeatures())); - installAndAssertFeature("ssh"); - } - - @After - public void uninstallSshFeature() throws Exception { - uninstallNewFeatures(featuresBefore); - } - - @Test - public void testBundleCommandSecurityViaSsh() throws Exception { - String manageruser = "man" + System.nanoTime() + "_" + counter++; - String vieweruser = "view" + System.nanoTime() + "_" + counter++; - - addUsers(manageruser, vieweruser); - - assertCommand(vieweruser, "bundle:refresh 999", Result.NOT_FOUND); - assertCommand(manageruser, "bundle:refresh -f 999", Result.NO_CREDENTIALS); - assertCommand(manageruser, "bundle:refresh 999", Result.OK); - assertCommand("karaf", "bundle:refresh -f 999", Result.OK); - assertCommand("karaf", "bundle:refresh 999", Result.OK); - - assertCommand(vieweruser, "bundle:restart 999", Result.NOT_FOUND); - assertCommand(manageruser, "bundle:restart -f 999", Result.NO_CREDENTIALS); - assertCommand(manageruser, "bundle:restart 999", Result.OK); - assertCommand("karaf", "bundle:restart -f 999", Result.OK); - assertCommand("karaf", "bundle:restart 999", Result.OK); - - assertCommand(vieweruser, "bundle:start 999", Result.NOT_FOUND); - assertCommand(manageruser, "bundle:start -f 999", Result.NO_CREDENTIALS); - assertCommand(manageruser, "bundle:start 999", Result.OK); - assertCommand("karaf", "bundle:start -f 999", Result.OK); - assertCommand("karaf", "bundle:start 999", Result.OK); - - assertCommand(vieweruser, "bundle:stop 999", Result.NOT_FOUND); - assertCommand(manageruser, "bundle:stop -f 999", Result.NO_CREDENTIALS); - assertCommand(manageruser, "bundle:stop 999", Result.OK); - assertCommand("karaf", "bundle:stop -f 999", Result.OK); - assertCommand("karaf", "bundle:stop 999", Result.OK); - - assertCommand(vieweruser, "bundle:uninstall 999", Result.NOT_FOUND); - assertCommand(manageruser, "bundle:uninstall -f 999", Result.NO_CREDENTIALS); - assertCommand(manageruser, "bundle:uninstall 999", Result.OK); - assertCommand("karaf", "bundle:uninstall -f 999", Result.OK); - assertCommand("karaf", "bundle:uninstall 999", Result.OK); - - assertCommand(vieweruser, "bundle:update 999", Result.NOT_FOUND); - assertCommand(manageruser, "bundle:update -f 999", Result.NO_CREDENTIALS); - assertCommand(manageruser, "bundle:update 999", Result.OK); - assertCommand("karaf", "bundle:update -f 999", Result.OK); - assertCommand("karaf", "bundle:update 999", Result.OK); - - assertCommand(vieweruser, "bundle:install xyz", Result.NOT_FOUND); - assertCommand(manageruser, "bundle:install xyz", Result.NOT_FOUND); - assertCommand("karaf", "bundle:install xyz", Result.OK); - } - - @Test - public void testConfigCommandSecurityViaSsh() throws Exception { - String manageruser = "man" + System.nanoTime() + "_" + counter++; - String vieweruser = "view" + System.nanoTime() + "_" + counter++; - - addUsers(manageruser, vieweruser); - - // A viewer cannot do anything to ConfigAdmin - assertCommand(vieweruser, "config:edit cfg." + vieweruser, Result.NOT_FOUND); - assertCommand(vieweruser, "config:delete cfg." + vieweruser, Result.NOT_FOUND); - - testConfigEdits(manageruser, Result.OK, "cfg." + manageruser, false); - testConfigEdits(manageruser, Result.NO_CREDENTIALS, "jmx.acl.test_" + counter++, false); - testConfigEdits(manageruser, Result.NO_CREDENTIALS, "org.apache.karaf.command.acl.test_" + counter++, false); - testConfigEdits(manageruser, Result.NO_CREDENTIALS, "org.apache.karaf.service.acl.test_" + counter++, false); - testConfigEdits("karaf", Result.OK, "cfg.karaf_" + counter++, true); - testConfigEdits("karaf", Result.OK, "jmx.acl.test_" + counter++, true); - testConfigEdits("karaf", Result.OK, "org.apache.karaf.command.acl.test_" + counter++, true); - testConfigEdits("karaf", Result.OK, "org.apache.karaf.service.acl.test_" + counter++, true); - } - - private void testConfigEdits(String user, Result expectedEditResult, String pid, boolean isAdmin) throws Exception, IOException { - assertCommand(user, "config:edit " + pid + "\n" + - "config:property-set x y\n" + - "config:property-set a b\n" + - "config:property-append x z\n" + - "config:update", expectedEditResult); - if (expectedEditResult != Result.OK) - // If we're expecting failure, don't continue any further... - return; - - String result = assertCommand(user, "config:edit " + pid + "\n" + - "config:property-list\n" + - "config:cancel", Result.OK); - Assert.assertTrue(result.contains("x = yz")); - Assert.assertTrue(result.contains("a = b")); - String result2 = assertCommand(user, "config:edit " + pid + "\n" + - "config:property-delete a\n" + - "config:property-list\n" + - "config:update", Result.OK); - Assert.assertTrue(result2.contains("x = yz")); - Assert.assertFalse(result2.contains("a = b")); - - if (isAdmin) { - assertCommand(user, "config:delete " + pid, Result.OK); - String result3 = assertCommand(user, "config:edit " + pid + "\n" + - "config:property-list", Result.OK); - Assert.assertFalse(result3.contains("x = yz")); - Assert.assertFalse(result3.contains("a = b")); - } else { - assertCommand(user, "config:delete " + pid, Result.NOT_FOUND); - String result3 = assertCommand(user, "config:edit " + pid + "\n" + - "config:property-list", Result.OK); - Assert.assertTrue("The delete command should have had no effect", result3.contains("x = yz")); - Assert.assertFalse(result3.contains("a = b")); - } - } - - @Test - public void testConfigCommandSecurityWithoutEditSessionViaSsh() throws Exception { - String manageruser = "man" + System.nanoTime() + "_" + counter++; - String vieweruser = "view" + System.nanoTime() + "_" + counter++; - - addUsers(manageruser, vieweruser); - - // Test the viewer user. Since the viewer cannot modify anything wrt Config Admin - // the commands should not even be found... - testConfigEditsNoSession(vieweruser, Result.NOT_FOUND, "cfg." + vieweruser); - testConfigEditsNoSession(vieweruser, Result.NOT_FOUND, "jmx.acl.test_" + counter++); - testConfigEditsNoSession(vieweruser, Result.NOT_FOUND, "org.apache.karaf.command.acl.test_" + counter++); - testConfigEditsNoSession(vieweruser, Result.NOT_FOUND, "org.apache.karaf.service.acl.test_" + counter++); - - // Test the manager user. The manager can modify some properties, but not the ones associated with security - // Therefore the config: commands will be found, but in some cases the manager is denied access - testConfigEditsNoSession(manageruser, Result.OK, "cfg." + manageruser); - testConfigEditsNoSession(manageruser, Result.NO_CREDENTIALS, "jmx.acl.test_" + counter++); - testConfigEditsNoSession(manageruser, Result.NO_CREDENTIALS, "org.apache.karaf.command.acl.test_" + counter++); - testConfigEditsNoSession(manageruser, Result.NO_CREDENTIALS, "org.apache.karaf.service.acl.test_" + counter++); - - // The admin user can modify everything. - testConfigEditsNoSession("karaf", Result.OK, "cfg.karaf.test_" + counter++); - testConfigEditsNoSession("karaf", Result.OK, "jmx.acl.test_" + counter++); - testConfigEditsNoSession("karaf", Result.OK, "org.apache.karaf.command.acl.test_" + counter++); - testConfigEditsNoSession("karaf", Result.OK, "org.apache.karaf.service.acl.test_" + counter++); - } - - private void testConfigEditsNoSession(String user, Result expectedResult, String pid) throws Exception, IOException { - assertCommand(user, "config:property-set -p " + pid + " a.b.c d.e.f", expectedResult); - assertCommand(user, "config:property-append -p " + pid + " a.b.c .g.h", expectedResult); - - if (expectedResult == Result.OK) { - Assert.assertTrue(assertCommand(user, "config:property-list -p " + pid, Result.OK).contains("a.b.c = d.e.f.g.h")); - } - assertCommand(user, "config:property-delete -p " + pid + " a.b.c", expectedResult); - if (expectedResult == Result.OK) { - Assert.assertFalse(assertCommand(user, "config:property-list -p " + pid, Result.OK).contains("a.b.c")); - } - } - - private String assertCommand(String user, String command, Result result) throws Exception, IOException { - if (!command.endsWith("\n")) - command += "\n"; - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OutputStream pipe = openSshChannel(user, user, out, out); - pipe.write(command.getBytes()); - pipe.flush(); - - closeSshChannel(pipe); - String output = new String(out.toByteArray()); - - switch(result) { - case OK: - Assert.assertFalse("Should not contain 'Insufficient credentials' or 'Command not found': " + output, - output.contains("Insufficient credentials") || output.contains("Command not found")); - break; - case NOT_FOUND: - Assert.assertTrue("Should contain 'Command not found': " + output, - output.contains("Command not found")); - break; - case NO_CREDENTIALS: - Assert.assertTrue("Should contain 'Insufficient credentials': " + output, - output.contains("Insufficient credentials")); - break; - default: - Assert.fail("Unexpected enum value: " + result); - } - return output; - } - - private void addUsers(String manageruser, String vieweruser) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OutputStream pipe = openSshChannel("karaf", "karaf", out); - pipe.write(("jaas:realm-manage --realm=karaf" - + ";jaas:user-add " + manageruser + " " + manageruser - + ";jaas:role-add " + manageruser + " manager" - + ";jaas:role-add " + manageruser + " viewer" - + ";jaas:user-add " + vieweruser + " " + vieweruser - + ";jaas:role-add " + vieweruser + " viewer" - + ";jaas:update;jaas:realm-manage --realm=karaf;jaas:user-list\n").getBytes()); - pipe.flush(); - closeSshChannel(pipe); - System.out.println(new String(out.toByteArray())); - } - - private OutputStream openSshChannel(String username, String password, OutputStream ... outputs) throws Exception { - client = SshClient.setUpDefaultClient(); - client.start(); - ConnectFuture future = client.connect("localhost", 8101).await(); - session = future.getSession(); - - int ret = ClientSession.WAIT_AUTH; - while ((ret & ClientSession.WAIT_AUTH) != 0) { - session.authPassword(username, password); - ret = session.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0); - } - if ((ret & ClientSession.CLOSED) != 0) { - throw new Exception("Could not open SSH channel"); - } - channel = session.createChannel("shell"); - PipedOutputStream pipe = new PipedOutputStream(); - channel.setIn(new PipedInputStream(pipe)); - - OutputStream out; - if (outputs.length >= 1) { - out = outputs[0]; - } else { - out = new ByteArrayOutputStream(); - } - channel.setOut(out); - - OutputStream err; - if (outputs.length >= 2) { - err = outputs[1]; - } else { - err = new ByteArrayOutputStream(); - } - channel.setErr(err); - channel.open(); - - return pipe; - } - - private void closeSshChannel(OutputStream pipe) throws IOException { - pipe.write("logout\n".getBytes()); - pipe.flush(); - - channel.waitFor(ClientChannel.CLOSED, 0); - session.close(true); - client.stop(); - - client = null; - channel = null; - session = null; - } -} http://git-wip-us.apache.org/repos/asf/karaf/blob/f7356e71/itests/src/test/java/org/apache/karaf/itests/SshCommandTestBase.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/karaf/itests/SshCommandTestBase.java b/itests/src/test/java/org/apache/karaf/itests/SshCommandTestBase.java new file mode 100644 index 0000000..ef05b5c --- /dev/null +++ b/itests/src/test/java/org/apache/karaf/itests/SshCommandTestBase.java @@ -0,0 +1,155 @@ +/* + * Licensed 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.karaf.itests; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.Arrays; +import java.util.HashSet; + +import junit.framework.Assert; + +import org.apache.karaf.features.Feature; +import org.apache.sshd.ClientChannel; +import org.apache.sshd.ClientSession; +import org.apache.sshd.SshClient; +import org.apache.sshd.client.future.ConnectFuture; +import org.junit.After; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.ops4j.pax.exam.junit.PaxExam; +import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; +import org.ops4j.pax.exam.spi.reactors.PerClass; + +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerClass.class) +public class SshCommandTestBase extends KarafTestSupport { + enum Result { OK, NOT_FOUND, NO_CREDENTIALS }; + + private SshClient client; + private ClientChannel channel; + private ClientSession session; + private HashSet<Feature> featuresBefore; + + @Before + public void installSshFeature() throws Exception { + featuresBefore = new HashSet<Feature>(Arrays.asList(featureService.listInstalledFeatures())); + installAndAssertFeature("ssh"); + } + + @After + public void uninstallSshFeature() throws Exception { + uninstallNewFeatures(featuresBefore); + } + + void addUsers(String manageruser, String vieweruser) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OutputStream pipe = openSshChannel("karaf", "karaf", out); + pipe.write(("jaas:realm-manage --realm=karaf" + + ";jaas:user-add " + manageruser + " " + manageruser + + ";jaas:role-add " + manageruser + " manager" + + ";jaas:role-add " + manageruser + " viewer" + + ";jaas:user-add " + vieweruser + " " + vieweruser + + ";jaas:role-add " + vieweruser + " viewer" + + ";jaas:update;jaas:realm-manage --realm=karaf;jaas:user-list\n").getBytes()); + pipe.flush(); + closeSshChannel(pipe); + System.out.println(new String(out.toByteArray())); + } + + String assertCommand(String user, String command, Result result) throws Exception, IOException { + if (!command.endsWith("\n")) + command += "\n"; + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OutputStream pipe = openSshChannel(user, user, out, out); + pipe.write(command.getBytes()); + pipe.flush(); + + closeSshChannel(pipe); + String output = new String(out.toByteArray()); + + switch(result) { + case OK: + Assert.assertFalse("Should not contain 'Insufficient credentials' or 'Command not found': " + output, + output.contains("Insufficient credentials") || output.contains("Command not found")); + break; + case NOT_FOUND: + Assert.assertTrue("Should contain 'Command not found': " + output, + output.contains("Command not found")); + break; + case NO_CREDENTIALS: + Assert.assertTrue("Should contain 'Insufficient credentials': " + output, + output.contains("Insufficient credentials")); + break; + default: + Assert.fail("Unexpected enum value: " + result); + } + return output; + } + + private OutputStream openSshChannel(String username, String password, OutputStream ... outputs) throws Exception { + client = SshClient.setUpDefaultClient(); + client.start(); + ConnectFuture future = client.connect("localhost", 8101).await(); + session = future.getSession(); + + int ret = ClientSession.WAIT_AUTH; + while ((ret & ClientSession.WAIT_AUTH) != 0) { + session.authPassword(username, password); + ret = session.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0); + } + if ((ret & ClientSession.CLOSED) != 0) { + throw new Exception("Could not open SSH channel"); + } + channel = session.createChannel("shell"); + PipedOutputStream pipe = new PipedOutputStream(); + channel.setIn(new PipedInputStream(pipe)); + + OutputStream out; + if (outputs.length >= 1) { + out = outputs[0]; + } else { + out = new ByteArrayOutputStream(); + } + channel.setOut(out); + + OutputStream err; + if (outputs.length >= 2) { + err = outputs[1]; + } else { + err = new ByteArrayOutputStream(); + } + channel.setErr(err); + channel.open(); + + return pipe; + } + + private void closeSshChannel(OutputStream pipe) throws IOException { + pipe.write("logout\n".getBytes()); + pipe.flush(); + + channel.waitFor(ClientChannel.CLOSED, 0); + session.close(true); + client.stop(); + + client = null; + channel = null; + session = null; + } +}