/** * This will execute the given command with given session and session is not closed at the end. * * @param commandInfo * @param session * @param commandOutput * @throws SSHApiException */ public static Session executeCommand( CommandInfo commandInfo, Session session, CommandOutput commandOutput) throws SSHApiException { String command = commandInfo.getCommand(); Channel channel = null; try { if (!session.isConnected()) { session.connect(); } channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); } catch (JSchException e) { session.disconnect(); throw new SSHApiException("Unable to execute command - ", e); } channel.setInputStream(null); ((ChannelExec) channel).setErrStream(commandOutput.getStandardError()); try { channel.connect(); } catch (JSchException e) { channel.disconnect(); session.disconnect(); throw new SSHApiException("Unable to retrieve command output. Command - " + command, e); } commandOutput.onOutput(channel); // Only disconnecting the channel, session can be reused channel.disconnect(); return session; }
/** * Copy a file to specific destination with WinSCP command * * @param lfile file you want to transfer * @param rfile destination file */ public synchronized void scpTo(String lfile, String rfile) { if (!connected) { throw new ActionFailedException("There is no session!"); } try { // exec 'scp -t rfile' remotely String command = "scp -p -t " + rfile; channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); // get I/O streams for remote scp OutputStream out = channel.getOutputStream(); InputStream in = channel.getInputStream(); channel.connect(); // byte[] tmp = new byte[1]; checkAck(in); // send "C0644 filesize filename", where filename should not include '/' int filesize = (int) (new File(lfile)).length(); command = "C0644 " + filesize + " "; if (lfile.lastIndexOf('/') > 0) { command += lfile.substring(lfile.lastIndexOf('/') + 1); } else { command += lfile; } command += "\n"; out.write(command.getBytes()); out.flush(); checkAck(in); // send a content of lfile FileInputStream fis = new FileInputStream(lfile); byte[] buf = new byte[1024]; while (true) { int len = fis.read(buf, 0, buf.length); if (len <= 0) break; out.write(buf, 0, len); out.flush(); } fis.close(); // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); checkAck(in); } catch (Exception e) { throw new ItemNotFoundException("Failed to copy file: " + e.getMessage()); } finally { if (channel != null) { channel.disconnect(); } } }
public void shutdown() { retries = -1; if (channel != null) { try { channel.disconnect(); channel.close(); } catch (Throwable e) { Flog.error(e); } channel = null; } }
public void disconnect() { if (connected) { if (channel != null) { channel.disconnect(); channel = null; } if (session != null) { session.disconnect(); session = null; } connected = false; } }
@Override public void run() { try { logger.debug("starting cleanup"); for (Map.Entry<String, Channel> entry : connections.entrySet()) { Channel channel = entry.getValue(); Long lastMessage = channel.attr(lastMessageAttrKey).get(); if (System.currentTimeMillis() - lastMessage > FIVE_MINUTES) { channel.disconnect(); connections.remove(entry.getKey()); logger.debug("connection released for {}", entry.getKey()); } else if (!channel.isActive()) { connections.remove(entry.getKey()); logger.debug("connection released for {}", entry.getKey()); } } logger.debug("cleanup complete"); } catch (Exception e) { logger.error("exception while clean up", e); } }
public void execCmd(String command) { // BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // String command = ""; BufferedReader reader = null; Channel channel = null; try { // while ((command = br.readLine()) != null) { channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); channel.setInputStream(null); ((ChannelExec) channel).setErrStream(System.err); channel.connect(); InputStream in = channel.getInputStream(); reader = new BufferedReader(new InputStreamReader(in, Charset.forName(charset))); String buf = null; while ((buf = reader.readLine()) != null) { System.out.println(buf); } // } } catch (IOException e) { e.printStackTrace(); } catch (JSchException e) { e.printStackTrace(); } finally { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } channel.disconnect(); session.disconnect(); } }
public static void main(String[] arg) { if (arg.length != 2) { System.err.println("usage: java ScpTo file1 user@remotehost:file2"); System.exit(-1); } FileInputStream fis = null; try { String lfile = arg[0]; String user = arg[1].substring(0, arg[1].indexOf('@')); arg[1] = arg[1].substring(arg[1].indexOf('@') + 1); String host = arg[1].substring(0, arg[1].indexOf(':')); String rfile = arg[1].substring(arg[1].indexOf(':') + 1); JSch jsch = new JSch(); Session session = jsch.getSession(user, host, 22); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); boolean ptimestamp = true; // exec 'scp -t rfile' remotely String command = "scp " + (ptimestamp ? "-p" : "") + " -t " + rfile; Channel channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); // get I/O streams for remote scp OutputStream out = channel.getOutputStream(); InputStream in = channel.getInputStream(); channel.connect(); if (checkAck(in) != 0) { System.exit(0); } File _lfile = new File(lfile); if (ptimestamp) { command = "T " + (_lfile.lastModified() / 1000) + " 0"; // The access time should be sent here, // but it is not accessible with JavaAPI ;-< command += (" " + (_lfile.lastModified() / 1000) + " 0\n"); out.write(command.getBytes()); out.flush(); if (checkAck(in) != 0) { System.exit(0); } } // send "C0644 filesize filename", where filename should not include '/' long filesize = _lfile.length(); command = "C0644 " + filesize + " "; if (lfile.lastIndexOf('/') > 0) { command += lfile.substring(lfile.lastIndexOf('/') + 1); } else { command += lfile; } command += "\n"; out.write(command.getBytes()); out.flush(); if (checkAck(in) != 0) { System.exit(0); } // send a content of lfile fis = new FileInputStream(lfile); byte[] buf = new byte[1024]; while (true) { int len = fis.read(buf, 0, buf.length); if (len <= 0) break; out.write(buf, 0, len); // out.flush(); } fis.close(); fis = null; // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); if (checkAck(in) != 0) { System.exit(0); } out.close(); channel.disconnect(); session.disconnect(); System.exit(0); } catch (Exception e) { System.out.println(e); try { if (fis != null) fis.close(); } catch (Exception ee) { } } }
/** * This will not reuse any session, it will create the session and close it at the end * * @param commandInfo Encapsulated information about command. E.g :- executable name parameters * etc ... * @param serverInfo The SSHing server information. * @param authenticationInfo Security data needs to be communicated with remote server. * @param commandOutput The output of the command. * @param configReader configuration required for ssh/gshissh connection * @throws SSHApiException throw exception when error occurs */ public static void executeCommand( CommandInfo commandInfo, ServerInfo serverInfo, AuthenticationInfo authenticationInfo, CommandOutput commandOutput, ConfigReader configReader) throws SSHApiException { if (authenticationInfo instanceof GSIAuthenticationInfo) { System.setProperty( X509_CERT_DIR, (String) ((GSIAuthenticationInfo) authenticationInfo).getProperties().get("X509_CERT_DIR")); } JSch jsch = new ExtendedJSch(); log.debug( "Connecting to server - " + serverInfo.getHost() + ":" + serverInfo.getPort() + " with user name - " + serverInfo.getUserName()); Session session; try { session = jsch.getSession(serverInfo.getUserName(), serverInfo.getHost(), serverInfo.getPort()); } catch (JSchException e) { throw new SSHApiException( "An exception occurred while creating SSH session." + "Connecting server - " + serverInfo.getHost() + ":" + serverInfo.getPort() + " connecting user name - " + serverInfo.getUserName(), e); } java.util.Properties config = configReader.getProperties(); session.setConfig(config); // ============================================================= // Handling vanilla SSH pieces // ============================================================= if (authenticationInfo instanceof SSHPasswordAuthentication) { String password = ((SSHPasswordAuthentication) authenticationInfo) .getPassword(serverInfo.getUserName(), serverInfo.getHost()); session.setUserInfo(new SSHAPIUIKeyboardInteractive(password)); // TODO figure out why we need to set password to session session.setPassword(password); } else if (authenticationInfo instanceof SSHPublicKeyFileAuthentication) { SSHPublicKeyFileAuthentication sshPublicKeyFileAuthentication = (SSHPublicKeyFileAuthentication) authenticationInfo; String privateKeyFile = sshPublicKeyFileAuthentication.getPrivateKeyFile( serverInfo.getUserName(), serverInfo.getHost()); logDebug("The private key file for vanilla SSH " + privateKeyFile); String publicKeyFile = sshPublicKeyFileAuthentication.getPrivateKeyFile( serverInfo.getUserName(), serverInfo.getHost()); logDebug("The public key file for vanilla SSH " + publicKeyFile); Identity identityFile; try { identityFile = GSISSHIdentityFile.newInstance(privateKeyFile, null, jsch); } catch (JSchException e) { throw new SSHApiException( "An exception occurred while initializing keys using files. " + "(private key and public key)." + "Connecting server - " + serverInfo.getHost() + ":" + serverInfo.getPort() + " connecting user name - " + serverInfo.getUserName() + " private key file - " + privateKeyFile + ", public key file - " + publicKeyFile, e); } // Add identity to identity repository GSISSHIdentityRepository identityRepository = new GSISSHIdentityRepository(jsch); identityRepository.add(identityFile); // Set repository to session session.setIdentityRepository(identityRepository); // Set the user info SSHKeyPasswordHandler sshKeyPasswordHandler = new SSHKeyPasswordHandler((SSHKeyAuthentication) authenticationInfo); session.setUserInfo(sshKeyPasswordHandler); } else if (authenticationInfo instanceof SSHPublicKeyAuthentication) { SSHPublicKeyAuthentication sshPublicKeyAuthentication = (SSHPublicKeyAuthentication) authenticationInfo; Identity identityFile; try { String name = serverInfo.getUserName() + "_" + serverInfo.getHost(); identityFile = GSISSHIdentityFile.newInstance( name, sshPublicKeyAuthentication.getPrivateKey( serverInfo.getUserName(), serverInfo.getHost()), sshPublicKeyAuthentication.getPublicKey( serverInfo.getUserName(), serverInfo.getHost()), jsch); } catch (JSchException e) { throw new SSHApiException( "An exception occurred while initializing keys using byte arrays. " + "(private key and public key)." + "Connecting server - " + serverInfo.getHost() + ":" + serverInfo.getPort() + " connecting user name - " + serverInfo.getUserName(), e); } // Add identity to identity repository GSISSHIdentityRepository identityRepository = new GSISSHIdentityRepository(jsch); identityRepository.add(identityFile); // Set repository to session session.setIdentityRepository(identityRepository); // Set the user info SSHKeyPasswordHandler sshKeyPasswordHandler = new SSHKeyPasswordHandler((SSHKeyAuthentication) authenticationInfo); session.setUserInfo(sshKeyPasswordHandler); } // Not a good way, but we dont have any choice if (session instanceof ExtendedSession) { if (authenticationInfo instanceof GSIAuthenticationInfo) { ((ExtendedSession) session) .setAuthenticationInfo((GSIAuthenticationInfo) authenticationInfo); } } try { session.connect(); } catch (JSchException e) { throw new SSHApiException( "An exception occurred while connecting to server." + "Connecting server - " + serverInfo.getHost() + ":" + serverInfo.getPort() + " connecting user name - " + serverInfo.getUserName(), e); } String command = commandInfo.getCommand(); Channel channel; try { channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); } catch (JSchException e) { session.disconnect(); throw new SSHApiException( "Unable to execute command - " + command + " on server - " + serverInfo.getHost() + ":" + serverInfo.getPort() + " connecting user name - " + serverInfo.getUserName(), e); } channel.setInputStream(null); ((ChannelExec) channel).setErrStream(commandOutput.getStandardError()); try { channel.connect(); } catch (JSchException e) { channel.disconnect(); session.disconnect(); throw new SSHApiException( "Unable to retrieve command output. Command - " + command + " on server - " + serverInfo.getHost() + ":" + serverInfo.getPort() + " connecting user name - " + serverInfo.getUserName(), e); } commandOutput.onOutput(channel); channel.disconnect(); session.disconnect(); }
/** * execute the given command in the remote host * * @param command * @return - command output in the remote host */ public String exec(String command) { if (!connected) { throw new ActionFailedException("There is no session!"); } StringBuffer data = new StringBuffer(); OutputStream out = null; InputStream in = null; try { Channel channel; boolean channel_connected = false; int count = 0; while (!channel_connected) { try { channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); out = channel.getOutputStream(); in = channel.getInputStream(); channel.connect(); channel_connected = true; } catch (Exception e) { count++; String msg = e.getMessage(); if (count < 5) { AutomationLogger.getInstance() .warn( "Failed to connect to SSH server due to " + msg + ". Will try again in 1 second"); if (msg.startsWith("session is down")) { AutomationLogger.getInstance().info("Try to re-connect session"); connect(); } Timer.sleep(1000); } else { throw new ActionFailedException("Failed to connect to SSH server due to " + e); } } } byte[] buf = new byte[1024]; // read count = 0; while ((count = in.read(buf)) > 0) { data.append(new String(buf, 0, count)); } } catch (Exception e) { AutomationLogger.getInstance().warn(e); } finally { try { in.close(); } catch (Exception e) { } try { out.close(); } catch (Exception e) { } if (channel != null) { channel.disconnect(); } } return data.toString(); }
/** * copy a file from remote host to local * * @param rfile * @param lfile */ public String scpFrom(String rfile, String lfile) { if (!connected) { throw new ActionFailedException("There is no session!"); } FileOutputStream fos = null; // When get a rfile which with regular expression, to save the file with the same name as it get // from the remote server[add by phoebe] String completeLfile = lfile; try { // exec 'scp -f rfile' remotely String command = "scp -f " + rfile; Channel channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); // get I/O streams for remote scp OutputStream out = channel.getOutputStream(); InputStream in = channel.getInputStream(); channel.connect(); byte[] buf = new byte[1024]; // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); while (true) { int c = checkAck(in); if (c != 'C') { break; } // read '0644 ' in.read(buf, 0, 5); long filesize = 0L; while (true) { if (in.read(buf, 0, 1) < 0) { // error break; } if (buf[0] == ' ') break; filesize = filesize * 10L + (long) (buf[0] - '0'); } String file = null; for (int i = 0; ; i++) { in.read(buf, i, 1); if (buf[i] == (byte) 0x0a) { file = new String(buf, 0, i); break; } } // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); // When get a rfile which with regular expression, to save the file with the same name as it // get from the remote server[add by phoebe] if (completeLfile.contains("*")) { completeLfile = completeLfile.substring(0, completeLfile.lastIndexOf("/")) + "/" + file; } // read a content of lfile fos = new FileOutputStream(completeLfile); int foo; while (true) { if (buf.length < filesize) foo = buf.length; else foo = (int) filesize; foo = in.read(buf, 0, foo); if (foo < 0) { // error break; } fos.write(buf, 0, foo); filesize -= foo; if (filesize == 0L) break; } fos.close(); fos = null; if (checkAck(in) != 0) { throw new ActionFailedException("Failed to get Ack, Copy may fail!"); } // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); } } catch (IOException e) { e.printStackTrace(); } catch (JSchException e) { e.printStackTrace(); } finally { if (channel != null) { channel.disconnect(); } } return completeLfile; }
public ChannelFuture disconnect() { return channel.disconnect(); }