Menu

#40 What can cause the ssh connection exit when I create the ssh with jsch

v1.0 (example)
open
nobody
None
2
2021-06-17
2021-06-17
gaowenzhi
No

I am focus on one project about webshell, Jsch is used to create the ssh connection. But when the ssh connection is created , the connection will exit without any error or info occasionally.
below is my code, I am not sure what can cause the issue? anyone can take a look at it?
when keyLogin() is called then method output() is called, in output(), it create one thread
to check the inputstream. when inputStream.read(bytes) != -1, I think the ssh connection exit, but I don't know why the ssh connection exit.

Login method

public class ShellPlatform {

..............

private boolean loginByEkey(String user, String host, int port, Map<String, Integer> ptySizeMap) {
    boolean result = true;
    try {
        String keyPath = SecretKeyUtil.getSecretKeyPath(user);
        File key = new File(keyPath);
        if (key.isFile()) {
            shellUtil.keyLogin(user, host, port, keyPath, ptySizeMap);
            outputStream = shellUtil.getInput();
            inputStream = shellUtil.getOutput();
            output();
        } 
    } catch (Exception e) {
        LOGGER.logException(e);
        this.classifyProcessException(e);
        result = false;
    }
    return result;
}

private boolean output() {
    try {
        Thread thread = new Thread() {
            @Override
            public void run() {
                while (running) {
                    byte[] bytes = new byte[1024];
                    try {
                        int i;
                        while ((i = inputStream.read(bytes)) != -1) {
                            initResult();
                            resultMessage.setData(new String(bytes,0,i));
                            resultMessage.setBdata(Arrays.copyOfRange(bytes,0,i));
                            sendMessage(resultMessage);
                            Thread.sleep(20L);
                        }
                        // break the while, the ssh connection exit
                        initResult();
                        resultMessage.setCode("1012");
                        resultMessage.setData("exit the shell");
                        sendMessage(resultMessage);
                        break;
                    } catch (Exception e) {
                        initResult();
                        resultMessage.setCode("1012");
                        resultMessage.setData("get command result fail");
                        resultMessage.setMsg(e.getMessage());
                        sendMessage(resultMessage);
                    }
                }
            }
        };
        thread.setName("outPutThread");
        thread.start();
    } catch (Exception e) {
        initResult();
        resultMessage.setCode("1012");
        resultMessage.setData("thread start fail");
        resultMessage.setMsg(e.getMessage());
        sendMessage(resultMessage);
        return false;
    }
    return true;
}
}

ShellUtil.java

public class ShellUtil {
private Session session;
private ChannelShell channel;
private InputStream inputStream;
private OutputStream outputStream;
// TODO
private static GLogger logger = ClustertoolLogger.getLogger();

public void login(String user, String host, int port, String pswd, Map<String, Integer> ptySizeMap)
        throws JSchException, IOException {
    JSch jsch = new JSch();
    session = jsch.getSession(user, host, port);
    if (null != pswd) {
        session.setPassword(pswd);
    }
    this.connect(ptySizeMap);
}

public void keyLogin(String user, String host, int port, String keyPath, Map<String, Integer> ptySizeMap)
        throws JSchException, IOException {
    JSch jsch = new JSch();
    jsch.addIdentity(keyPath);

    session = jsch.getSession(user, host, port);
    this.connect(ptySizeMap);
}

private void connect(Map<String, Integer> ptySizeMap) throws JSchException, IOException {
    try {
        session.setConfig("StrictHostKeyChecking", "no");
        session.connect(30000); // making a connection with timeout. 30s
        channel = (ChannelShell) session.openChannel("shell");
        inputStream = channel.getInputStream();
        outputStream = channel.getOutputStream();
        Integer col = ptySizeMap.get("col") == null ? 80 : ptySizeMap.get("col");
        Integer row = ptySizeMap.get("row") == null ? 24 : ptySizeMap.get("row");
        Integer wp = ptySizeMap.get("wp") == null ? 640 : ptySizeMap.get("wp");
        Integer hp = ptySizeMap.get("hp") == null ? 480 : ptySizeMap.get("hp");
        channel.setPtyType("xterm");
        channel.setPtySize(col, row, wp, hp);
        channel.connect(30000); // making a connection with timeout. 30s            
    } catch (JSchException e) {
        //Stringcontains()可能存在JDK版本沖突
        if(null != e.getMessage() && e.getMessage().indexOf("channel is not opened") != -1){
            throw new JSchException("SSH connection timeout");
        }
        throw e;
    }
}

public boolean isLogined() {
    return session.isConnected() && channel.isConnected() && !channel.isClosed();
}

public void logout() throws IOException {
    if (null != inputStream) {
        inputStream.close();
    }
    if (null != outputStream) {
        outputStream.close();
    }
    if (null != channel) {
        channel.disconnect();
    }
    if (null != session) {
        session.disconnect();
    }
}

public OutputStream getInput() throws JSchException, IOException {
    if (isLogined()) {
        if (null == outputStream) {
            outputStream = channel.getOutputStream();
        }
        return outputStream;
    } else {
        throw new JSchException("not have login");
    }
}

public InputStream getOutput() throws JSchException, IOException {
    if (isLogined()) {
        if (null == inputStream) {
            inputStream = channel.getInputStream();
        }
        return inputStream;
    } else {
        throw new JSchException("not have login");
    }
}

public void changePtySize(Map<String, Integer> ptySizeMap) throws JSchException, IOException {
    if (isLogined()) {
        Integer col = ptySizeMap.get("col") == null ? 80 : ptySizeMap.get("col");
        Integer row = ptySizeMap.get("row") == null ? 24 : ptySizeMap.get("row");
        Integer wp = ptySizeMap.get("wp") == null ? 640 : ptySizeMap.get("wp");
        Integer hp = ptySizeMap.get("hp") == null ? 480 : ptySizeMap.get("hp");
        channel.setPtySize(col, row, wp, hp);
    } else {
        throw new JSchException("link exception");
    }
}
}

Discussion


Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.