Interact with linux server using java JSCH - java

I have created java program using JSch class. Program successfully execute the (ls, cd, change) commands. These commands dint need any inputs. But while executing the /usr/ses/b/kr command it require the password.
Can you please reply how I can send password to linux server using JSch. Or there is any another way?
((ChannelExec)channel).setCommand("/usr/ses/b/kr;");

You should set StrictHostKeyChecking property "no" and channel should be set shell.as following.
String username = "xxxyyyzzz";
String password = "aaabbbccc";
String host = "192.168.1.1"; // sample ip address
if(command.getText().toString() != ""){
JSch jsch = new JSch();
try {
session = jsch.getSession(username, host, 22);
session.setPassword(password);
Properties properties = new Properties();
properties.put("StrictHostKeyChecking", "no");
session.setConfig(properties);
session.connect(30000);
channel = session.openChannel("shell");
channel.setInputStream(bais);
channel.setOutputStream(baos);
channel.connect();
} catch (JSchException e) {
// TODO Auto-generated catch block
}
}
else{
//
}

Related

Audit Log on machine shows login every time channel connected in JSch

I am using JSch to fetch data from remote server on brocade switch. A new session is created and a new channel is opened with type as 'shell'. I have few commands which fetches data from this server. I created new Channel for every command and disconnects channel after fetching data.
Now in Audit log on server shows new login for every channel which i created for each command.
Should login be shown for every session created instead of every channel connected?
public Session getSession(String hostName,
String username,
String password,
Integer port) throws Exception {
Session session = null;
try {
JSch jsch = new JSch();
if (port == null) {
port = 22;
}
session = jsch.getSession(username, hostName, port);
session.setPassword(password);
session.setConfig("max_input_buffer_size", Integer.toString(100 * 1024 * 1024));
session.setConfig("StrictHostKeyChecking", "no");
session.setConfig("UserKnownHostsFile", "/dev/null");
session.connect(15 * 1000);
} catch (Exception e) {
if (session != null) {
session.disconnect();
}
throw new Exception("Error in connecting to: " + hostName, e);
}
return session;
}
private Channel getChannel(Session session,String type) throws Exception {
if (session == null || !session.isConnected()) {
session = getSession();
}
Channel channel = null;
try {
channel = session.openChannel(type);
} catch (Exception e) {
throw e;
}
channel.setInputStream(null);
return channel;
}
SSH channel does not create a new login.
But it creates a new shell session. Maybe your "audit log" logs shell session as if it were a new login. With a normal SSH client, you typically create only one shell session for each login. So it's easy to mismatch these two things.

Search file on SSH server for a pattern (with less command) using JSch

I am currently trying to access a Linux server and run some commands.
The general idea is to search for a log file containing certain text and then access that log, search for the requisite text and store all the data currently displayed on the screen in a String.
This approach works fine through PuTTY but now the requirement is different.
I have accomplished this task on other commands like ls and other commands that provide a direct output. However, I am having no luck with commands like less or more.
I have of course tried on sending the entire contents of the log to an array list and then searching for my text (seeing as I will have a relative idea of the position of the data once the 1st line is found). However, this takes a huge amount of time as the log size varies from 10 Mb to 750 Mb.
I would appreciate if anyone can think of another approach or provide any ideas towards a feasible way to this approach.
For reference:
Code I have tried
public class check {
private Session session;
private String username = "user";
private String password = "pass";
private String hostname = "host";
public SSHConnectionManager()
{ }
public SSHConnectionManager(String hostname, String username, String password)
{
this.hostname = hostname;
this.username = username;
this.password = password;
}
public void open() throws JSchException
{
open(this.hostname, this.username, this.password);
}
public void open(String hostname, String username, String password) throws JSchException
{
JSch jSch = new JSch();
session = jSch.getSession(username, hostname, 22);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no"); // not recommended
session.setConfig(config);
session.setPassword(password);
System.out.println("Connecting SSH to " + hostname + " - Please wait for few seconds... ");
session.connect();
System.out.println("Connected!");
}
public String runCommand(String command) throws JSchException, IOException
{
String ret = "";
if (!session.isConnected())
throw new RuntimeException("Not connected to an open session. Call open() first!");
ChannelExec channel = null;
channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(command);
channel.setInputStream(null);
PrintStream out = new PrintStream(channel.getOutputStream());
InputStream in = channel.getInputStream(); // channel.getInputStream();
channel.connect();
ret = getChannelOutput(channel, in);
channel.disconnect();
System.out.println("Finished sending commands!");
return ret;
}
private String getChannelOutput(Channel channel, InputStream in) throws IOException
{
byte[] buffer = new byte[1024];
StringBuilder strBuilder = new StringBuilder();
String line = "";
while (true){
while (in.available() > 0) {
int i = in.read(buffer, 0, 1024);
if (i < 0) {
break;
}
strBuilder.append(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){}
}
return strBuilder.toString();
}
public void close()
{
session.disconnect();
System.out.println("Disconnected channel and session");
}
public static void main(String[] args)
{
SSHConnectionManager ssh = new SSHConnectionManager();
try {
ssh.open();
String ret = ssh.runCommand("ls -l");
System.out.println(ret);
ret=ssh.runCommand("cd *move to path of log*");
System.out.println(ret);
ret=ssh.runCommand("less *log name*");
System.out.println(ret);
ret=ssh.runCommand("/*searchtext*");
System.out.println(ret);
ssh.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I get the necesaary output for my ls command but not for any of the others.
First, your code executes every command in its own separate shell. So the cd command has no effect on the less command. Send, /*searchtext* is not a command at all. Note that setCommand is not an equivalent of typing something in SSH console window. It's completely different interface.
First step would be to execute all commands in the same shell. For that use a shell technique of your server. On Linux server, you would use semicolon or double ampersand. As for example shown here: Multiple commands using JSch.
Though it won't help you with the /*searchtext*. You should not try to use "human" techniques for automation.
In the end, the better solution is to actually do everything with a single command, like using grep:
grep *searchtext* *move to path of log*/*log name*

JSCH session connection issue

I ran the below program and reboot the host which takes almost 6 to 8 mins to complete the reboot, but i never get the timed out.. i.e is it never go to else part.
public static void main(String a[]) throws JSchException, InterruptedException {
java.util.Properties config = new java.util.Properties();
JSch jsch = new JSch();
String user = "cli";
String host = "135.104.217.114";
String password = "cli";
int port = 22;
Session session = jsch.getSession(user,host,port);
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(password);
session.connect();
while(true)
{
if(session.isConnected())
{
System.out.println("session connected");
}
else
{
System.out.println("sesion not connected--------------");
}
Thread.sleep(1000);
}
}
You most likely need to configure the "Sever Alive" properties.
session.setServerAliveInterval(5000); // Check if server is alive every 5 seconds
session.setServerAliveCountMax(5); // Disconnect after 5 Server Alive checks did not receive a response.

com.jcraft.jsch.JSchException: timeout: socket is not established

I am trying to upload a file to a server (with java) where I have an acount and the SFTP connection stopped working (for a timeout problem I guess). I want to know is there a way to reset this connection and get it working. This is the function:
public static void upload(File file, boolean retry) {
try
{
System.out.println("Uplodaing file " + file.getName());
JSch jsch = new JSch();
Session session = jsch.getSession("****", "*****", 22);
session.setPassword("*****");
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setTimeout(5);
System.out.println("Establishing connection");
session.connect(10);
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
if (!retry)
sftpChannel.put(file.getAbsolutePath(), file.getName(),new SystemOutProgressMonitor(), ChannelSftp.OVERWRITE);
else
sftpChannel.put(file.getAbsolutePath(), file.getName(),new SystemOutProgressMonitor(), ChannelSftp.RESUME);
channel.disconnect();
session.disconnect();
}
catch (Exception e)
{
e.printStackTrace();
upload(file, false);
}
}
I know this question is quite old but in case anyone stumbles over it (as I did):
The problem is the connection timeout, which should be in milliseconds. In case OP intended 10 seconds, it should be 10000 here. 10 milliseconds simply isn't enough.

Why does an SFTP connection still exist after the JSCH Channel has been closed?

When the code below has finished running, netstat -a|grep sftp shows an open SFTP connection. It also shows up as an open connection in JProfiler.
channel.isConnected() in the finally block prints false. Any ideas why the connections is not being closed as I'm at a loss?
public static void clean() {
com.jcraft.jsch.ChannelSftp channel = null;
try {
channel = Helper.openNewTLSftpChannel();
channel.connect();
channel.cd(remoteFileDirectory);
List<ChannelSftp.LsEntry> list = channel.ls("*." + fileType);
for (ChannelSftp.LsEntry file : list) {
String fileName = file.getFilename();
DateTime fileDate = new DateTime(parseDateFromFileName(fileName));
//if this file is older than the cutoff date, delete from the SFTP share
if (fileDate.compareTo(cleanupCutoffdate) < 0) {
channel.rm(fileName);
}
}
} catch (Exception exception) {
exception.printStackTrace();
} finally {
if (channel != null) {
channel.disconnect();
System.out.println(channel.isConnected());
}
}
}
Adding openNewTLSftpChannel() below:
public static ChannelSftp openNewSftpChannel(String privateKeyFileName, String password, String username, String host, int port)
throws ConfigurationErrorException {
JSch jsch = new JSch();
File sftpPrivateFile = new File(privateKeyFileName);
Channel channel;
try {
if (!sftpPrivateFile.canRead()) {
throw new ConfigurationErrorException("File access error: " + sftpPrivateFile.getAbsolutePath());
}
jsch.addIdentity(sftpPrivateFile.getAbsolutePath(), password);
Session session = jsch.getSession(username, host, port);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
channel = session.openChannel("sftp");
} catch (JSchException jschException) {
throw new ConfigurationErrorException("File access error: " + sftpPrivateFile.getAbsolutePath());
}
return (ChannelSftp) channel;
}
If you take a look at the JSCH examples for SFTP you'll see how the session is terminated:
//setup Session here
...
session.connect();
...
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
...run sftp logic...
//close sessions here
sftpChannel.exit();
session.disconnect();
You'll notice that there are two parts to the connection and disconnection; the Session object and the Channel object.
In my code I use the Session object to set my authentication information, and the Channel object to execute the sftp commands I need.
In your instance, you're creating the Session object in your openNewSftpChannel method, but it is never closed, hence your session stays alive.
For further context, check out the examples.
Robert H is correct, you need to exit your channel and disconnect your session. I wanted to add that the session exists even when the channel has been closed. Since you create your session within a try block inside a method, it seems you have lost your session, but you can get it back using 'getSession' on your sftpChannel channel.
You can change your finally block to this:
} finally {
if (channel != null) {
Session session = channel.getSession();
channel.disconnect();
session.disconnect();
System.out.println(channel.isConnected());
}
}

Categories