Dropbears,

I submitted a patch to enhance the dropbear SSH server to handle the Linux-PAM "expired password dialog".  That is, if you ssh into a system running the dropbear SSH server and configured to use Linux PAM and your password is expired, this patch enhances the SSH server so you can change your password while logging in.

I believe this feature will become more important to small devices because of increased security concerns.  Specifically, if a device is created with a default ssh password, it is too easy for an attacker to learn that password and gain access to the device. However, if that password is pre-expired (such as with the `passwd --expire USERNAME` command), the password must be changed before the device can be accessed; that encourages folks to change the password away from the default, so the attackers won't be able to access the device.

For example, California Law SB-327 (https://leginfo.legislature.ca.gov/faces/billTextClient.xhtml?bill_id=201720180SB327) title 1.81.26 ("Security of Connected Devices") paragraph 1798.91.04. (b) (2) states (excerpted): it shall be deemed a reasonable security feature [if] ... the device contains a security feature that requires a user to generate a new means of authentication before access is granted to the device for the first time. That means you need to set or change the password before you can use the device.

A use case is:
1. Someone creates a device which uses the dropbear SSH server, and provisions the device with a username and default password, and administratively expires the password. 2. A user installs the device and tries to use it.  They are required to change its password the first time they attempt to access it. 3. After this point, the attacker cannot access the device with its default password.
Anyway, that's my motivation for making this patch.

This is a refresh of a previous patch discussed on the dropbear mailing list: https://lists.ucc.gu.uwa.edu.au/pipermail/dropbear/2016q2/thread.html in threads titled "dropbear and PAM_NEW_AUTHTOK_REQ" and "[PATCH 1/2] Support changing expired passwords".
This patch is substantially the same as the previous patch.
I did not make the corresponding change to the SSH client because I am not using it.

Here is a code walkthrough to help explain the changes.

The scenario involves:
- A user who invokes the "ssh" command.
- The client "ssh" program.
- The dropbear "ssh" server.
- The Linux PAM implementation.

The sequence is:
1. A user directs their SSH client to login to the dropbear SSH server.
2. The ssh client passes the username and password to the dropbear ssh server in a SSH_MSG_USERAUTH_REQUEST per RFC 4252. 3. The dropbear ssh server response to the client indicates the password is expired.  ==> dropbear is enhanced with a new message for this.   Specifically, return code PAM_NEW_AUTHTOK_REQD means that everything is okay, except the password is expired and must be changed.  Changed code in svr-authpam.c function svr_auth_pam() handles this condition by calling the new send_msg_userauth_chauthtok() function. 4. The SSH client prompts the user for a new password, and sends another SSH_MSG_USERAUTH_REQUEST to the SSH server, this time with the fifth element TRUE to indicate a password change request. 5. The dropbear ssh server changes the user's password, and the ssh connection continues.  ==> dropbear is enhanced to invoke pam_chauthtok ("change password") to handle this request.

This detailed code walkthrough begins at the last step.  Referring to the patched code: - The SSH_MSG_USERAUTH_REQUEST flows into the dropbear SSH server, is decoded partially, and control is passed into svr-authpam.c function svr_auth_pam().
- The client_request_changepw boolean and existing password are read.
- If client_request_changepw==true, the new password is also read.
- Both passwords are stored in the UserData. (This is eventually passed into pamConvFunc() as the appdata_ptr parameter via the call to pam_start(..., pamConv, ...)).
- The pam_start and pam_authenticate functions are called as usual.
- If client_request_changepw==true, we invoke PAM pam_chauthtok() to change the password. The call to pam_chauthtok() does not use the PAM_CHANGE_EXPIRED_AUTHTOK flag, making this an unconditional request. That is, if the SSH client requests a password change, we will definitely call PAM to change the password. - As part of its processing, the pam_chauthtok() function calls back into the srv-authpam.c pamConvFunc() to obtain the new password.  It passes in a PAM_PROMPT_ECHO_OFF message like "Enter new password:". The patch enhances this function to return the new password which it gets from the userData set up by svr_auth_pam(). - If everything goes well, pam_chauthtok takes care of writing that password into the /etc/passwd file.
- If not, PAM error codes are handled correctly.

Notes:
- The unnecessary m_burn(userDatap->passwd, ...) was removed, as it is an alias of svr_auth_pam / password, and cleanup is performed by svr_auth_pam at the cleanup label.  This is where the strdup'd old and new passwords are freed. - The call to PAM pam_start() identifies the service_name of "sshd" which affects the config files PAM uses to process dropbear requests. The /etc/pam.d/sshd config file may need to be changed to tell PAM that the sshd service should be allowed to change passwords.  For example, add an entry in the /etc/pam.d/ config files for the "sshd" service and the "password" type, like this: sshd password include common-password.

- Joseph

Reply via email to