1

I am looking for a solution to sanitizing variables in my bash password change script.

The script below is working, however I have found that some "Special Characters" will break my script. I am not controlling at the moment what Characters are being passed through. I am either looking to sanitize the variables before passing them through, or pushing the variables as a whole untouched. I have tried using '${PASS}' in place of "${PASS}" however the script would not complete when this was the case.

I would appreciate any recommendations anyone could offer. I have tried searching for the answer to this question before posting but didn't find anything relative so i am sorry if this has been answered elsewhere.

#!/bin/bash

# Two variables are passed, Username and new Password. 

USERNAME=$1
PASS=$2

expect << EOF
spawn passwd ${USERNAME}
expect "Enter new UNIX password:"
send "${PASS}\r"
expect "Retype new UNIX password:"
send "${PASS}\r"
expect eof;
EOF

expect << EOF
spawn htdigest /.passwd "Authenticated Users" ${USERNAME}
expect "New password:"
send "${PASS}\r"
expect "Re-type new password:"
send "${PASS}\r"
expect eof;
EOF

expect << EOF
spawn htpasswd /squiddb ${USERNAME}
expect "New password:"
send "${PASS}\r"
expect "Re-type new password:"
send "${PASS}\r"
expect eof;
EOF

Thank you in advance!

Astupidmoose
  • 21
  • 1
  • 2
  • What "Special Characters"? +1 for using `expect` to set a password. I had this issue with `Perl` and `Expect`. – MattSizzle May 27 '14 at 05:35
  • Side-note: I have always used `autoexpect` generated script and edited them according to my need. This practice has seen me through many issues, possibly like this one as well. – PradyJord May 27 '14 at 07:29
  • Here is an example of an extreme case of special characters for ${PASS}: billy$@%^443&%&^fe!! – Astupidmoose May 27 '14 at 07:41
  • For me, I would like to use `chpasswd` for password changing in a script. You can use it like this: `echo "$USERNAME:$PASS"|chpasswd`. But I'm not sure it can solve the issue caused by special characters. – WKPlus May 27 '14 at 07:50
  • Do you mean the "special characters" just not the correct password? Or what's the exact error? If the password just can't include the "special characters", maybe you can have a evaluation before you send the password to expect. – Nancy May 27 '14 at 10:08
  • I would like to allow special characters in passwords as this keeps them safer and limiting customers is not my intention. Running the commands through shell but not in a script allows passwords to be changed with special characters no problem. I believe the problem is in the sanitization and need to escape special characters, however these characters are unknown until users input is entered. Something to do with how the special characters are interpreted by the script is causing the issue. – Astupidmoose May 27 '14 at 16:13
  • @WKPlus `chpasswd` in a script is horribly insecure and should be avoided at all cost. – MattSizzle May 27 '14 at 21:43
  • If one of the answers addressed your question to the point of resolution can you accept it? This will encourage people to answer your questions again in the future. – MattSizzle May 28 '14 at 19:45
  • sorry @MattGreen, wanted to test this before committing to an answer and was not able to until today. – Astupidmoose May 29 '14 at 20:48

2 Answers2

1

Send the username and password to the expect scripts via command-line arguments to expect instead. As done now, a double quote would confuse expect since the here-to document is interpolated fully before sent to expect's stdin.

A password like 'hej"' without the single quotes would lead to a send command for expect looking like this:

send "hej"\r"

expect will not enjoy that.

You can access the argument via argv, beware of quoting. Do not that you will expose the username and password to anyone doing "ps" on that box if you pass them as arguments on the command line to expect. But you already do that when calling the script in the question...

Olof
  • 111
  • 5
  • +1 as that is the exact issue. I don't understand why people run `expect` in `bash` with a `heredoc`, expect is a shell and should be used as one. – MattSizzle May 27 '14 at 21:45
  • Thanks, but the best solution is yours, @MattGreen :) Less fork/exec, just one level of string interpolation to worry about. I gave it a +1. – Olof May 28 '14 at 17:23
1

Why not use the Expect shell directly for doing this.

#!/usr/bin/expect

set timeout 20
set user [lindex $argv 0]
set password [lindex $argv 1]

spawn passwd $user
expect "Enter new UNIX password:"
send "$password\r";
expect "Retype new UNIX password:"
send "$password\r";
wait 1

spawn htdigest /.passwd "Authenticated Users" $user
expect "New password:"
send "$password\r"
expect "Re-type new password:"
send "$password\r"
wait 1

spawn htpasswd /squiddb $user
expect "New password:"
send "$password\r"
expect "Re-type new password:"
send "$password\r"

exit 0

Execute the above like

./SCRIPTNAME.exp user password
MattSizzle
  • 3,145
  • 1
  • 22
  • 42
  • I am still having problems with passing special characters. Here are some examples I have run through quickly: Billy2 - Works Billy2$ - Works Billy2! - Does not work Billy2!@ - Error message: -bash: !@: event not found Billy2%$&^^ - Does not work: Billy2%$&^^ becomes Billy2%$ and pushes out ^^: command not found – Astupidmoose May 29 '14 at 20:43
  • Can you run it with the `interpreter` explicitly: `expect SCRIPTNAME.exp user password`, your variables are getting interpolated, still which should not occur in the `expect` shell with the above. – MattSizzle May 29 '14 at 20:55
  • Still a no go for the following combinations: Billy2%$&^^, Billy2%$&, Billy2!@. I also tried Billy2!234wf which shows the following: -bash: !234: event not found – Astupidmoose May 29 '14 at 21:08