| /* |
| * 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.EnumSet; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.apache.karaf.features.Feature; |
| import org.apache.sshd.client.SshClient; |
| import org.apache.sshd.client.channel.ClientChannel; |
| import org.apache.sshd.client.channel.ClientChannelEvent; |
| import org.apache.sshd.client.future.ConnectFuture; |
| import org.apache.sshd.client.session.ClientSession; |
| import org.apache.sshd.client.session.ClientSession.ClientSessionEvent; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Assert; |
| 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())); |
| } |
| |
| void addViewer(String vieweruser) throws Exception { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| OutputStream pipe = openSshChannel("karaf", "karaf", out); |
| pipe.write(("jaas:realm-manage --realm=karaf" |
| + ";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(); |
| String sshPort = getSshPort(); |
| ConnectFuture future = client.connect(username, "localhost", Integer.parseInt(sshPort)); |
| future.await(); |
| session = future.getSession(); |
| |
| Set<ClientSessionEvent> ret = EnumSet.of(ClientSessionEvent.WAIT_AUTH); |
| while (ret.contains(ClientSessionEvent.WAIT_AUTH)) { |
| session.addPasswordIdentity(password); |
| session.auth().verify(); |
| ret = session.waitFor(EnumSet.of(ClientSessionEvent.WAIT_AUTH, ClientSessionEvent.CLOSED, ClientSessionEvent.AUTHED), 0); |
| } |
| if (ret.contains(ClientSessionEvent.CLOSED)) { |
| 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(EnumSet.of(ClientChannelEvent.CLOSED), 0); |
| session.close(true); |
| client.stop(); |
| |
| client = null; |
| channel = null; |
| session = null; |
| } |
| } |