SSHThread.java 9.77 KB
package com.sitech.ismp.check.util;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.oro.text.regex.MalformedPatternException;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
import com.sitech.ismp.check.interfaces.InterfacePro;

import expect4j.Closure;
import expect4j.Expect4j;
import expect4j.ExpectState;
import expect4j.matches.EofMatch;
import expect4j.matches.Match;
import expect4j.matches.RegExpMatch;
import expect4j.matches.TimeoutMatch;

public class SSHThread implements RemoteController {

	private String host_ip;
	private int port;
	private String login_id;
	private String password;
	private static final long defaultTimeOut = 1000;
	String RPCCMD = "";
	// 存放命令执行结果
	private StringBuffer result = new StringBuffer();
	Session session;
	Channel channel;
	public static String[] errorMsg = new String[] { "could not acquire the config lock " };

	private Logger logger = Logger.getLogger("COLL");

	public static final int COMMAND_EXECUTION_SUCCESS_OPCODE = -2;
	private static Expect4j expect = null;
	// 正则匹配,用于处理服务器返回的结果
	public static String[] linuxPromptRegEx = new String[] { "~]#", "~#", "#", "$", ":~#", "/$", ">" };
	InputStream inputStream;  
	OutputStream outputStream;
	
	public void setRPCCMD(String rpccmd) {
		RPCCMD = rpccmd;
	}

	/**
	 * 构造函数
	 * 
	 * @param host_ip
	 * @param port
	 * @param login_id
	 * @param password
	 */
	public SSHThread(String host_ip, int port, String login_id, String password) {
		this.host_ip = host_ip;
		this.port = port;
		this.login_id = login_id;
		// this.password = DES3.decrypt(password);
		this.password = password;

		expect = getExpect();
	}

	// 获得Expect4j对象,该对用可以往SSH发送命令请求
	private Expect4j getExpect() {
		try {
			logger.debug(String.format("Start logging to %s@%s:%s", this.login_id, this.host_ip, port));
			JSch jsch = new JSch();
			session = jsch.getSession(this.login_id, this.host_ip, port);
			session.setPassword(password);
			Hashtable<String, String> config = new Hashtable<String, String>();
			config.put("StrictHostKeyChecking", "no");
			session.setConfig(config);
			localUserInfo ui = new localUserInfo();
			session.setUserInfo(ui);
			session.connect();
			channel = (ChannelShell) session.openChannel("shell");
			Expect4j expect = new Expect4j(channel.getInputStream(), channel.getOutputStream());
			expect.setDefaultTimeout(1000);
			channel.connect();
			logger.debug(String.format("Logging to %s@%s:%s successfully!", this.login_id, this.host_ip, port));
			return expect;
		} catch (Exception ex) {
			logger.error("Connect to " + this.host_ip + ":" + port + "failed,please check your username and password!");
			ex.printStackTrace();
		}
		return null;
	}

	// 登入SSH时的控制信息
	// 设置不提示输入密码、不显示登入信息等
	public static class localUserInfo implements UserInfo {
		String passwd;

		public String getPassword() {
			return passwd;
		}

		public boolean promptYesNo(String str) {
			return true;
		}

		public String getPassphrase() {
			return null;
		}

		public boolean promptPassphrase(String message) {
			return true;
		}

		public boolean promptPassword(String message) {
			return true;
		}

		public void showMessage(String message) {
		}
	}

	public void run() {
		// super.run();
	}

	/**
	 * 关闭连接
	 */
	public void close() {
		try {
			// if(channel!=null&&channel.isConnected()){
			// channel.disconnect();
			// }
			if (session != null && session.isConnected()) {
				session.disconnect();
				System.out.println("Disonnection successed!");
				logger.info("Disconnect ip=" + this.host_ip);
			} else {
				logger.info("Disconnect ip=has exception before" + this.host_ip);
			}
			if (channel != null) {
				channel.disconnect();
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e);
			logger.info("ERROR Disconnect ip=" + this.host_ip);
		}
	}

	/**
	 * 
	 */
	public void doCommand(String command) {
	}

	/**
	 * 
	 */
	public String getResultAsStr(String command) {
		this.result = new StringBuffer();
		Closure closure = new Closure() {
			public void run(ExpectState expectState) throws Exception {
				result.append(expectState.getBuffer());
				expectState.exp_continue();
			}
		};
		List<Match> lstPattern = new ArrayList<Match>();
		String[] regEx = linuxPromptRegEx;
		if (regEx != null && regEx.length > 0) {
			synchronized (regEx) {
				for (String regexElement : regEx) {
					try {
						RegExpMatch mat = new RegExpMatch(regexElement, closure);
						lstPattern.add(mat);
					} catch (MalformedPatternException e) {
						logger.error("RegExpMatch error", e);
					} catch (Exception e) {
						logger.error("RegExpMatch exec error", e);
					}
				}
				lstPattern.add(new EofMatch(new Closure() {
					public void run(ExpectState state) {
					}
				}));
				lstPattern.add(new TimeoutMatch(defaultTimeOut, new Closure() {
					public void run(ExpectState state) {
					}
				}));
			}
		}
		try {
			boolean isSuccess = true;
			isSuccess = isSuccess(lstPattern, command);
			// 防止最后一个命令执行不了
			isSuccess = !checkResult(expect.expect(lstPattern));

			// 找不到错误信息标示成功
			String response = result.toString().toLowerCase();

			for (String msg : errorMsg) {
				if (response.indexOf(msg) > -1) {
					logger.info(msg);
				}
			}

		} catch (Exception ex) {
			logger.error("RegExpMatch exec error", ex);
		}
		
		return formatNVT(getResponse(),command);
	}

	// 检查执行是否成功
	private boolean isSuccess(List<Match> objPattern, String strCommandPattern) {
		try {
			boolean isFailed = checkResult(expect.expect(objPattern));
			if (!isFailed) {
				expect.send(strCommandPattern);
				expect.send("\n");
				expect.getLastState();
				return true;
			}
			return false;
		} catch (MalformedPatternException ex) {
			return false;
		} catch (Exception ex) {
			return false;
		}
	}

	// 检查执行返回的状态
	private boolean checkResult(int intRetVal) {
		if (intRetVal == COMMAND_EXECUTION_SUCCESS_OPCODE) {
			return true;
		}
		return false;
	}

	public String getResult() {
		
		return null;
	}

	public void initial() throws Exception {
//		try {
//			JSch jsch = new JSch();
//			session = jsch.getSession(login_id, host_ip, port);
//			logger.info("into the step 11111" + login_id + "--" + host_ip + "--" + port + "--" + password);
//			if (session != null) {
//				session.setPassword(this.password);
//				session.setConfig("StrictHostKeyChecking", this.keyChecking);
//				session.connect(30000);
//				this.autorized = true;
//				logger.info("ssh connect successfuly!!! ip= " + this.host_ip);
//				if (session != null && !session.isConnected()) {
//					this.autorized = false;
//					this.close();
//				}
//			}
//		} catch (Exception e) {
//			System.out.println("ssh创建session失败");
//			e.printStackTrace();
//			logger.error(e);
//			logger.error("ssh connect fail ip=" + this.host_ip);
//			throw new Exception(e);
//		}
	}

	public boolean getResultAsString(String targetString) {
		try {
			InputStream in = channel.getInputStream();
			int nextChar;
			while (true) {
				while ((nextChar = in.read()) != -1) {
					result.append((char) nextChar);
					if (this.result.toString().indexOf(targetString) != -1) {
						return true;
					}
				}
				if (channel.isClosed() || channel.isEOF()) {
					// System.out.println(" exit-status: "
					// + channel.getExitStatus());
					in.close();
					break;
				}
				try {
					Thread.sleep(500);
				} catch (Exception ee) {
					ee.printStackTrace();
					return false;
				}
			}
		} catch (Exception e) {
			this.result = new StringBuffer();
			e.printStackTrace();
			return false;
		}
		if (this.result.toString().indexOf(targetString) != -1) {
			return true;
		} else {
			return false;
		}
	}
	
	private String formatNVT(String str,String command){
		String nvt_start = InterfacePro.nvt_start;
		String nvt_end = InterfacePro.nvt_end;
		
//		str = Pattern.compile("\\[0[^\\[0]*m", Pattern.DOTALL).matcher(str).replaceAll("");
//		str = Pattern.compile(nvt_start+"[^"+nvt_start+"]*"+nvt_end, Pattern.DOTALL).matcher(str).replaceAll("");
		
		str = str.replace(nvt_start, "");
		str = str.replace(nvt_end, "");
		String[] s = str.split("\n");
		
		String result = "";
		if(s.length>0){
			for(int i=0;i<s.length-1;i++){
				if(s[i].indexOf(command)>=0||s[i].indexOf("Last login:")>=0)
					continue;
				else
					result += s[i]+"\n";
			}
		}
		return result;
	}

	/**
	 * 获取服务器返回的信息
	 * 
	 * @return 服务端的执行结果
	 */
	public String getResponse() {
		return result.toString();
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String str = "";
		if (true) {
			try {
				SSHThread ssh = new SSHThread("172.21.1.100", 22, "bnmsapp4", "bnmsapp4");
				String cmd = "var=0\r\ndf -k /bnmsapp4/basd | grep \"/\" | grep \"%\" | awk '{print $4}' | while read lll\r\ndo\r\nvar=${lll}\r\necho 'var='$var\r\ndone";
				str = ssh.getResultAsStr(cmd);
				System.out.println("======================");	
				System.out.println(str);
				System.out.println("======================");				
				ssh.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			System.out.println("please use : java com.sitech.ismp.coll.centercoll.SSHThread <ip> <username> <password>");
		}
//		String nvt_start = "123";
//		String nvt_end = "456";
//		str = str.replace("[01;34", "");
//		str = str.replace("", "");
////		str = Pattern.compile(nvt_start+"[^"+nvt_start+"]*"+nvt_end, Pattern.DOTALL).matcher(str).replaceAll("");
//		str = Pattern.compile("123[^123]*456", Pattern.DOTALL).matcher(str).replaceAll("");
//		System.out.println(str);

	}
}