"Received message is too long" when connecting to SFTP server with JSch - java

I wanted to download files using FTP from a server. I can do it properly through command-line and want the same thing using Java. This is my code
session = jsch.getSession(user, server, 22);
session.setPassword(pass);
session.setTimeout(10000);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
**channel.connect();**
channel.disconnect();
session.disconnect();
Problem is when the channel is connecting i.e channel.connect and I am getting an error:
com.jcraft.jsch.JSchException: 4: Received message is too long: 1619214428
at com.jcraft.jsch.ChannelSftp.start(ChannelSftp.java:242)
at com.jcraft.jsch.Channel.connect(Channel.java:200)
at com.jcraft.jsch.Channel.connect(Channel.java:144)
at com.cca.processor.FTPProcessor.main(FTPProcessor.java:54)
Caused by: 4: Received message is too long: 1619214428
at com.jcraft.jsch.ChannelSftp.start(ChannelSftp.java:214)
... 3 more

As you commented yourself, you cannot connect with any SFTP client.
So there's nothing wrong with your JSch/Java code.
The error occurs only after an SSH authentication, when an SFTP session is starting.
It's typically caused by some startup shell script printing a message, and thus breaking the SFTP protocol.
The number in the error (1619214428) is then the first four characters in the message interpreted as a 32-bit number.
But in your case it does not really seem to be a readable text (were it, WinSCP would display the readable form too). The number stands for ‭6083405C‬ in hexadecimal notation, what is <.(# (where the dot stands for a character outside of ASCII table).
See also WinSCP documentation for the error message:
https://winscp.net/eng/docs/message_large_packet
Still, it's the server that is broken, not your code. You should contact your server administrator or review startup shell scripts of your account.
Though you claim you were able to use FTP from command-line and WinSCP. So maybe you should actually use FTP (or better FTPS), not SFTP. You cannot use JSch for FTP (or FTPS). You can use Apache Commons FTPClient for example.

Related

Java program to get a file on SFTP server using public key authentication and proxy server

In our project, we need to get a file from external SFTP server using public key authentication. I have searched online but didn't any example for mentioning proxy server routing since it's required as per company's policy
We are using the following command on Unix server to get the file but we want to use java program to implement this functionality
sftp -v -oIdentityFile=/home/intusr/.ssh/id_rsa -oProxyCommand="/usr/bin/corkscrew 11.555.66.22 4444 %h %p" user#transmit.com:stage/filedir/
Your help will be appreciated. Best resource I have found so far is
https://kodehelp.com/java-program-for-uploading-file-to-sftp-server/
The most commonly used Java SSH library is JSch, which supports both public key authentication and HTTP proxy:
How to transfer a file using a proxy with JSch library
Can we use JSch for SSH key-based communication?
Combined, the code would be like:
JSch jsch = new JSch();
jsch.addIdentity("/path/to/private/key");
Session session = jsch.getSession("user", "host");
ProxyHTTP proxy = new ProxyHTTP("proxy", proxyport)
proxy.setUserPasswd("proxyusername", "proxypassword");
session.setProxy(proxy);
session.connect();
For downloading a file, see:
How to retrieve a file from a server via SFTP?
You will have to verify server host key as well.

Opening ChannelSftp channel to transfer the file after using sudo [duplicate]

I am using JSch in a Java client to connect to a remote server and get some files using SFTP. The following code has been working fine for me: -
JSch ssh = new JSch();
JSch.setConfig(FileTransferConstants.STRICT_HOST_KEY_CHECKING, FileTransferConstants.NO);
Session session = ssh.getSession(userName, host, port);
session.setPassword(password);
session.connect();
Channel channel = session.openChannel(FileTransferConstants.SFTP);
channel.connect();
ChannelSftp sftp = (ChannelSftp) channel;
sftp.cd(remoteDirectoryPath);
sftp.lcd(localDirectoryPath);
sftp.get(remoteDirectoryPath + remoteFileName, remoteFileName);
The problem is that there has now been a change of site policy. I am no longer permitted to log on directly as this user (userName above). I must first log on as my personal user and then su into the user that has access to the files I want to SFTP.
I don't think there is anyway I can refactor the above code to achieve this and so I have started looking at using a shell or exec channel instead. I have had little success so far and cannot seem to find any examples on the web, so I would be very grateful for any advice or pointers in the right direction. Many thanks.
I do not think you can do this directly with JSch. But with some modification of its code, it's probably doable.
Note that my answer assumes that the server is *nix-based (what is backed by your reference to su) and uses OpenSSH SFTP server.
You have to open SSH "exec" channel, to execute something like:
sudo /bin/sftp-server
But on top of that channel, you need to build the ChannelSftp instance, not ChannelExec.
So you will need to implement Session.openChannel-like method, that will open exec channel, but create ChannelSftp for it.
For some background, see how it's possible to do sudo with WinSCP SFTP client.
Note that while the FAQ claims, that you won't be able to use password for the sudo, that's true for WinSCP. But as you have a full control of the session with JSch, you may be able to feed the password to sudo.
For that you might override the ChannelSftp.start() to write the password to the channel input, before starting the actual SFTP session.
You still need the requiretty option be off, as the SFTP cannot work with TTY.
For general considerations when automating operations using a different/root account, see:
Allowing automatic command execution as root on Linux using SSH

How to get Welcome message after connecting to SSH using JSch

When I connect to SSH using PuTTY, I get the following message as given below.
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-98-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
deb#ubuntu:~$
Similarly, when I use JSch library to connect, I should also get the same message in Java. Please help me about how to get this. I provide below my code details.
public String connect() {
String errorMessage = null;
try {
sesConnection = jschSSHChannel.getSession(userName, ipOrHostName, PORT);
sesConnection.setPassword(password);
sesConnection.setConfig("StrictHostKeyChecking", "no");
sesConnection.connect(TIMEOUT);
//After connecting, I should get the welcome message
} catch (JSchException jschX) {
errorMessage = jschX.getMessage();
}
return errorMessage;
}
I want to get the welcome message from a unix system before executing the commands in JSch. Please help about how to get it.
The message you are seeing is simply printed on a shell output.
That does not go well with automatic its reading and executing commands.
I general to automate a command execution, you correctly plan to use SSH channel "exec" (ChannelExec in JSch). But that channel won't give you the message.
You would have to use "shell" channel (ChannelShell in JSch). But that channel is intended for implementing an interactive shell session. Not to automate command execution and not for parsing command output. Particularly in the context of your question, there's no realiable way to find out the end of the "welcome message". You would have to read the output line by line, until you get the prompt ("deb#ubuntu:~$").
Or, if your use case allows that, you can use ChannelShell to get the message and then use ChannelExec to execute the commands.
You better talk to the server administrator to make the information you need available using a different API (like using SSH2_MSG_USERAUTH_BANNER, or even other way).
See my answer to SSH MOTD per user to understand the different ways how the server can provide the "welcome message". Had the server used SSH2_MSG_USERAUTH_BANNER, you could use UserInfo.showMessage to capture the message. See also How to read the SSH key-sig pair banner (for generating SSH password) after connecting to host in Java?

JSch scp without known_host file and with StrictHostKeyChecking

I am trying to copy some files from a Windows machine to a Linux machine, which is working fine with JSch so far. I can copy files using StrictHostKeyChecking no or I need to have the known_host file from the Linux machine I copy to. I am using the code for a Java project which should be able to send files automatically to (unknown) Linux machines. I got the username, password, IP and the publickey for the machine. Is there any way to authenticate without the known_host file and via the publickey? Because of security issues I do not want to switch StrictHostKeyChecking to no but then I get "com.jcraft.jsch.JSchException: UnknownHostKey"
FileInputStream fis = null;
JSch jsch = new JSch();
//jsch.setKnownHosts("");
jsch.addIdentity("D:\\Uni\\Arbeit\\remote_id_rsa");
Session session=jsch.getSession(user, host, 22);
session.setPassword(password);
//session.setConfig("StrictHostKeyChecking", "no");
session.connect();
That does not make sense. Either you know the host public key and you can verify it either using the known_host file or programmatically using:
public void KnownHosts.add(HostKey hostkey, UserInfo userinfo)
(You can access the instance of KnownHosts using Session.getHostKeyRepository())
For more details, see How to resolve Java UnknownHostKey, while using JSch SFTP library?
Or you do not know the host public key, and then you cannot create a secure connection (and the StrictHostKeyChecking=no is your only option).
See my article about verifying the host key to understand, what is it about, and its importance. The article is about WinSCP client, but it's valid in general for any SSH client.

JSch Session Connecting

Hi I am trying to connect via ssh tunneling to a database on a server, but I can't even get the Jsch session to connect. I am attempting to do this in GWT as part of my back-end code. So this is in the Implementation part of the server side code.
I am not that familiar with servers in general. Typically in terminal I type:
ssh -x username#xxxxx.xxx.edu
Then I am prompted for my password and I enter the password and then I am in.
So in java my code is as follows:
String host="xxxxx.xxx.edu";
String user="username";
String password="password";
Session session= null;
try{
//Set StrictHostKeyChecking property to no to avoid UnknownHostKey issue
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
session=jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig(config);
session.connect();
}
I've double checked the username and the password and the host string and they are all what I use in terminal successfully.
The error I get on the 'session.connect()' line is as follows: (scroll right to see whole error)
com.jcraft.jsch.JSchException: java.security.AccessControlException: access denied (java.net.SocketPermission xxxxx.xxx.edu resolve)
at com.jcraft.jsch.Util.createSocket(Util.java:341)
at com.jcraft.jsch.Session.connect(Session.java:194)
at com.jcraft.jsch.Session.connect(Session.java:162)
at com.front.server.GameServiceImpl.createGame(GameServiceImpl.java:39)
Is there something I am missing? Is this not identical to what I do in terminal to sign in via ssh? I have also tried prepending 'ssh://' to the host string as well but to no avail.
Thanks in advance!
I figured out that there is no problem with the code above. I copied/pasted it into a simple java main and it worked fine. It appears there is something wrong with putting that same code in GWT back-end.
According to the exception message, it seems that the problem has not come from JSch.
Refer to Security and Permissions on java.sun.com:
All applets and any applications invoked with a security manager must
be granted explicit permission to access local system resources apart
from read access to the directory and its subdirectories where the
program is invoked. The Java platform provides permissions to allow
various levels of access to different types of local information.
,and see SocketPermission section.

Categories

Resources