Reputation: 951
Per the following, I'm trying to obfuscate a password within a script
Hide/encrypt password in bash file to stop accidentally seeing it
However, because this password has non-alpha numeric characters in it, I don't think the variable "$MYPASS" echoing out properly in the second to last line of the script
My script:
#!/bin/bash
PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH
MYENCPASS='IURv34bmNocv98RnZXQhCg=='
MYPASS=`echo "$MYENCPASS" | base64 --decode`
echo
echo Enter username you\'d like to change password for:
read USERNAME
dscl /LDAPv3/127.0.0.1 -read /Users/$USERNAME >/dev/null 2>&1
if [ "$?" != "0" ]; then
echo
echo -e "\033[31m Username $USERNAME does not exist! Exiting..."
echo -e "\033[0m"
exit 1
fi
echo
echo Enter New Password for "$USERNAME"
read PASSWORD
dscl -u diradmin -P "$MYPASS" /LDAPv3/127.0.0.1 passwd /Users/$USERNAME $PASSWORD
echo Password successfully changed for $USERNAME to $PASSWORD at `date` | tee -a /var/log/odpasswd.log
Your ideas/suggestions are most appreciated!
Thanks, Dan
Upvotes: 3
Views: 270
Reputation: 295363
First, you need to quote your parameter to echo to avoid string-splitting and glob expansion:
echo "Password successfully changed for $USERNAME to $PASSWORD at `date`"
Second, if you want to emit the password in a machine-parsable form, use printf %q
:
printf 'Password successfully changed for %s to %q at %s\n' \
"$USERNAME" "$PASSWORD" "$(date)"
As an aside -- it's bad practice to use all-uppercase names for local variables (as it risks namespace conflicts with built-in and environment variables).
A complete version of your script, making a stronger attempt to follow best practices around scripting (but still failing horribly to follow any kind of good practices around security), would look something like this:
#!/bin/bash
# you probably don't need to export PATH -- if something is already exported,
# it stays exported on updates.
PATH=/bin:/usr/bin:/sbin:/usr/sbin
## this is really, _really_ horrible "security".
myencpass='IURv34bmNocv98RnZXQhCg=='
mypass=$(base64 --decode <<<"$myencpass")
echo
echo "Enter username you'd like to change password for:"
read -r username
if ! dscl /LDAPv3/127.0.0.1 -read "/Users/$username" &>/dev/null; then
# This is bad practice -- assuming that the only error that can happen is
# the nonexistent-user case, and hiding any other error messages, means that
# the user can't diagnose the _actual_ cause of any other error.
printf '\n\033[31m Username %s does not exist! Exiting...\033[0m\n' "$username"
exit 1
fi
printf '\nEnter New Password for %s\n' "$username"
read -r password
if dscl -u diradmin -P "$mypass" /LDAPv3/127.0.0.1 passwd "/Users/$username" "$password"; then
# previously, there was no conditional here, so we logged that this was
# successful even if it failed.
# And, of course, storing users' plaintext passwords in a log makes you evil.
printf "Password successfully changed for %s to %q at %s\n" \
"$username" "$password" "$(date)" \
| tee -a /var/log/odpasswd.log
fi
If you wanted to actually do this The Right Way, instead of trying this kind of obfuscation technique you'd authenticate to LDAP with, say, a cached Kerberos ticket (I'm assuming this is MacOS's Open Directory -- it can do that), readable only by the user the script runs as, and use sudo to allow temporary privilege escalation to the user who can read the ticket only when running this script.
Upvotes: 3