My JSch session doesn't execute command

2.6k views Asked by At

I'm trying to write a Java code that can ssh into a Unix server and reset a user's password. So I tried to implement some of the code found in SO.

Eg.

Using JSch ChannelExec, I followed this link to get the proper command for resetting user's password.

When I tried running this code, seems like it doesn't reset the user's password. So I tried running the command directly from the Unix's shell, and the command work perfectly. I assume that the exec didn't work at all. I changed the exec to run a simple command like mkdir /home/fikrie/testingjsch which then prove my assumption, seeing that directory were not created.

This is my code:

public void executeSetPassword(final String userName, final GuardedString password)  {
    JSch jsch = new JSch();
    String host = configuration.getHost();
    String remoteUser = configuration.getRemoteUser();
    GuardedString passwd = configuration.getPassword();
    String command = "echo " + userName + ":" + password + " | chpasswd";
    Boolean sessionStatus, channelStatus;

    logger.info("userName is " + userName);
    logger.info("password is " + password);
    logger.info("command is " + command);

    final Session session;
    try {
        session = jsch.getSession(remoteUser, host, 22);

        passwd.access(new Accessor(){
            @Override
            public void access(char[] clearChars) {
                session.setPassword(new String(clearChars));
            }});
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();

        sessionStatus = session.isConnected();
        logger.info("sessionStatus is " + sessionStatus);
        ChannelExec channel=(ChannelExec) session.openChannel("exec");
        channel.setCommand(command);

        channel.connect();
        channelStatus = channel.isConnected();

        logger.info("channelStatus is " + channelStatus);
        logger.info("Exit status = " + channel.getExitStatus());

        channel.disconnect();
        session.disconnect();
    }
    catch (Exception e) {
        throw new RuntimeException(e);
    }
}

What am I missing actually? The session and channel seems to be alive but it doesn't execute the command. This is the log for the code:

Method: executeSetPassword(UnixConnector.java:230)  Level: INFO Message: userName is anne
Method: executeSetPassword(UnixConnector.java:231)  Level: INFO Message: password is org.identityconnectors.common.security.GuardedString@e492109
Method: executeSetPassword(UnixConnector.java:232)  Level: INFO Message: command is echo anne:org.identityconnectors.common.security.GuardedString@e492109 | chpasswd
Method: executeSetPassword(UnixConnector.java:249)  Level: INFO Message: sessionStatus is true
Method: executeSetPassword(UnixConnector.java:257)  Level: INFO Message: channelStatus is true
Method: executeSetPassword(UnixConnector.java:258)  Level: INFO Message: Exit status = -1

This is the JSch Log:

INFO: Connecting to 192.168.1.62 port 22
INFO: Connection established
INFO: Remote version string: SSH-2.0-OpenSSH_5.3
INFO: Local version string: SSH-2.0-JSCH-0.1.53
INFO: CheckCiphers: aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
INFO: aes256-ctr is not available.
INFO: aes192-ctr is not available.
INFO: aes256-cbc is not available.
INFO: aes192-cbc is not available.
INFO: CheckKexes: diffie-hellman-group14-sha1,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
INFO: CheckSignatures: ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
INFO: SSH_MSG_KEXINIT sent
INFO: SSH_MSG_KEXINIT received
INFO: kex: server: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
INFO: kex: server: ssh-rsa,ssh-dss
INFO: kex: server: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,[email protected]
INFO: kex: server: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,[email protected]
INFO: kex: server: hmac-md5,hmac-sha1,[email protected],hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96
INFO: kex: server: hmac-md5,hmac-sha1,[email protected],hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96
INFO: kex: server: none,[email protected]
INFO: kex: server: none,[email protected]
INFO: kex: server: 
INFO: kex: server: 
INFO: kex: client: ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
INFO: kex: client: ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
INFO: kex: client: aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc
INFO: kex: client: aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc
INFO: kex: client: hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96
INFO: kex: client: hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96
INFO: kex: client: none
INFO: kex: client: none
INFO: kex: client: 
INFO: kex: client: 
INFO: kex: server->client aes128-ctr hmac-md5 none
INFO: kex: client->server aes128-ctr hmac-md5 none
INFO: SSH_MSG_KEXDH_INIT sent
INFO: expecting SSH_MSG_KEXDH_REPLY
INFO: ssh_rsa_verify: signature true
WARN: Permanently added '192.168.1.62' (RSA) to the list of known hosts.
INFO: SSH_MSG_NEWKEYS sent
INFO: SSH_MSG_NEWKEYS received
INFO: SSH_MSG_SERVICE_REQUEST sent
INFO: SSH_MSG_SERVICE_ACCEPT received
INFO: Authentications that can continue: gssapi-with-mic,publickey,keyboard-interactive,password
INFO: Next authentication method: gssapi-with-mic
INFO: Authentications that can continue: publickey,keyboard-interactive,password
INFO: Next authentication method: publickey
INFO: Authentications that can continue: password
INFO: Next authentication method: password
INFO: Authentication succeeded (password).
INFO: Disconnecting from 192.168.1.62 port 22
INFO: Caught an exception, leaving main loop due to Socket closed
1

There are 1 answers

0
Martin Prikryl On BEST ANSWER

I assume the problem is that you close the connection before the command is even started.

All the examples your pointed to read a command output, until the end (hence until the command finishes). You do not read the output so you fail to wait for the command to finish.

Either consume the command output as the other examples do. Or (if you are not interested in the output) wait until channel.isClosed() is true before exiting.