3

I am trying to generate a hashed password as in /etc/shadow file, using bash script. The user is prompted for the password which is saved in a variable PSWD. I have extracted the Hash and the salt value from the /etc/shadow file and saved them in a variables HVAL and SVAL respectively.

Now in order to generate a hashed password using Password and the Salt value, I need to use command given below (Reference):

$ perl -e 'print crypt("password","\$6\$salt\$") . "\n"'

In the above command, I must replace "password" with the $PSWD variable, "6" with $HVAL and "salt" with $SVAL variable.

I've tried exporting above variables and replacing them in the perl command, as shown below, but it was totally messed up.

perl -e 'print crypt("$ENV{"PSWD"}","\$$ENV{"HVAL"}\$$ENV{"SVAL"}\$") . "\n"'

What will be the corrections?

3
  • @StéphaneChazelas- I've used the backticks while assigning the output to a variable, still it is not working.CommentedAug 2, 2015 at 6:46
  • Yes, there's also the problem of the quotes, you'd need "$ENV{\"VAR\"}" though "$ENV{VAR}" would be enough, see my answer.CommentedAug 2, 2015 at 6:51
  • If the password is being changed: The hash should be re-generated. If only testing the password then ok.
    – user79743
    CommentedAug 3, 2015 at 13:10

2 Answers 2

6

The problem is with your double quotes. Here you don't need to quote those hash keys as they are simple identifiers. From perldoc perldata:

In fact, a simple identifier within such curlies is forced to be a string, and likewise within a hash subscript. Neither need quoting. Our earlier example, $days{'Feb'} can be written as $days{Feb} and the quotes will be assumed automatically. But anything more complicated in the subscript will be interpreted as an expression. This means for example that $version{2.0}++ is equivalent to $version{2}++, not to $version{'2.0'}++.

So:

perl -le 'print crypt($ENV{PSWD},"\$$ENV{HVAL}\$$ENV{SVAL}\$")' 

If you're using it inside backticks, you'd need to double your backslashes as in:

var=`perl -le 'print crypt($ENV{PSWD},"\\$$ENV{HVAL}\\$$ENV{SVAL}\$")'` 

Best is to use the $(...) form of command substitution instead:

var=$(perl -le 'print crypt($ENV{PSWD},"\$$ENV{HVAL}\$$ENV{SVAL}\$")') 
1
  • A comment that the vars are passed in the environment to avoid being seen in ps -ef will help understand the command concept.
    – user79743
    CommentedAug 3, 2015 at 13:14
0

The sequence to get to the correct quote starts with the original command:

perl -e 'print crypt("password","\$6\$salt\$") . "\n"' 

Let's add some space:

perl -e 'print crypt(" password ","\$ 6 \$ salt \$") . "\n"' 

Let's change the vars to their equivalents:

perl -e 'print crypt(" $ENV{PSWD} ","\$ $ENV{HVAL} \$ $ENV{SVAL} \$") . "\n"' 

The equivalents should not be quoted, as in quotes they fail:

perl -e 'print "$ENV{PSWD}" . "\n"' # correct. perl -e 'print "$ENV{"PSWD"}" . "\n"' # fail. 

And finally, lets remove the spaces inserted above:

perl -e 'print crypt("$ENV{PSWD}","\$$ENV{HVAL}\$$ENV{SVAL}\$") . "\n"' 

then, the command may be assigned to a variable.

var="$( perl -e 'print crypt("$ENV{PSWD}","\$$ENV{HVAL}\$$ENV{SVAL}\$") . "\n"' )" 

With exported values: PSWD=password, HVAL=6, SVAL=saltsalt I get:

$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/

    You must log in to answer this question.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.