Sending Jsch commands - java

Beating my head against a wall here.
I am trying in the constructor to establish a link and log on. Then in the begin method to execute a java application on the remote computer. Finally in terminate, to kill the java process.
No exceptions show up, the command just doesn't execute. I can see the user has logged in if I go to the remote terminal and run a last. The user has only a login time of 0 though. I can also get an error if I change the password to the wrong password.
But the remote java app isn't running. Remote app runs fine when I log in directly from that terminal or ssh in and run it from the command line.
Ideas? Thanks in advance.
//Constants for the login information
String HOST="<HOSTNAME>";
String USER="<userid>";
String PASSWORD="<password>";
//Constants for command strings
String START_COMMAND="java -Djava.library.path=/usr/local/share/OpenCV/java -jar <filename>";
String TERMINATE_COMMAND="killall java";
Channel channel;
Session session;
InputStream in;
public VisionProcessing(){
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
try {
System.out.println("Trying login");
session = jsch.getSession(USER, HOST, 22);
session.setPassword(PASSWORD);
session.setConfig(config); //XXX No idea what this does
session.connect();
channel=session.openChannel("exec");
((ChannelExec)channel).setPty(true);
channel.connect();//This is important
if (channel.isConnected()){
System.out.println("Connected");
} else {
System.out.println("Not Connected");
}
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Exception logging in");
}
}
public boolean beginTargeting() {
try {
StringBuilder outputBuffer = new StringBuilder();
Channel channel = session.openChannel("exec");
InputStream commandOutput = channel.getInputStream();
int readByte = commandOutput.read();
while(readByte != 0xffffffff)
{
outputBuffer.append((char)readByte);
readByte = commandOutput.read();
}
System.out.println("Begin");
if (channel.isConnected()){
System.out.println("Connected");
((ChannelExec)channel).setCommand(START_COMMAND);
} else {
System.out.println("Not Connected");
}
channel.connect();//This is important
channel.disconnect();
}catch(IOException ioX)
{
System.out.println(ioX);
}
catch(JSchException jschX)
{
System.out.println(jschX);
}
return true;
}
public boolean terminateTargeting() {
try {
System.out.println("Terminate");
channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(TERMINATE_COMMAND);
channel.connect();//This is important
System.out.println("Terminating");
channel.setInputStream(null);
channel.disconnect();
session.disconnect();
System.out.println("DONE");
}catch(Exception ee){
System.out.println(ee);
}
return true;
}

Related

Running Command on a Router Line By Line (JSCH API)

I have written a method in Java, which takes an ArrayList of Strings and tries to run the command on a CISCO router console one by one. And I am trying to print the output of each command on the console. I am using the Jsch API for it.
I am able to connect to the router just fine using SSH. But when I print the OutputStream to the console it just prints the same thing over and over again. No output of the commands I sent. I intentionally have a few incorrect commands in there so that the console prints the error, but I get no such thing.
Here is my method:
/**
* Deliver a config to the router line by line.
* #param configLines
* #throws DeviceExcpetion
*/
public void deliverConfig(List<String> configLines) throws DeviceExcpetion {
Channel channel = null;
JSch jSch = new JSch();
Session session = null;
try {
session = jSch.getSession(userid, ipAddress, port);
// Set the password.
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
// Finally make the connection.
session.connect();
channel = session.openChannel("shell");
InputStream inputStream = null;
ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
channel.setOutputStream(responseStream);
channel.connect();
for (String line : configLines) {
inputStream = new ByteArrayInputStream(line.getBytes(StandardCharsets.UTF_8));
channel.setInputStream(inputStream);
if (channel.isConnected()) {
Thread.sleep(1000);
}
String responseString = new String(responseStream.toByteArray());
System.out.println(responseString);
}
} catch (JSchException e) {
e.printStackTrace();
throw new DeviceExcpetion(e.getMessage());
} catch (InterruptedException e) {
e.printStackTrace();
throw new DeviceExcpetion(e.getMessage());
} finally {
if (session != null) {
session.disconnect();
}
if (channel != null) {
channel.disconnect();
}
}
}

ssh to remote server inside remote server using jsch(jump server to dev machine)

I have two machines dev server and log server which has logs stored, I want to first ssh to dev server and then from there i want to do ssh to log server to execute some script.
Below is the code I tried using jsch :
Get jschSession:
private Session getSSHSession(String user,String host,String password) {
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
Session session = null;
try {
JSch jsch = new JSch();
session=jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig(config);
session.connect();
} catch (JSchException e) {
e.printStackTrace();
}
return session;
}
Execute a command
private String execute(Session session, String cmd) {
StringBuffer sb = new StringBuffer();
try{
Channel channel=session.openChannel("exec");
((ChannelExec) channel).setPty(true);
((ChannelExec)channel).setCommand(cmd);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
channel.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(channel.getInputStream()));
String msg = null;
while ((msg = br.readLine())!=null) {
sb.append(msg);
}
System.out.println("------------msg: -----------"+sb.toString());
while(true){
System.out.println("channel.getExitStatus(): "+channel.getExitStatus());
if(channel.isClosed()){
System.out.println("exit-status: "+channel.getExitStatus());
if(channel.getExitStatus()==0) {
System.out.println("script executed successfully..........");
}
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
channel.disconnect();
session.disconnect();
}catch(Exception e){
e.printStackTrace();
}
return sb.toString();
}
call the execute
public String audit(AuditRequest request) {
Session session = getSSHSession(user,host,password);
String cmd = "ssh user#server; cd /mmt/test;ls -ltr";
String result = execute(session,cmd);
System.out.println("cmd1: "+cmd+" result: -------------"+result);
return result;
}
So basically I am first connecting to dev server and then using its session I am trying to execute the ssh command to connect to log server.
By the posted code I am able to connect to my dev machine but from there not able to do ssh to log machine.
If i remove ((ChannelExec) channel).setPty(true); below is the error I am getting:
Pseudo-terminal will not be allocated because stdin is not a terminal.
Permission denied, please try again.
Permission denied, please try again.
And ifI put the setPty for pseudo terminal , it's stucking in channel.connect();
Read multiple posts/questions lots of people mentioned using channel.setPty(true) But that doesn't seems to work
Could anyone help me to know what is going wrong here.
Thanks

Jsch java ssh client is not getting disconnected after command gets executed

I am using java ssh client (http://www.jcraft.com/jsch/) to connect to remote machine and execute the command.
The code is working fine till i connect to remote machine and execute the command. however, the issue is , the channel and session are not getting disconnected even after command executed successfully.
I have called session.disconnect and channel.disconnect as well but still the issue.
Here is my code:
JSch jsch = new JSch();
String host = null;
host = "192.168.102.211";
String privateKey = "C:\\test\\key";
String cmd = "a";
String command = "b";
jsch.addIdentity(privateKey);
Session session = jsch.getSession("user1", host, 22);
Channel channel = session.openChannel("shell");
UserInfo ui = new MyUserInfo() {
public boolean promptYesNo(String message) {
return true;
}
};
session.setUserInfo(ui);
session.connect(30000);
OutputStream ops = channel.getOutputStream();
PrintStream ps = new PrintStream(ops, true);
channel.connect();
ps.println(cmd);
ps.println(command);
ps.close();
InputStream in = channel.getInputStream();
byte[] bt = new byte[1024];
while (in.available() > 0) {
// int i = in.read(bt, 0, 1024);
for (int i = in.read(); i >=0; i--)
{
String str = new String(bt, 0, i);
System.out.print(str);
}
break;
}
if (channel != null) {
channel.disconnect();
session.disconnect();
System.out.println(channel.isConnected());
}
}
Please suggest
Update your question with a relevant code.
just a hint, you should do something like.
} finally {
if (channel != null) {
Session session = channel.getSession();
channel.disconnect();
session.disconnect();
System.out.println(channel.isConnected());
}
}
I have similar error I change my code to that
first I have declare session and channel
static Session session = null;
static Channel channel = null;
And this the connation code
public static OutputStream puttyConnection(String user, String hostName, String password)
throws JSchException, IOException {
session = new JSch().getSession(user, hostName, 22);
session.setPassword(password);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
channel = session.openChannel("shell");
OutputStream ops = channel.getOutputStream();
channel.connect();
return ops;
}
and in the finish of my running code I use to disconnect like that
if (channel != null) {
channel.disconnect();
session.disconnect();
System.out.println(channel.isConnected());
}
I encountered a similar problem, realizing that the channel could only be disconnected if it was closed. So I used the while loop to check if the channel is closed and then I was able to disconnect the channel without any problem.
while (true){
if(channel.isClosed()){
channel.disconnect();
break;
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

JSch Shell channel execute commands one by one testing result before proceeding

I have a program for connecting to an SSH shell. I was able to execute the commands and read output from them.
But I have a new requirement. Now I need to execute a command and read the output if successful execute the next command.
I have used the program from this question: JSch issue - Cannot retrieve full command output
public class SshConnectionManager {
private static Session session;
private static ChannelShell channel;
private static String username = "";
private static String password = "";
private static String hostname = "";
private static Session getSession(){
if(session == null || !session.isConnected()){
session = connect(hostname,username,password);
}
return session;
}
private static Channel getChannel(){
if(channel == null || !channel.isConnected()){
try{
channel = (ChannelShell)getSession().openChannel("shell");
channel.setPty(false);
channel.connect();
}catch(Exception e){
System.out.println("Error while opening channel: "+ e);
}
}
return channel;
}
private static Session connect(String hostname, String username, String password){
JSch jSch = new JSch();
try {
session = jSch.getSession(username, hostname, 22);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(password);
System.out.println("Connecting SSH to " + hostname + " - Please wait for few seconds... ");
session.connect();
System.out.println("Connected!");
}catch(Exception e){
System.out.println("An error occurred while connecting to "+hostname+": "+e);
}
return session;
}
private static void executeCommands(List<String> commands){
try{
Channel channel=getChannel();
System.out.println("Sending commands...");
sendCommands(channel, commands);
readChannelOutput(channel);
System.out.println("Finished sending commands!");
}catch(Exception e){
System.out.println("An error ocurred during executeCommands: "+e);
}
}
private static void sendCommands(Channel channel, List<String> commands){
try{
PrintStream out = new PrintStream(channel.getOutputStream());
out.println("#!/bin/bash");
for(String command : commands){
out.println(command);
}
out.println("exit");
out.flush();
}catch(Exception e){
System.out.println("Error while sending commands: "+ e);
}
}
private static void readChannelOutput(Channel channel){
byte[] buffer = new byte[1024];
try{
InputStream in = channel.getInputStream();
String line = "";
while (true){
while (in.available() > 0) {
int i = in.read(buffer, 0, 1024);
if (i < 0) {
break;
}
line = new String(buffer, 0, i);
System.out.println(line);
}
if(line.contains("logout")){
break;
}
if (channel.isClosed()){
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee){}
}
}catch(Exception e){
System.out.println("Error while reading channel output: "+ e);
}
}
public static void close(){
channel.disconnect();
session.disconnect();
System.out.println("Disconnected channel and session");
}
public static void main(String[] args){
List<String> commands = new ArrayList<String>();
commands.add("ls -l");
executeCommands(commands);
close();
}
}
I need to use "shell" channel instead of "exec" because the server does not allow the "exec" channel: link
In general you should use an "exec" channel for this. The "shell" channel should not be used to automate a command execution.
But I understand that your server does not support the "exec" channel. I've added the above comment for the other readers, not to try to use this solution, unless they really have to.
As #Yair Harel already commented, if you have to use the "shell" channel, you have to use shell techniques.
So in your particular case, you may want to have the remote shell print some unique string and the exit code after the command finishes:
out.println(command + " ; echo Command-has-finished-with-code-$?");
Then you keep reading the output until you find a line starting "Command-has-finished-with-code-". You parse the exit code and decide how to proceed.
Note that the command syntax (particularly the command separator character ; and exit code variable $?) is OS- and shell-specific. As your server is not of a standard kind, the syntax may be different.
Side notes:
The "#!/bin/bash" is a pure nonsense. The shell ignores all commands starting with # (it's comment). There's no point sending it.
Do not use StrictHostKeyChecking=no. See JSch SFTP security with session.setConfig("StrictHostKeyChecking", "no");

I am trying to post multiple file using SFTP connection but not able to post more than 2 files

I am trying to post multiple file using SFTP connection. I am using below code to connect SFTP server and post file on server.
My program running properly but for only 2 file not more than that, third file on words its generates Authentication error "com.jcraft.jsch.JSchException: Auth fail".
Could you please somebody guide me for that.
public boolean putSftp(String input , String fileName) {
JSch jsch = new JSch();
Session session = null;
try {
System.out.println("Input : "+input+": File Name :"+fileName+" :-----------Logon on to the Server---------- : "+ datetime);
session = jsch.getSession(USER_NAME, FTP_HOSTNAME, 22);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(PASSWORD);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
sftpChannel.cd(TO_DIRECTORY);
sftpChannel.put(input+fileName, fileName);
System.out.println("File sucessfully posted on server....:"+datetime);
sftpChannel.exit();
session.disconnect();
result = true;
}catch (JSchException e) {
System.out.println("Here JSCH...!!! : ");
e.printStackTrace();
}catch (SftpException e) {
System.out.println("Here SFTP...!!! :");
e.printStackTrace();
} catch (Exception e){
System.out.println("Here Exception...!!!"+e);
}finally {
System.out.println("In Side of SFTP Method....."+result);
}
return result;
}

Categories

Resources