Added support for using special characters for password.
This commit is contained in:
@@ -5,48 +5,77 @@ echo "Content-type: application/json"
|
||||
echo ""
|
||||
|
||||
# Read POST data
|
||||
read POST_DATA
|
||||
read -r POST_DATA
|
||||
|
||||
# Debug log
|
||||
# Debug log for generated hash
|
||||
DEBUG_LOG="/tmp/password_change.log"
|
||||
|
||||
# Extract the passwords from POST data
|
||||
OLD_PASSWORD=$(echo "$POST_DATA" | sed -n 's/^.*oldPassword=\([^&]*\).*$/\1/p')
|
||||
NEW_PASSWORD=$(echo "$POST_DATA" | sed -n 's/^.*newPassword=\([^&]*\).*$/\1/p')
|
||||
|
||||
# URL-decode the passwords
|
||||
OLD_PASSWORD=$(echo "$OLD_PASSWORD" | sed 's/+/ /g;s/%\(..\)/\\x\1/g' | xargs -0 printf "%b")
|
||||
NEW_PASSWORD=$(echo "$NEW_PASSWORD" | sed 's/+/ /g;s/%\(..\)/\\x\1/g' | xargs -0 printf "%b")
|
||||
|
||||
# User to change password for
|
||||
# Extract the passwords from POST data (URL encoded)
|
||||
USER="root"
|
||||
OLD_PASSWORD=$(echo "$POST_DATA" | grep -o 'oldPassword=[^&]*' | cut -d= -f2-)
|
||||
NEW_PASSWORD=$(echo "$POST_DATA" | grep -o 'newPassword=[^&]*' | cut -d= -f2-)
|
||||
|
||||
# Verify old password first
|
||||
USER_SHADOW_ENTRY=$(grep "^$USER:" /etc/shadow)
|
||||
if [ -z "$USER_SHADOW_ENTRY" ]; then
|
||||
echo '{"state":"failed", "message":"User not found"}'
|
||||
# URL-decode the passwords (replace + with space and decode %XX)
|
||||
urldecode() {
|
||||
local encoded="${1//+/ }"
|
||||
printf '%b' "${encoded//%/\\x}"
|
||||
}
|
||||
|
||||
OLD_PASSWORD=$(urldecode "$OLD_PASSWORD")
|
||||
NEW_PASSWORD=$(urldecode "$NEW_PASSWORD")
|
||||
|
||||
# Basic validation to reject & and $ characters
|
||||
if echo "$OLD_PASSWORD$NEW_PASSWORD" | grep -q '[&$]'; then
|
||||
echo '{"state":"failed","message":"Password contains forbidden characters (& or $)"}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract current password hash and salt
|
||||
# Extract the hashed password from /etc/shadow for the specified user
|
||||
USER_SHADOW_ENTRY=$(grep "^$USER:" /etc/shadow)
|
||||
|
||||
if [ -z "$USER_SHADOW_ENTRY" ]; then
|
||||
echo '{"state":"failed","message":"User not found"}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract the password hash (second field, colon-separated)
|
||||
USER_HASH=$(echo "$USER_SHADOW_ENTRY" | cut -d: -f2)
|
||||
|
||||
# Extract the salt (MD5 uses the $1$ prefix followed by the salt)
|
||||
SALT=$(echo "$USER_HASH" | cut -d'$' -f3)
|
||||
|
||||
# Generate hash from old password
|
||||
OLD_GENERATED_HASH=$(echo "$OLD_PASSWORD" | openssl passwd -1 -salt "$SALT" -stdin)
|
||||
# Generate hash from old password using the same salt
|
||||
OLD_GENERATED_HASH=$(printf '%s' "$OLD_PASSWORD" | openssl passwd -1 -salt "$SALT" -stdin)
|
||||
|
||||
# Verify old password
|
||||
if [ "$OLD_GENERATED_HASH" != "$USER_HASH" ]; then
|
||||
echo '{"state":"failed", "message":"Current password is incorrect"}'
|
||||
echo '{"state":"failed","message":"Current password is incorrect"}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Change password using passwd command
|
||||
# We need to pass both the new password and its confirmation
|
||||
(echo "$NEW_PASSWORD"; echo "$NEW_PASSWORD") | passwd $USER 2>> $DEBUG_LOG
|
||||
# Create a temporary file for the new password
|
||||
PASS_FILE=$(mktemp)
|
||||
chmod 600 "$PASS_FILE"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo '{"state":"success", "message":"Password changed successfully"}'
|
||||
# Write the new password twice (for confirmation)
|
||||
printf '%s\n%s\n' "$NEW_PASSWORD" "$NEW_PASSWORD" > "$PASS_FILE"
|
||||
|
||||
# Change password using passwd command
|
||||
ERROR_OUTPUT=$(passwd "$USER" < "$PASS_FILE" 2>&1)
|
||||
RESULT=$?
|
||||
|
||||
# Log the operation
|
||||
echo "Password change attempt. Result: $RESULT. Time: $(date)" >> "$DEBUG_LOG"
|
||||
if [ $RESULT -ne 0 ]; then
|
||||
echo "Error output: $ERROR_OUTPUT" >> "$DEBUG_LOG"
|
||||
fi
|
||||
|
||||
# Clean up
|
||||
rm -f "$PASS_FILE"
|
||||
|
||||
# Return result
|
||||
if [ $RESULT -eq 0 ]; then
|
||||
echo '{"state":"success","message":"Password changed successfully"}'
|
||||
else
|
||||
echo '{"state":"failed", "message":"Failed to change password"}'
|
||||
echo '{"state":"failed","message":"Failed to change password"}'
|
||||
fi
|
||||
Reference in New Issue
Block a user