Search code examples
javasshjsch

Java SSH change password on login


private String user = "root",
            newPassword = "test123";

private int port = 22;

public SSHConnection(String host, String password) {
     try {
        JSch jsch = new JSch();

        Session session = jsch.getSession(user, host, port);
        session.setPassword(password);
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();

        ChannelExec channel = (ChannelExec)session.openChannel("exec");
        OutputStream out = channel.getOutputStream();
        ((ChannelExec)channel).setErrStream(System.err);
        channel.connect();

        out.write(password.getBytes());
        out.flush();
        out.write(newPassword.getBytes());
        out.flush();
        out.write(newPassword.getBytes());
        out.flush();

        channel.disconnect();
        session.disconnect();
    }
    catch(Exception e) {
        e.printStackTrace();
    }
}

I am asked to change my password on the first time I log in on the server. I am trying to do it with JSch, but I'm not sure how can I accomplish this. As far as I understand I can't use any commands as I'm forced to change password before doing anything, so I can't use

 (echo old_password; echo new_password; echo new_password) | passwd username

Solution

  • I solved my issue by calling channel.setPty(true);

    private String user = "root",
                newPassword = "test123";
    
    private int port = 22;
    
    public SSHConnection(String host, String password) {
         try {
            JSch jsch = new JSch();
    
            Session session = jsch.getSession(user, host, port);
            session.setPassword(password);
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
    
            ChannelExec channel = (ChannelExec)session.openChannel("exec");
            OutputStream out = channel.getOutputStream();
    
            ((ChannelExec)channel).setErrStream(System.err);
            channel.setPty(true);
            channel.connect();
    
            out.write((password + "\n").getBytes());
            out.flush();
            Thread.sleep(1000);
    
            out.write((newPassword + "\n").getBytes());
            out.flush();
            Thread.sleep(1000);
    
            out.write((newPassword + "\n").getBytes());
            out.flush();
            Thread.sleep(1000);
    
            channel.disconnect();
            session.disconnect();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
    

    I added sleeps before each input for consistency, normally you would want to wait for output before entering each password, but for my uses this will do.