Prompt for administrator password

I am trying to write a script to prompt the user for their admin PW, then store the PW in a file for use later. When the program is run again, it will look for the PW in the file. If correct, it continues without further notice, but if incorrect, it prompts for the correct PW. My problem is that I cannot test if the PW is correct. In the script below, I test the PW by doing a shell command that requires it, but can’t find out if the user had to type their PW or not. So I can only ask them if they did it. Can someone point the way to a better way of testing if the PW is correct without bothering the user if it is? I usually run this as an applet, so the password.txt file is in the applet application. If you “Run” it from the Script Editor, the password file will be in the Script Editor app (everyone probably knows this but I didn’t!). And no, I don’t really use such simplistic names for the PW file!


global pass_file
property msgtext2 : "If applet just prompted you to enter your password, confirm the password by entering it here." & return & "Otherwise just hit OK to proceed"
property PW : ""

--get stored PW from file
set pass_file to ((path to me as Unicode text) & "Contents:Resources:Password.txt") as file specification
try
	set PW to read pass_file -- Read PW from the file; will be read as string by default
on error --password file did not exist, so prompt now for the PW
	set PW to GetPW("To run this program without interruption, you need to enter your administrator password", PW)
end try

--see if the PW is valid
do shell script "ls ~root" password PW with administrator privileges --this will prompt for PW if PW is incorrect
do shell script "sudo -k" -- timeout sudo ability
set PW to GetPW(msgtext2, PW) --prompt for PW. If no PW entered, PW remains the same

on GetPW(msgtext, OldPW) --if no PW entered, return the OldPW; otherwise return updated PW
	set TempPW to text returned of (display dialog msgtext default answer "" buttons {"OK"} default button 1 with hidden answer)
	if TempPW is "" then --PW was not entered, so return OldPW
		return OldPW
	else --PW was entered, so file it and return it to caller
		write (TempPW as string) to open for access pass_file with write permission
		close access pass_file
		return TempPW
	end if
end GetPW


Thanks for any pointers you can provide.

Hi,

I’m using this subroutine


on checkAdminPassword(uName, pWord)
	do shell script "sudo -k" user name uName
	delay 1
	try
		do shell script "sudo -v" user name uName password pWord with administrator privileges
		return true
	on error e
		return false
	end try
end checkAdminPassword

Stefan

Thanks for your help. Works beautifully.

This is a really bad idea.

You’re giving the user the illusion of security by using hidden answer dialogs to prompt for the password, then you write the password in plain text file that advertises its purpose “hmm… I wonder what the file ‘password.txt’ does…?”

It might be OK if this were just for you, but if you’re thinking of distributing this app to anyone else then you have to revisit this.

At the very, very least, encrypt the data and don’t store it in such an obvious file name.
Never store the password within the application itself (if user A sends a copy of the app to user B you have just compromised user A’s machine). If you have to store it, put it in the user’s preferences folder so that at least other users don’t get to see it.
A even better solution would be to add it to the user’s keychain (via keychain scripting) so you never have to worry about it at all.

Unfortunately this solution does not work anymore. I assume this was written for an earlier version of OS X or AppleScript.

In 10.5 as well as 10.6 calling the function “checkAdminPassword(…)” with false credentials (like: wrong password) will pop up a dialog from the system. AppleScript is trying to be nice and give me a second chance…

If the authentication dialog is answered incorrectly or dismissed, the function will return “false”, as it should in the first place.
If the authentication dialog is answered correctly, the function will return true, although the password given to the function was wrong.

In other words: The feedback of the function is that of the authentication dialog that pops up if the credentials are wrong, not of the values that are passed.
This dialog shouldn’t be there; it kills this wonderful function.

Has anybody any other way of checking if the credentials are valid?