#1489 PR merged: Tweak how ssh user is copied in usr/share/rear/rescue/default/500_ssh.sh

Labels: enhancement, fixed / solved / done

N3WWN opened issue at 2017-09-12 19:05:

This PR was originally included in my YUM PR, but I at the request of @jsmeix , I pulled it out and am submitting it separately.

In my testing, I would see multiple passwd entries created if the string 'ssh' occurred in more than just the sshd daemon user's entry. While this didn't actually break anything, these tweaks should make it cleaner.

jsmeix commented at 2017-09-14 09:18:

@schlomo in
https://github.com/rear/rear/pull/1489#pullrequestreview-62333816
you wrote that in rescue/default/500_ssh.sh

... we check for $1$ in the ssh password
which is probably not working any more.
Probably better to check for $?$ or so
to catch all encryption formats.

I am afraid I do not understand what that means.
In particular I do not understand what '$1$' or '$?$' stands for.
Apparently this seems to be really basic knowledge
that everybody "just knows" - except me :-(
and no comment explains what that code is about :-((
My blind guess is that '$1$' is perhaps meant to detect
if $SSH_ROOT_PASSWORD is already encrypted but
e.g. my SLES11 /etc/shadow password entries look like

...:$2y$...
...:$2a$...

so that neither '$1$' nor '$?$' seem to match - but I could be
totally wrong because I do not understand what goes on here.

N3WWN commented at 2017-09-14 15:02:

@jsmeix
Looks like your SLES11 has at least one more encryption method (or variant) than my CentOS7 box 😁

From crypt(3):

   The glibc2 version of this function supports additional encryption algorithms.

   If salt is a character string starting with the characters "$id$" followed by a string terminated by "$":

          $id$salt$encrypted

   then instead of using the DES machine, id identifies the encryption method used and this then determines how the rest of the password string is interpreted.  The following values of id are supported:

          ID  | Method
          ─────────────────────────────────────────────────────────
          1   | MD5
          2a  | Blowfish (not in mainline glibc; added in some
              | Linux distributions)
          5   | SHA-256 (since glibc 2.7)
          6   | SHA-512 (since glibc 2.7)

   So $5$salt$encrypted is an SHA-256 encoded password and $6$salt$encrypted is an SHA-512 encoded one.

   "salt" stands for the up to 16 characters following "$id$" in the salt.  The encrypted part of the password string is the actual computed password.  The size of this string is fixed:

   MD5     | 22 characters
   SHA-256 | 43 characters
   SHA-512 | 86 characters

   The characters in "salt" and "encrypted" are drawn from the set [a–zA–Z0–9./].  In the MD5 and SHA implementations the entire key is significant (instead of only the first 8 bytes in DES).

If we have extglob enabled (i.e. shopt -s extglob), I can match DES, MD5, Blowfish and SHA with the following:

# Set the SSH root password; if pw is hashed just copy it otherwise use openssl (for backward compatibility)
if [[ "$SSH_ROOT_PASSWORD" ]] ; then
    case "$SSH_ROOT_PASSWORD" in
    \$[0-9]?([a-z])\$*) echo "ALREADY ENC:  root:$SSH_ROOT_PASSWORD:::::::" ;;
    *     ) echo "NOT ENC:  root:$(echo $SSH_ROOT_PASSWORD | openssl passwd -1 -stdin):::::::" ;;
    esac
fi

I don't see any format restrictions, but going off the of what we know (single digit or single digit+single char), I tested the following successfully:

  1. SSH_ROOT_PASSWORD='unencryptedpasswd' # pass -> detected as unencrypted
  2. SSH_ROOT_PASSWORD='$1$encryptedpasswd' # pass -> detected as encrypted
  3. SSH_ROOT_PASSWORD='$6$encryptedpasswd' # pass -> detected as encrypted
  4. SSH_ROOT_PASSWORD='$2a$encryptedpasswd' # pass -> detected as encrypted
  5. SSH_ROOT_PASSWORD='$2az$encryptedpasswd' # pass -> detected as unencrypted because of the extra char in the crypt ID

This may not adhere to the coding standards of the project as I just whipped up this test, but it may serve as a good start. We could add a comment directing folks to check out the crypt(3) man page, too.

jsmeix commented at 2017-09-15 10:35:

@N3WWN
many thanks for your explanation in
https://github.com/rear/rear/pull/1489#issuecomment-329510764

If you like could you do another pull request to enhance it
so that it also works for more encryption methods?

jsmeix commented at 2017-09-15 10:39:

@N3WWN
regarding "If we have extglob enabled" see

$ find usr/sbin/rear usr/share/rear/ | xargs grep 'extglob'
usr/sbin/rear:# The extglob shell option enables several extended pattern matching operators.
usr/sbin/rear:shopt -s nullglob extglob

i.e. ReaR has extglob enabled
and nullglob which requires to be careful,
e.g. see my commenta bout 'nullglob' in
prep/NETFS/default/070_set_backup_archive.sh


[Export of Github issue for rear/rear.]