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

JSch does not support to extend or replace "UserAuthNone" class #293

Closed
MatusSkerlik opened this issue Mar 23, 2023 · 6 comments
Closed

Comments

@MatusSkerlik
Copy link

Greetings,

it is possible to change implementation of "userauth.none" in config throught "UserAuth" interface,
but when it is actually done, it will throw cast exception.

Error occurs after server responds to auth none request, when JSch want to get an array of supported auth methods.

smethods = ((UserAuthNone) ua).getMethods();

There is a cast of class that implemented UserAuth to UserAuthNone , which is package private class, so it cannot be extended.

I propose to add try-catch block for this cast or create new interface (eg. IUserAuthNone), which would add getMethods() method to interface definition, so it can be implemented by third party.

Thanks,
Matus

@norrisjeremy
Copy link
Contributor

I'm not sure I understand the use case for overriding userauth.none, can you provide more details for why you require this functionality?

@MatusSkerlik
Copy link
Author

MatusSkerlik commented Mar 23, 2023

Of course,

when JSch used against Palo Alto 850 devices, it will fail to auth.

It is due to SocketTimeoutException (exactly at UserAuthNone:83) , immediately after "SSH_MSG_USERAUTH_REQUEST(50)" with method "none" is sent by JSch.

This device do not respond for this kind of request, which is not handled by JSch.
According to RFC 4252, page 7

5.2. The "none" Authentication Request

   A client may request a list of authentication 'method name' values
   that may continue by using the "none" authentication 'method name'.

   If no authentication is needed for the user, the server MUST return
   SSH_MSG_USERAUTH_SUCCESS.  Otherwise, the server MUST return
   SSH_MSG_USERAUTH_FAILURE and MAY return with it a list of methods
   that may continue in its 'authentications that can continue' value.

   This 'method name' MUST NOT be listed as supported by the server.

which implies that this is device specific issue.

It is also possible to log in to this device (authenticate and open shell channel) through putty, which implies that it is possible to login to device with different approach (putty skips auth none ? i dont know).

That is why we want to rewrite UserAuthNone class logic to catch SocketTimeoutException and return false for method start(), which will result in continuation of auth logic with methods defined in "PreferredAuthentications" (JSch config).

@norrisjeremy
Copy link
Contributor

norrisjeremy commented Mar 23, 2023

What if you try using the enable_auth_none config option that we added in the 0.2.7 release?
This instructs the UserAuthNone class to skip sending the none type SSH_MSG_USERAUTH_REQUEST message.
You can set enable_auth_none to no.

@MatusSkerlik
Copy link
Author

We are fully aware of this option, but when applied, there is lost of compatibility with Dell PowerConnect 5448.
This device will send SSH_MSG_USERAUTH_FAILURE for every auth method, if there is no auth none as prerequisite.

In our context, it is not possible to determine, what device we are dealing with beforehand.
So we cannot do device specific JSch config.

We need to catch SocketTimeoutException, and it would be best to catch it directly within UserAuthNone (we would do wrapper around UserAuthNone or extend UserAuthNone and rewrite start(), both options not currently available).
When catch is made, we would return false; which would result in continuation of trying auth methods.

There are multiple solutions for this:

  1. create public interface for UserAuthNone like IUserAuthNone, which would include getMethods() method, rewrite cast in Session#414 to interface.
smethods = ((UserAuthNone) ua).getMethods();
# to
smethods = ((IUserAuthNone) ua).getMethods();
  1. make UserAuth specific children public, so user of library can extend it, this should ensure that cast below would not throw.
smethods = ((UserAuthNone) ua).getMethods();

Is there any specific reason, why UserAuth children are package private ?

We could also just catch SocketTimeoutException from Session.connect.
But with this approach, we will lost track from what read call this exception origin.

Also please note that all UserAuth methods can be rewritten using JSch config, only UserAuthNone cannot be due to cast we talked about.
There is an option to specify custom UserAuthNone class in Jsch config with key 'userauth.none', however, when custom implementation is provided it will fail due to class cast exception in class Session#414.

Please let us know if any of mentioned solution is valid, we would be more than happy to create a pull request.

norrisjeremy added a commit to norrisjeremy/jsch that referenced this issue Mar 25, 2023
@norrisjeremy
Copy link
Contributor

Hi @MatusSkerlik,

I've opened #295 that includes a change to make UserAuthNone public.
Can you confirm if this will cover your use case?

Thanks,
Jeremy

@MatusSkerlik
Copy link
Author

Hi @norrisjeremy ,

I can confirm that changes you made works for us.

I have created simulated ssh server in paramiko where server won't send any response after method auth none is recieved.
Another methods are processed as usual.

After wrapping UserAuthNone class with our own implementation, JSch won't throw !SocketTimeoutException(we catch it in wrapper) but continues to authenticate with methods defined inPreferredAuthentications` config option.

Authentification than can be then successfull at any of these methods, which is what we expected.

We appreciate it, thanks a lot,
Matus

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

2 participants