package com.linkage.maitain.factory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.log4j.Logger;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
public class SSHProtocol {
private static final Logger LOGGER = Logger.getLogger(SSHProtocol.class);
public static final UserInfo defaultUserInfo = new UserInfo() {
public String getPassphrase() {
return null;
}
public String getPassword() {
return null;
}
public boolean promptPassword(String arg0) {
return false;
}
public boolean promptPassphrase(String arg0) {
return false;
}
public boolean promptYesNo(String arg0) {
return true;
}
public void showMessage(String arg0) {
}
};
JSch jsch = null;
String host;
String user;
int port = 22;
String password;
int timeout = 15 * 1000;
public static final String RETR_STR = "\n";
private Session session = null;
public SSHProtocol(String host, int port, String user, String password) {
jsch = new JSch();
this.host = host;
this.port = port;
this.user = user;
this.password = password;
}
public SSHProtocol(String host, String user, String password) {
jsch = new JSch();
this.host = host;
this.user = user;
this.password = password;
}
public SSHProtocol(String host, int port) {
jsch = new JSch();
this.host = host;
this.port = port;
}
public void setLoginUser(String user, String password) {
this.user = user;
this.password = password;
}
public int execCommand(String command, StringBuffer sb)
throws JSchException {
Channel channel = null; //
String result = null;
int i;
int status = -1;
if (command == null || !isConnected()) {
return -1;
}
try {
channel = session.openChannel("exec"); //
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err, true); //
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[2048];
while (true) {
while (in.available() > 0) {
i = in.read(tmp, 0, 1024);
if (i < 0) {
break;
}
result = new String(tmp, 0, i, "utf-8");
sb.append(result);
}
if (channel.isClosed()) {
status = channel.getExitStatus();
// System.out.println("exit-status: "+status);
break;
}
try {
Thread.sleep(200);
} catch (Exception ee) {
}
}
channel.disconnect();
} catch (JSchException e) {
e.printStackTrace();
throw e;
} catch (IOException ex) {
ex.printStackTrace();
}
return status;
}
public String execShell(String[] commands, String[] resps, boolean fetch)
throws JSchException {
Channel channel = null;
StringBuffer result = new StringBuffer();
String tmp;
int i;
boolean execOk = false;
if (commands == null || resps == null) {
throw new JSchException("Empty commands or responses to ssh.");
} else if (commands.length != resps.length) {
throw new JSchException(
"Commands and responses length not equal to command.");
}
if (!isConnected()) {
throw new JSchException("has not connect to server");
}
try {
channel = session.openChannel("shell");
PipedInputStream pins = new PipedInputStream();
PipedOutputStream pouts = new PipedOutputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
channel.setInputStream(pins);
channel.setOutputStream(out);
pouts.connect(pins);
channel.connect();
try {
Thread.sleep(200);
} catch (Exception ex) {
ex.printStackTrace();
}
for (i = 0; i < commands.length; i++) {
if (!commands[i].endsWith(RETR_STR)) {
commands[i] += RETR_STR;
}
pouts.write(commands[i].getBytes());
LOGGER.debug("--------------- commands: "+commands[i]);
try {
Thread.sleep(2000);
} catch (Exception ex) {
ex.printStackTrace();
}
tmp = out.toString("utf-8");
LOGGER.debug("--------------- resp: "+resps[i]);
LOGGER.debug("--------------- return: "+tmp);
execOk = isGetSuccessReturn(tmp, resps[i]);
if (i == commands.length - 1 && fetch) {//
result.append(tmp);
}
if (execOk && i < commands.length - 1) {//
out.reset();
}
if (!execOk) {
// one command timeout ,then ignore the others
throw new JSchException("command " + commands[i]
+ " execute fails, other commands ignored.");
}
}
channel.disconnect();
return result.toString();
} catch (JSchException e) {
e.printStackTrace();
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new JSchException(e.getMessage());
}
}
public String execShell(String[] commands, String[] resps, boolean fetch,
ShellChannelWrapper shellChannelWrapper) throws JSchException {
StringBuffer result = new StringBuffer();
boolean newShellChannel = null == shellChannelWrapper.getShellChannel();
if (null == commands || null == resps) {
throw new JSchException("Empty commands or responses to ssh.");
} else if (commands.length != resps.length) {
throw new JSchException(
"Commands and responses length not equal to command.");
}
if (!isConnected()) {
throw new JSchException("has not connect to server");
}
try {
if (newShellChannel) {
shellChannelWrapper.createNewShellChannel(session);
}
try {
Thread.sleep(200);
} catch (Exception ex) {
ex.printStackTrace();
}
shellChannelWrapper.getOut().reset();
for (int i = 0; i < commands.length; i++) {
if (!commands[i].endsWith(RETR_STR)) {
commands[i] += RETR_STR;
}
shellChannelWrapper.getPouts().write(commands[i].getBytes());
try {
Thread.sleep(2000);
} catch (Exception ex) {
ex.printStackTrace();
}
String tmp = shellChannelWrapper.getOut().toString("utf-8");
boolean execOk = isGetSuccessReturn(tmp, resps[i]);
if (i == commands.length - 1 && fetch) {//
result.append(tmp);
}
if (execOk && i < commands.length - 1) {//
shellChannelWrapper.getOut().reset();
}
if (!execOk) {
// one command timeout ,then ignore the others
throw new JSchException("command " + commands[i]
+ " execute fails, other commands ignored.");
}
}
return result.toString();
} catch (JSchException e) {
e.printStackTrace();
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new JSchException(e.getMessage());
}
}
public String execShellToPrompt(String command, String osprompt,
ShellChannelWrapper shellChannelWrapper) throws JSchException {
String[] commands = { command };
String[] responses = { osprompt };
String result = execShell(commands, responses, true,
shellChannelWrapper);
int pos1 = result.lastIndexOf(command);
if (pos1 == -1) {
pos1 = 0;
} else {
pos1 = pos1 + command.length();
}
result = getActualReqult(result, osprompt, pos1);
return result;
}
public int execCommand(String host, int port, String user, String password,
String command, StringBuffer sb) throws JSchException {
JSch jsch = new JSch();
String result = null;
int i;
int status = -1;
if (command == null) {
return -1;
}
try {
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setUserInfo(defaultUserInfo);
// session.setTimeout(timeout);
session.connect();
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
LOGGER.debug("................"+command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err, true);
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[2048];
while (true) {
while (in.available() > 0) {
i = in.read(tmp, 0, 1024);
if (i < 0) {
break;
}
result = new String(tmp, 0, i, "utf-8");
sb.append(result);
}
if (channel.isClosed()) {
status = channel.getExitStatus();
// System.out.println("exit-status: "+status);
break;
}
try {
Thread.sleep(200);
} catch (Exception ee) {
}
}
channel.disconnect();
session.disconnect();
} catch (JSchException e) {
e.printStackTrace();
throw e;
} catch (IOException ex) {
ex.printStackTrace();
}
return status;
}
public String parseShellPrompt(String buffer) {
String sp = "";
int len = buffer.length();
if (len < 1) {
return "";
}
int pos_end = len - 1;
int pos_begin = 0;
char ch = buffer.charAt(pos_end);
while (ch == '\r' || ch == '\n') {
pos_end--;
ch = buffer.charAt(pos_end);
}
pos_begin = pos_end;
ch = buffer.charAt(pos_begin);
while (ch != '\r' && ch != '\n') {
pos_begin--;
ch = buffer.charAt(pos_begin);
}
sp = buffer.substring(pos_begin + 1, pos_end);
return sp;
}
public void connect(String user, String password) throws JSchException {
try {
session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setUserInfo(defaultUserInfo);
session.connect(timeout);
try {
Thread.sleep(200);
} catch (Exception ex) {
ex.printStackTrace();
}
} catch (JSchException e) {
e.printStackTrace();
throw e;
}
}
public void connect() throws JSchException {
try {
session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setUserInfo(defaultUserInfo);
session.connect();
try {
Thread.sleep(200);
} catch (Exception ex) {
ex.printStackTrace();
}
} catch (JSchException e) {
e.printStackTrace();
throw e;
}
}
/**
* 锟较匡拷锟结话
*/
public void disconnect() {
if (session != null) {
session.disconnect();
}
}
public boolean isConnected() {
if (session != null && session.isConnected()) {
return true;
} else {
return false;
}
}
private boolean isGetSuccessReturn(String actualReturn, String wantReturn)
throws RuntimeException {
Vector<String> wantsuccess = new Vector<String>();
Vector<String> wantfailuer = new Vector<String>();
int i = 0;
String strtemp = "";
int itemp = -1;
parseWantReturn(wantReturn, wantsuccess, wantfailuer);
Iterator<String> iter = wantfailuer.iterator();
while (iter.hasNext()) {
strtemp = (String) iter.next();
itemp = actualReturn.indexOf(strtemp);
if (-1 != itemp) {
throw new RuntimeException(strtemp);
}
}
iter = wantsuccess.iterator();
while (iter.hasNext()) {
strtemp = (String) iter.next();
itemp = actualReturn.indexOf(strtemp);
if (-1 != itemp) {
return true;
}
}
return false;
}
private void parseWantReturn(String wantReturn, Vector<String> wantSuccess,
Vector<String> wantFailure) {
String allsuccess = "";
String allfailure = "";
String[] strtemp;
int i = 0;
if (null == wantReturn) {
return;
}
// parse by "^^"
StringTokenizer st = null;
/*st = new StringTokenizer(wantReturn, OSPromptType.ERRPROMPTTOKEN);
int len = st.countTokens();
if (len != 2) {
allfailure = "";
allsuccess = wantReturn;
} else {
allsuccess = st.nextToken();
allfailure = st.nextToken();
}
// parse by ",,"
if (allsuccess.length() > 0) {
st = new StringTokenizer(allsuccess, OSPromptType.PROMPTTOKEN);
while (st.hasMoreTokens()) {
wantSuccess.add(st.nextToken());
}
}
if (allfailure.length() > 0) {
st = new StringTokenizer(allfailure, OSPromptType.PROMPTTOKEN);
while (st.hasMoreTokens()) {
wantFailure.add(st.nextToken());
}
}*/
}
public String getActualReqult(String message, String token, int posBegin) {
String actualresult = "";
int pos = 0;
pos = message.indexOf(token, posBegin);
if (pos == -1) {
pos = message.length();
}
actualresult = message.substring(posBegin, pos);
return actualresult;
}
public static class ShellChannelWrapper {
private Channel shellChannel;
private PipedInputStream pins;
private PipedOutputStream pouts;
private ByteArrayOutputStream out;
public void createNewShellChannel(Session jschSession) throws Exception {
shellChannel = jschSession.openChannel("shell");
pins = new PipedInputStream();
pouts = new PipedOutputStream();
out = new ByteArrayOutputStream(2048);
shellChannel.setInputStream(pins);
shellChannel.setOutputStream(out);
pouts.connect(pins);
shellChannel.connect();
}
public Channel getShellChannel() {
return shellChannel;
}
public void setShellChannel(Channel shellChannel) {
this.shellChannel = shellChannel;
}
public PipedInputStream getPins() {
return pins;
}
public void setPins(PipedInputStream pins) {
this.pins = pins;
}
public PipedOutputStream getPouts() {
return pouts;
}
public void setPouts(PipedOutputStream pouts) {
this.pouts = pouts;
}
public ByteArrayOutputStream getOut() {
return out;
}
public void setOut(ByteArrayOutputStream out) {
this.out = out;
}
}
/*
* public static void main(String[] args) throws Exception { SSHProtocol ssh =
* new SSHProtocol("192.168.32.71",22); StringBuffer sb = new
* StringBuffer(); int status = -1; String[] commands = {"passwd
* test080514","test","test"}; String[] response = {"New password,,New UNIX
* password^^Unknown user name", "Retype new password,,Retype new UNIX
* password","#"}; String[] commands2 = {"pwd"}; String[] response2 = {"#"};
* String tmp;
*
* try { ssh.connect("root","linux123"); } catch (Exception e) {}
*
* /*status = ssh.execCommand("useradd test080514", sb);
* System.out.println("useradd status = "+status+" result = "+sb);
* sb.setLength(0); status = ssh.execCommand("useradd test080514", sb);
* System.out.println("useradd(existent user) status = "+status+" result =
* "+sb);
*
* sb.setLength(0); status = ssh.execCommand("usermod -g root test080514",
* sb); System.out.println("usermod status = "+status+" result = "+sb);
* sb.setLength(0); status = ssh.execCommand("usermod -g root test0805140",
* sb); System.out.println("usermod(noexistent user) status = "+status+"
* result = "+sb); sb.setLength(0); status = ssh.execCommand("usermod -g
* root0 test080514", sb); System.out.println("usermod(existent group)
* status = "+status+" result = "+sb);
*/
// System.out.println("passwd result = "+ssh.execShell(commands, response,
// true));
// commands[0] = "passwd test0805140";
// System.out.println("passwd(noexistent user) result =
// "+ssh.execShell(commands, response, true));
/*
* sb.setLength(0); status = ssh.execCommand("cut -d: -s -f1,2
* /etc/shadow|grep -w test080514", sb); System.out.println("grep status =
* "+status+" result = "+sb); sb.setLength(0); status = ssh.execCommand("cut
* -d: -s -f1,2 /etc/shadow|grep -w test0805140", sb);
* System.out.println("grep(noexistent user) status = "+status+" result =
* "+sb);
*
*
* sb.setLength(0); status = ssh.execCommand("userdel test080514", sb);
* System.out.println("userdel status = "+status+" result = "+sb);
* sb.setLength(0); status = ssh.execCommand("userdel test0805140", sb);
* System.out.println("userdel(noexistent user) status = "+status+" result =
* "+sb);
*
* sb.setLength(0); status = ssh.execCommand("cat /etc/passwd", sb);
* System.out.println("cat /etc/passwd status = "+status+" result = "+sb);
*
* sb.setLength(0); status = ssh.execCommand("cat /etc/group", sb);
* System.out.println("cat /etc/group status = "+status+" result = "+sb);
*/
/*
* tmp = ssh.execShell(commands2, response2, true);
* System.out.println("fetch=true,
* pwd=\n"+tmp+"\nshellprompt="+ssh.parseShellPrompt(tmp)); tmp =
* ssh.execShell(commands2, response2, false);
* System.out.println("fetch=false,
* pwd=\n"+tmp+"\nshellprompt="+ssh.parseShellPrompt(tmp));
*
* sb.setLength(0); status = ssh.execCommand("su - jiangh", sb);
* System.out.println("su status = "+status+" result = "+sb);
* sb.setLength(0); status = ssh.execCommand("su - jiangh0", sb);
* System.out.println("su(noexistent user) status = "+status+" result =
* "+sb);
*
* sb.setLength(0); status =
* ssh.execCommand("192.168.32.71",22,"jiangh","jiangh","ls -l",sb);
* System.out.println("ls status = "+status+" result = "+sb);
* sb.setLength(0); status =
* ssh.execCommand("192.168.32.71",22,"jiangh","jiangh","ls0 -l",sb);
* System.out.println("ls(error) status = "+status+" result = "+sb); }
*/
}