Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Packet corrupt #91

Closed
jnsanders1983 opened this issue Nov 3, 2021 · 23 comments
Closed

Packet corrupt #91

jnsanders1983 opened this issue Nov 3, 2021 · 23 comments

Comments

@jnsanders1983
Copy link

First off I downloaded jsch-0.1.55 from jcraft.com

Background: I have written a Java program that is a GUI use to configure a Cisco telephone router. This is normally done logging into the router using either telnet or ssh. Configuration is done through the terminal.

I have successfully written code using the ChannelExec but it only works once. And I get the Packet corrupt on the next command.

In this application I do not store user credentials for security reasons. So the proposed workaround of recreating the session is not ideal because I do not want to keep prompting the user to enter credentials, I only want to prompt for credentials when a real time out occurs, and in my opinion not being able to send commands back to back with in milliseconds of each other is not a session timeout.

Below is the stack trace and my example code. I have done the initial setup in my class constructor. And I create the Session in a separate method when I prompt the user for credentials.

com.icraft.isch.JSchException: Packet corrupt
at com.jcraft.jsch.Session.start discard (Session.java:1067)
at com.jcraft.jsch.Session. read (Session. java: 937)
at com.jcraft.jsch.Session. connect (Session.java: 309)
at gov.jdaccs. comm.SecureShellChannel. sendCommand (SecureShellChannel.java: 122)
at gov. jdaccs. views. RouterPanelView$3$1. doInBackground (RouterPanelView.java: 239)
at gov. jdaccs. views. RouterPanelView$3$1. doInBackground (RouterPanelView.java: 1)
at javax.swing.SwingWorker$l.call(Swingworker.iava:295)
at java.util. concurrent. FutureTask. run (FutureTask java: 266)
at javax. swing.SwingWorker.run (SwingWorker.java: 334)
at java.util. concurrent. ThreadPoolExecutor, runworker (ThreadPoolExecutor. java: 1149)
at java.til. concurrent-ThreadPoolExecutorsworker.run(IhreadPoolExecutor.java:624)
at java.lang.Thread. run (Thread. java: 748)

System.out.println("String Builder") ;
StringBuilder output = new StringBuilder();

System.out.println("Create Channel")
channel = session. openChannel("exec”);
System.out.println( "Sending command: + command) ;
( (ChannelExec) channel) .setCommand (command) ;
InputStream commandOutput = channel. getInputStream();
channel. connect ();

int readByte = commandOutput. read () ;

while (readByte != Oxffffffff)
{
output. append ( (char) readByte):
readbyte = commandOutput. read() ;
}

// close Channel	
channel. disconnect () ;

// close Session
session.disconnect () ;
return output. tostring();

}

@norrisjeremy
Copy link
Contributor

Hi @jnsanders1983,

Have you confirmed this occurs with the latest version of this fork (0.1.69) versus the 0.1.55 JCraft release?

Thanks,
Jeremy

@jnsanders1983
Copy link
Author

I have not yet. I just downloaded the source for it about an hour ago. I am a bit "old school" I started programming in 2002. But I have been programming for the last 20 years. I notice that this uses maven to build the project and I am not familiar with maven and how to build it with maven. I am using Eclipse IDE and a rather old version of it, I believe 3.8. This is for another project we have that uses the perc ultra virtual machine and 3.8 is the only thing compatible. Anyhow as soon as I figure out how to build it and jar it up I will be able to confirm.

@norrisjeremy
Copy link
Contributor

Hi @jnsanders1983,

If you want to self-compile, you will need to use Java 16 or newer (the result Jar will still be compatible with Java 8+).
To compile it, you can simply execute the following command the command line:

./mvnw clean package

This jar file will be output into the target sub-directory.

Thanks,
Jeremy

@jnsanders1983
Copy link
Author

@norrisjeremy

I am trying to add the maven project to Eclipse, and I installed maven, then imported in the project. but this error came up:

Project build error: Non-resolvable parent POM: Failure to transfer org.sonatype.oss:oss-parent:pom:9 from http://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. Original error: Could not transfer artifact org.sonatype.oss:oss-parent:pom:9 from/to central (http://repo.maven.apache.org/maven2): Failed to transfer http://repo.maven.apache.org/maven2/org/sonatype/oss/oss-parent/9/oss-parent-9.pom. Error code 501, HTTPS Required and 'parent.relativePath' points at wrong local POM pom.xml /jsch-jsch-0.1.69 line 400 Maven pom Loading Problem

Not sure what it means and how to resolve it.

@norrisjeremy
Copy link
Contributor

Hi @jnsanders1983,

Unfortunately I am not familiar with how Eclipse works. You might have to hunt around on Google or Stack Overflow to figure out why that is happening.

Thanks,
Jeremy

@jnsanders1983
Copy link
Author

@norrisfjeremy

It would actually just save me some time if I could be pointed to the location of a pre-complied jar file to use. When I looked in this repo all I found was the source code.

@norrisjeremy
Copy link
Contributor

Hi @jnsanders1983,

You can find the published JAR file in the Sonatype repository here: https://search.maven.org/artifact/com.github.mwiede/jsch/0.1.69/jar (just click the Downloads button in the right corner and select jar).

Thanks,
Jeremy

@jnsanders1983
Copy link
Author

@norrisjeremy

I downloaded the published JAR and included it in my libraries (removed the old one) I ran the program and tried to login and I didn't even get past connect();

com.jcraft.jsch.JSchException: Algorithm negotiation fail
at com.jcraft.jsch.Session.receive_kexinit(Session.java:595)
at com.jcraft.jsch.Session.connect(Session.java:325)
at gov.jdaccs.comm.SecureShellChannel.connect(SecureShellChannel.java:86)

@jnsanders1983
Copy link
Author

here is my source code for the portion that I wrote
SecureShellChannel.txt
.

@norrisjeremy
Copy link
Contributor

Hi @jnsanders1983,

The Cisco equipment you are connecting to likely only supports legacy crypto algorithms that are disabled by default in our forked version of JSch.
If you can run ssh -vv against the equipment manually, that should provide output of the various crypto algorithms it supports, and you can adjust JSch to enable the required algorithms.

Thanks,
Jeremy

@jnsanders1983
Copy link
Author

@norrisjeremy

here is the portion of code that my Login Window calls when the used enters credentials and clicks the connect button.

login.btn_ConnectAddActionListener(new ActionListener() {

		public void actionPerformed(ActionEvent e)
		{
			String tempU = login.getUsername();
			char[] tempP = login.getPasswd();

			try
			{
				// Create all three sessions
				opsMain.createSession(tempU, tempP);
				opsBackup.createSession(tempU, tempP);
				radar.createSession(tempU, tempP);

				
				// TODO these might not be needed
				// Connect all three sessions
				opsMain.connect();
				opsBackup.connect();
				radar.connect();
			}
			catch (JSchException jse)
			{
				// Erase tempP
				Arrays.fill(tempP, '0');
				login.dispose();

				String msg = jse.getMessage();

				// Case "No Network connection"
				if (msg.compareToIgnoreCase("java.net.SocketException: Network is unreachable (connect failed)") == 0)
				{
					msg = "Network is unreachable, connect failed!";
				}
				// Case "Auth fail"
				else if (msg.compareToIgnoreCase("Auth fail") == 0)
				{
					msg = "Invalid username or password!";
				}

				displayDialog(msg, "Error", JOptionPane.ERROR_MESSAGE);
				jse.printStackTrace();
			}
			finally
			{
				// Erase tempP
				Arrays.fill(tempP, '0');
				login.dispose();
			}
		}
	});

@jnsanders1983
Copy link
Author

@norrisjeremy

Thanks for the information. This Cisco Router doesn't really support commands like that. typing in ssh -vv just gets me an error. I will probably have to do some research or open a ticket with Cisco.

@jnsanders1983
Copy link
Author

@norrisjeremy

from my educational background in Security +. The authentication/encryption algorithm should be chosen based on what the end point is capable of. Example when you attempt to make a connection the endpoint will respond with which algorithms it can use. Then the software should pick the most secure one to use. Since this authentication failed I would say that your software is not following the security model and you all should look into changing this. Just leaving it up to someone to edit the code themselves to make it use whatever one they need it to and not the one you all chose it to. It’s should be something negotiable between the two end points not just sorry I only do this one and access denied.

@jnsanders1983
Copy link
Author

@Hr0bar, since you author this post (#59). Could you please review this thread and see if you can shed any light on my problem. I am using a Cisco Router running the Cisco IOS. I wrote my code using the original JSch and I was able to log in and issue commands, but not able to issue multiple commands with out recreating the connecting. I updated to this branch of JSch and now I can't even negotiate a connection. I was hoping for some help or suggestions.

@Hr0bar
Copy link

Hr0bar commented Dec 14, 2021

Hi @jnsanders1983 two things:

  • I think norrisjeremy wants you to run "ssh -vv" from some linux box against the Cisco router, so "ssh -vv CISCO_ROUTER_IP_ADDRESS" with which you can determine which algos the router uses and then configure this new jsch for it based on the configuration info in this repository. Shouldnt be hard to support this legacy Cisco IOS algos with this new jsch.

  • For our use case, we reverted back to old 0.1.55 because we are using it to connect to hundreds of thousands of Network devices (not only Cisco IOS, but 50+ vendors like Aruba, Fortinet and others that went bankrupt before 2010) and it was simply impossible to configure it properly to support all of these old network devices, so this new jsch wasnt a "Drop in replacement" as the description suggests. Always some user reported that it was breaking stuff for him, on some exotic old device.

@jnsanders1983
Copy link
Author

@Hr0bar Thanks for the quick reply. I am really new to this concept of JSch and setting it all up. I got it to work on a Ubuntu laptop to raspberry pi. I am literally just using this to send command to configure the Cisco Router. Adding removing users and setting up pots and voip lines. So I believe I just need the plain function of sending commands and getting returned output.

I really didn't do any configuration other than what I have in the code I attached to the post. And I couldn't find any specific examples that relate to what I am trying to do. Could you be a little more specific on configuration process?

@jnsanders1983
Copy link
Author

@Hr0bar sorry to be more specific I got this working on 0.1.55 but I had issues having to send multiple commands sequentially. I would get a Packet Corrupt error on second command. Which lead me to believe I would have to recreate the connection for every command which would be not ideal and excessive.

@Hr0bar
Copy link

Hr0bar commented Dec 14, 2021

That seems like a different issue than algorithm negotiation fail, according to https://stackoverflow.com/questions/27838523/jschexception-packet-corrupt this happens when you try to open multiple same sessions in your code.

Same:
https://stackoverflow.com/questions/12837036/jsch-how-to-reuse-a-session

@jnsanders1983
Copy link
Author

@Hr0bar, Thank you for the articles... So I am assuming there is no fix and no way to reuse the session, and I will have to recreate the session/ or a new session. Unless I want to dive into the source code and find a creative way to reuse the session or increment the packet number.

@Hr0bar
Copy link

Hr0bar commented Dec 14, 2021

No, it should work. We simply do:

  • send command to outputstream, so like "show running-config\n"
  • wait until we receive "# \z" regular expression (For Cisco IOS), which means command finished and we are again at ROUTER_HOSTNAME# prompt
  • send another command to outputstream

You shouldnt be doing channel. disconnect () ; or session.disconnect () ; in between commands. It needs to stay open.

@jnsanders1983
Copy link
Author

@Hr0bar OK, Thanks, I thought I had tried that before... but I'll give it another go.

@jnsanders1983
Copy link
Author

jnsanders1983 commented Dec 16, 2021

@Hr0bar,

What kind of channel are you using to send command? You said you where using a outputstream. I am using a ChannelExec which I believe according to the code I am using sends the command on connect. See below.

channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
InputStream commandOutput = channel.getInputStream()l
channel.connect();

Then I wait for the output to be returned before reading it.

If there is a better way of doing this I'd like to know. It seems like me that in order to send more commands I would have to call the channel.connect(), which seems like that would through an error if it is already connected. Is there another method to send a command that does not involve the setCommand() ?

to be clear these commands are not send from a terminal, but are the result of user actions via a GUI.

@Hr0bar
Copy link

Hr0bar commented Dec 17, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants