通过ganymed-ssh2-build210.jar这个工具连接ssh,其无法执行passwd,原因在于通过该jar建立的连接,没有伪终端。
发送的ssh连接命令是:ssh username@ip command;
而可以在终端通过ssh -t username@ip command 可以正常执行;
man ssh; 有这样的连接参数;
-t Force pseudo-tty allocation. This can be used to execute arbitrary screen-based pro‐
grams on a remote machine, which can be very useful, e.g. when implementing menu ser‐
vices. Multiple -t options force tty allocation, even if ssh has no local tty.
所以需要在ssh创建连接的时候指定可以使用伪终端;
查看jar中的Connection 及 Session没有对该项的设置;需要考虑使用其他的工具:jsch
查看jsch channelExec api:
可以进行设置 ,进行代码测试:
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
/**
* 远程执行AIX的shell script ssh -t user@ip command
*
*/
public class SSHRemoteAIXExecute extends RemoteExecute {
private static final String CHANGE_LINE = "\r";
private static final String PASSWD_CMD = "passwd";
private Logger logger = LoggerFactory.getLogger(SSHRemoteAIXExecute.class);
private Session session;
private JSch jsch;
public SSHRemoteAIXExecute(String ip, String username, String userPwd, int port) {
this.setIp(ip);
this.setPort(port);
this.setUsername(username);
this.userPwd = userPwd;
}
@Override
public void setIp(String ip) {
super.setIp(ip);
closeConn();
}
@Override
public void setPort(int port) {
super.setPort(port);
closeConn();
}
private void closeConn() {
if (session != null && session.isConnected()) {
session.disconnect();
session = null;
}
}
@Override
public void setUsername(String userName) {
super.setUsername(userName);
closeConn();
}
/**
* 远程登录unix的主机
*
* @return 登录成功返回true,否则返回false
*/
public Boolean login() throws Exception {
jsch = new JSch();
session = jsch.getSession(this.getUsername(), this.getIp(), this.getPort());
session.setPassword(this.userPwd);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
return session.isConnected();
}
/**
* @param cmd
* 即将执行的命令
* @return 命令执行完后返回的结果值
*/
@Override
public String execute(String cmd) throws Exception {
StringBuffer sb = new StringBuffer();
if (login()) {
ChannelExec channel = (ChannelExec) session.openChannel(JSCH_EXEC);
channel.setPty(true);
channel.setCommand(cmd);
channel.connect();
InputStream in = channel.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, Charset.forName(DEFAULTCHART)));
String buf = null;
Thread.sleep(1000);
while ((buf = reader.readLine()) != null) {
sb.append(buf + CHANGE_LINE);
}
reader.close();
channel.disconnect();
closeConn();
}
return sb.toString();
}
public boolean setNewPassword(String newpassword) throws Exception {
if (login()) {
ChannelExec channel = (ChannelExec) session.openChannel(JSCH_EXEC);
channel.setPty(true);
channel.setCommand(PASSWD_CMD);
channel.connect();
OutputStream out = channel.getOutputStream();
InputStream in = channel.getInputStream();
byte[] buffer = new byte[2048];
Thread.sleep(1000);
int length = in.read(buffer);
String rs = "", coldpassword = "", cnewpass = "";
if (length > 0) {
rs = new String(buffer, 0, length);
if (rs.contains("Error")) {
logger.error("ERROR");
return false;
}
if (!rs.contains("password:")) {
Thread.sleep(1000);
length = in.read(buffer);
rs = new String(buffer, 0, length);
}
if (rs.contains("Old")) {
// (current) UNIX password:
coldpassword = userPwd + CHANGE_LINE;
out.write(coldpassword.getBytes());
out.flush();
Thread.sleep(1000);
length = in.read(buffer);
rs = new String(buffer, 0, length);
}
if (length > 0 && !rs.contains("time")) {
// root's New password:
cnewpass = newpassword + CHANGE_LINE;
out.write(cnewpass.getBytes());
out.flush();
Thread.sleep(1000);
length = in.read(buffer);
rs = new String(buffer, 0, length);
}
if (rs.contains("again:")) {
// Enter the new password again:
cnewpass = newpassword + CHANGE_LINE;
out.write(cnewpass.getBytes());
out.flush();
Thread.sleep(1000);
length = in.read(buffer);
rs = new String(buffer, 0, length);
}
if (!rs.contains("Error")) {
this.isSuccessfully = true;
}else{
this.isSuccessfully = false;
this.errorMessage = rs;
}
}
channel.disconnect();
closeConn();
}
return this.isSuccessfully;
}
public static void main(String[] args) {
String ip = "ip";
String userName = "username";
String userPwd = "password";
String newpassword = "newpassword";
int port = 22;
SSHRemoteAIXExecute rlec = new SSHRemoteAIXExecute(ip, userName, userPwd, port);
try {
rlec.setNewPassword(newpassword);
// rlec.execute("who");
System.out.println(rlec.isSuccessfully);
} catch (Exception e) {
e.printStackTrace();
} finally {
rlec.closeConn();
}
}
}
注:在in.read(buffer)时,可能会发生阻塞及获取字符长度不全,需要通过Tread.sleep()进行延迟。