/*
* Copyright 2011 Future Systems
*
* 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.krakenapps.honey.sshd.impl;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
import org.apache.sshd.server.SessionAware;
import org.apache.sshd.server.session.ServerSession;
import org.krakenapps.honey.sshd.HoneyFileSystem;
import org.krakenapps.honey.sshd.HoneySshService;
import org.krakenapps.honey.sshd.HoneySshSession;
import org.krakenapps.termio.TerminalDecoder;
import org.krakenapps.termio.TerminalEventListener;
import org.krakenapps.termio.TerminalInputStream;
import org.krakenapps.termio.TerminalOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HoneySshSessionImpl implements Command, Runnable, HoneySshSession, SessionAware {
private final Logger logger = LoggerFactory.getLogger(HoneySshSessionImpl.class.getName());
private HoneySshService sshd;
private HoneyFileSystem fs;
private Environment env;
private ServerSession session;
private InputStream in;
private OutputStream out;
private OutputStream err;
private TerminalInputStream tin;
private TerminalOutputStream tout;
private ExitCallback callback;
private TerminalDecoder decoder;
private Map<String, String> environmentVariables;
private Thread t;
private CopyOnWriteArraySet<TerminalEventListener> listeners = new CopyOnWriteArraySet<TerminalEventListener>();
public HoneySshSessionImpl(HoneySshService sshd) {
this.sshd = sshd;
this.fs = new HoneyFileSystemImpl(sshd.getRootPath());
this.decoder = new TerminalDecoder(this);
this.environmentVariables = new HashMap<String, String>();
}
@Override
public void setSession(ServerSession session) {
this.session = session;
}
@Override
public void setInputStream(InputStream in) {
this.in = in;
this.tin = new TerminalInputStream();
}
@Override
public void setOutputStream(OutputStream out) {
this.out = out;
this.tout = new TerminalOutputStream(out);
}
@Override
public void setErrorStream(OutputStream err) {
this.err = err;
}
@Override
public void setExitCallback(ExitCallback callback) {
this.callback = callback;
}
@Override
public void start(Environment env) throws IOException {
this.env = env;
t = new Thread(this, "Honey SSH Shell");
t.start();
for (TerminalEventListener listener : listeners)
listener.onConnected(this);
}
@Override
public void destroy() {
t.interrupt();
}
@Override
public void run() {
byte[] b = new byte[512];
try {
while (true) {
int length = in.read(b);
for (int i = 0; i < length; i++)
decoder.feed(b[i]);
}
} catch (Exception e) {
if (e instanceof InterruptedException)
logger.info("kraken honey sshd: interrupted");
else
logger.error("kraken honey sshd: terminating shell", e);
} finally {
}
}
@Override
public String getUsername() {
return env.getEnv().get(Environment.ENV_USER);
}
@Override
public InetSocketAddress getRemoteAddress() {
return (InetSocketAddress) session.getIoSession().getRemoteAddress();
}
@Override
public String getEnvironmentVariable(String key) {
return environmentVariables.get(key);
}
@Override
public void setEnvironmentVariable(String key, String value) {
environmentVariables.put(key, value);
}
@Override
public TerminalInputStream getInputStream() {
return tin;
}
@Override
public void setInputStream(TerminalInputStream in) {
this.in = in;
}
@Override
public TerminalOutputStream getOutputStream() {
return tout;
}
@Override
public void setOutputStream(TerminalOutputStream out) {
this.out = out;
}
@Override
public void close() {
callback.onExit(0);
}
@Override
public Set<TerminalEventListener> getListeners() {
return listeners;
}
@Override
public void addListener(TerminalEventListener listener) {
listeners.add(listener);
}
@Override
public void removeListener(TerminalEventListener listener) {
listeners.remove(listener);
}
@Override
public HoneySshService getHoneySshService() {
return sshd;
}
@Override
public HoneyFileSystem getHoneyFileSystem() {
return fs;
}
}