blob: f7a44f03d0e14151a0bd987db4457fc0d6ea9277 [file] [log] [blame]
/*
* 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;
}
}