从java jsch移除用户交互

时间:2015-06-18 07:03:57

标签: java ssh expect aix jsch

我正在尝试编写一个可以ssh到unix服务器并重置用户密码的Java代码。我使用jsch进行连接和命令执行。我在几台服务器(CentOS,Ubuntu,HP-UX)上测试过,它工作正常。

当我在AIX上测试时,我遇到了这个问题,它提示用户的新密码。我的程序将一直挂起,直到发生超时。然后会出现错误。我确实谷歌如何阻止用户交互here,但遗憾的是,我正在处理的AIX没有chpasswd。在搜索有关错误代码here的更多信息时,我发现了可用于此案例的expect4j库。

我尝试了一些像here这样的例子并将其应用到我的代码中。

这是我的代码:

public void executeSetPassword(final String userName, final GuardedString password)  {
    JSch.setLogger(new JSCHLogger());
    if ((userName != null) && (password != null)) {
        JSch jsch = new JSch();
        String host = configuration.getHost();
        String remoteUser = configuration.getRemoteUser();
        GuardedString passwd = configuration.getPassword();

        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();

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

            password.access(new Accessor() {
              @Override
              public void access(char[] clearChars) {
              channel.setCommand("echo -e " + "\"" + new String(clearChars) + "\\n" + new String(clearChars) + "\"" + " | passwd " + userName + ";pwdadm -c " + userName);
                    }});

            channel.setErrStream(System.err);
            channel.setPty(true);

            final Expect4j expect = new Expect4j(channel.getInputStream(), channel.getOutputStream());
            channel.connect();

            final StringBuilder buffer = new StringBuilder();
            Closure closure = new Closure() {
                        public void run(ExpectState expectState) throws Exception {
                            buffer.append(expectState.getBuffer());//string buffer for appending output of executed command
                        }
            };

            expect.expect("New password");
            password.access(new Accessor() {
                @Override
                public void access(char[] clearChars) {
                    try {
                        expect.send(new String(clearChars));
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }});

            BufferedReader reader;
            try {
                reader = new BufferedReader(new InputStreamReader(channel.getInputStream()));
                String line;
                while ((line = reader.readLine()) != null) {
                    logger.info(line);
                    if( line.contains("New password:") == true) {
                        logger.info("set something here");
                    }
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            if(channel.isClosed()) {
                channel.disconnect();
                session.disconnect();
                expect.close();
                logger.info("Exit status = " + channel.getExitStatus());
            }

        }
        catch ( Exception e) {
            throw new RuntimeException(e);
        }
    }

当我尝试运行它时,同样的事情发生了。这是否意味着我的期望无法正常工作?

这是日志:

INFO: Connecting to 192.168.1.39 port 22
INFO: Connection established
INFO: Remote version string: SSH-1.99-OpenSSH_3.8.1p1
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-sha1,diffie-hellman-group1-sha1
INFO: kex: server: ssh-rsa,ssh-dss
INFO: kex: server: aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,aes128-ctr,aes192-ctr,aes256-ctr
INFO: kex: server: aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,aes128-ctr,aes192-ctr,aes256-ctr
INFO: kex: server: hmac-md5,hmac-sha1,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
INFO: kex: server: hmac-md5,hmac-sha1,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
INFO: kex: server: none,zlib
INFO: kex: server: none,zlib
INFO: kex: server: 
INFO: kex: server: 
INFO: kex: client: 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.39' (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: publickey,keyboard-interactive,password
INFO: Next authentication method: publickey
INFO: Authentications that can continue: keyboard-interactive,password
INFO: Next authentication method: keyboard-interactive
INFO: Authentications that can continue: password
INFO: Next authentication method: password
INFO: Authentication succeeded (password).
Thread Id: 1    Time: 2015-06-18 13:44:07.318   Class: com.mastersam.connectors.unix.UnixConnector  Method: executeSetPassword(UnixConnector.java:421)  Level: INFO Message: 3004-709 Error changing password for "fikrie".

我也试过改变ssh频道而不是exec。这是更改后的代码:

    final ChannelShell channel=(ChannelShell) session.openChannel("shell");

    channel.setPty(true);
    final Expect4j expect = new Expect4j(channel.getInputStream(), channel.getOutputStream());
    channel.connect();
    final StringBuilder buffer = new StringBuilder();
    Closure closure = new Closure() {
              public void run(ExpectState expectState) throws Exception {
                    buffer.append(expectState.getBuffer());
              }
    };

    password.access(new Accessor() {
                @Override
                public void access(char[] clearChars) {
                    try {
                        expect.send(echo -e " + "\"" + new String(clearChars) + "\\n" + new String(clearChars) + "\"" + " | passwd " + userName);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }});

0 个答案:

没有答案