Resolve go language ssh client password expiration issue

  • 2020-10-31 21:47:32
  • OfStack

go ssh package does not support the password expired reset function!

Version: go v1.14.1 linux installed.

ssh package: git clone https: / / github com/golang/crypto git

It was downloaded around April 1st, 2020.

First, describe the phenomenon of the problem and the reasons why it must be solved:
In normal ssh clients, if the password is expired or does not comply with the password rules, the terminal will prompt 1 paragraph when logging in, such as expired. You will then be prompted to enter your old password at the terminal, enter a new password, and confirm it to complete the password change.

However, with this ssh package, execute ssh.Dial If the password is expired, this function will return an error without giving you a chance to change the new password.

And that's exactly what my project needs. Because in my project, the server pushes the script to a device through the ssh client, in which there is a script to change the password, in order to change the password of the target device. If the password for the device does not expire, I can also log in with the old password and execute the script to change the password. However, if the password is expired, I will be prompted to change it when I log in to ssh. If the go language fails, I will not be able to change the password successfully. Other languages, or terminal software, have the ability to reset passwords. I think this is probably why the go language is too young to be fully functional (at least I haven't found one).

In addition, the solution and principle are as follows:

I modified the ssh package myself client_auth.c File solved.

The specific modification is to add a custom authentication method, changePassword, to replace the "password" authentication, and to implement the specified Auth method and method method. These two methods are required in the ssh package. Only when these two methods are implemented, can the auth interface be implemented and can the ssh server be connected as one configuration of ssh client. I could have just changed the code for "password", but I didn't dare to move, so I rewrote one and kept it. ~ ~ ~ ~

Several of the same types have previously been defined in ssh, representing authentication methods, including "password "," publickey "," keyboardinactive", and "gcc". These are all in accordance with the ssh protocol. The reference document is rfc4252.

The normal ssh connection USES the authentication method of "password" to enter the user name and password, including the password expiration needs to be reset, which is also the authentication method. Each authentication method implements the interface Auth, which sends the password and then receives the response from the server. The problem is with this implementation! If the password is expired, the server will respond to one change password, which is specified in rfc4252.

But go's ssh packet doesn't recognize this response! Return failure directly! This is so lame!
Therefore, my own authentication method, changePassword's Auth implementation, has added the recognition of this response, and still sends the message containing the old and new password according to the format of the subsequent message as specified in the rfc4252 document. When the server receives this message, it will reset to the new password. This completes the function I need.

Talk about the course of exploration:

1.1 At first, I didn't think the go language would be so boring. It is surprising that it did not implement functions according to rfc. But there is no way, just start to read the source package. There is no article on the Internet to explain, are relying on their own 1 little bit of groping hard scalp to see.

2. I didn't look at rfc when I first looked at the code. I don't know how he got those authentication methods, and which authentication method should he take when the password expires. I think there is one keyboardinteractive which seems to be the correct answer, because both the old and new passwords need to be entered, and there is also confirmation. I think it should be this authentication. So I do this, but I still get all kinds of errors, and I want to give up 1 degree. As a result, I accidentally saw comments in the code and mentioned rfc4252. After looking at it for 1 time, I found that many functions were implemented in accordance with this. Then I found that the password expired with the authentication of password, not keyboardinteractive. ~ ~ ~ ~

conclusion


Related articles: