Make user verify administrator password with timeout

FYI: Kill sends SIGTERM by default which is almost equivalent to quitting an application properly. As long as you don’t send SIGKILL, you’re doing fine. But like Applications, it completely depends how well the signal handle function is implemented.

I actually envised, the launching of the applet, and calling the handler to be done inside a “try block”. I think I can manage to kill an applet by sending a signal to it, without generating a crash-report, which I guess is what SIGTERM does. :slight_smile:

I am not doing anything. :wink: I was just sketching up a probable way to solve the problem, with something that really should work, so that the “with administrator privileges” do shell script can time out.

There must be put som effort into this in order to create a working solution, with testing of every step and so on. The only thing that I guess can be taken lightly, is that there will be no race conditions, with regards to the file name the process id is written into. There is a way around the lack of timeout for the do shell script, or other commands that also are from scripting additions, as long as someone are willing to invest time in creating a practical implementation.

That is really wants it, I don’t, -at the moment at least, (I reckon it may take up to three hours to make a solution that works, with testing and everything).

Edit

Having a do shell script, spawn a background process, containing an osascript, telling the applet to quit, would probably not work, all the time that the do shell script is running, so the only option is killing it, that will be brutal, maybe the only way to get rid of any crash reports, is to set debug options for the applet.

I should mention, that I am unsure whether you can excempt an app from a crash report when it crashes, by setting properties directly for it, but you can disable crashreporter globally, before and after the app is executed: OSX Daily

That’s the limitation of an applet, try quitting it by hand it won’t work either. Putting it in an idle handler won’t work as well. The other option is not killing the applet but killing the command the applet is executing, but that makes the whole applet kind of overhead and bring us back to my example first.

Again, what would the point of an applet be then? Applications, processes that have GUI and connected to the window server/console, has to be able to listen to AppleEvents and has to support a required set of Apple events. Applications, including applets, are quit by an AppleEvent like any other applications. So to me applications should therefore never be quit otherwise than sending an quit AppleEvent, unless it hangs of course. BSD processes, like osascript, can only be quit by sending a signal to it and kill is perfect for the job. In short: When stopping an application you send an AppleEvent and when stopping a BSD process you send a signal.

I should mention, that I am unsure whether you can excempt an app from a crash report when it crashes

Normal killing (signal SIGTERM) doesn’t cause an crash report. When using signal SIGQUIT it will generate a crash report. When the process is halted it will generate a crash report on next launch depending on application (applet won’t).

Hello.

I did mix up the SIGTERM and SIGQUIT signals. The whole idea for using an applet, was to not just kill the script, but let the script be informed of whether the timeout occured or not. So I did need an applet for doing the do shell script, as I needed something to quit other than the calling script. You can kill an OSX application, which an applet is a form of, therefore I thought that would be the easiest approach to achieve the stated goal, of informing a script of a timeout. And it is also possible to disable the CrashReporter before, calling the Applet, and enable it when it is done, thereby not cluttering the screen with a Crash Report dialog, when the user finally unlocks it.

I am not saying that this is a “clean” solution, but it is a solution that can be made to work. :slight_smile:

So here’s a working solution.

Three parts: The calling script, the applet to generate the dialog, and a little 1-byte file to store the return value of the applet so that the calling script knows the result (since I don’t know how else to get at the return value)

Calling script (this goes into whatever script it is that you want to request the administrator password):

property PassEnteredFile : ((path to scripts folder from user domain) & "Background scripts:ScriptData:PasswordEntered.b") as string

property PromptPassApp : ((path to scripts folder from user domain) & "Script Resources:Scripts for Services:PromptForPassword.app:") as string
property PromptName : "PromptForPassword"

property DelayTimeOut : 15

on CheckPassword()
	local PassEntered, PassFileRef, CloseTerminal, ScriptStr, PID, StartTime
	
	set PassEntered to false
	set PassFileRef to open for access PassEnteredFile with write permission
	set eof of PassFileRef to 0
	write PassEntered to PassFileRef as boolean
	close access PassFileRef
	
	ignoring application responses
		tell application PromptPassApp to activate
	end ignoring
	
	set StartTime to current date
	repeat until ((current date) - StartTime > DelayTimeOut)
		if not appIsRunning(PromptName) then exit repeat
		delay 0.25
	end repeat
	
	if appIsRunning(PromptName) then
		set ScriptStr to "ps aux | grep -v grep |grep -i " & quoted form of PromptName & " | awk '{print $2;}'"
		set PID to do shell script ScriptStr
		do shell script "kill " & PID
	end if
	
	set PassEntered to read (PassEnteredFile as alias) as boolean
	
	return PassEntered
	
end CheckPassword

password prompt script to be saved as applet:

property PassEnteredFile : ((path to scripts folder from user domain) & "Background scripts:ScriptData:PasswordEntered.b") as string

on run
	local PassEntered, PassFileRef
	
	try
		do shell script "echo" with administrator privileges
		set PassEntered to true
	on error
		set PassEntered to false
	end try
	
	set PassFileRef to open for access PassEnteredFile with write permission
	set eof of PassFileRef to 0
	write PassEntered to PassFileRef as boolean
	close access PassFileRef
	
end run

And the ‘PasswordEntered.b’ file will be created wherever you have the path set to in the two scripts.

You can do whatever you want with the results of CheckPassword(). In my case, if it returns false (meaning that the password dialog either timed out or was cancelled) I lock the screen immediately.

It ain’t pretty but it works! And way less than 3 hours to make, so long as you don’t count the failed attempts at getting this done before I asked the question here!

I appreciate the help, as always. I had considered the need of using another script/app/process in order to accomplish this. Little disappointed it came to this, but at least it works, and now I can for the user to authenticate him/herself and have the screen lock to a password protected machine if they can’t.

Hi,

Skimming through this post I didn’t get how Stefan’s script fell short with the ‘display dialog’.

Edited: wait, I didn’t see page 2. :slight_smile:

Edited: oh, I’m page 2. Nevermind about the page 2.

Later,
kel

See post #14 (http://macscripter.net/viewtopic.php?pid=179780#p179780) to see why “display dialog” was unacceptable.

Hi scriptim,

Nevermind, I found your other post:

Interesting!

Thanks,
kel

Hi,

In previous os’s the lock screen from the utility menu didn’t work (wink wink). There was a way to get around it. But, now it seems that they fixed it in Yosemite. What if you uieelment script the utility menu to lock screen?

I’ll Have to reread this post again maybe to see what was the goal, but it is a nice puzzle for a workaround.

Edited: :smiley:

gl,
kel

Would that be much different from ui scripting the keychain access menu bar item like I’m doing now?

Also, there might be a way to script Keychain Access. Still looking into that.

Edited: note that it’s different now.

Edited: I know that there was a way to script it, but memory is not as good. How the hell did I script Keychain Access! Thinking!

gl,
kel

Checking on unix ‘security’ module.

Edited: maybe found a way with Python.

Darn, I can’t find anything.

Maybe it’s best to script the utility menu and ‘Lock Screen’ for Keychain Access.

gl,
kel

To be sure, both the way I’m accomplishing the timeout on the password dialog AND the way I’m locking the screen such that a password is required immediately are both brutal. I’d love to find better ways of doing both.

Thanks to DJ I’m now using the word ‘brutal’ to describe code.

brutal is a brutal word! :smiley:

Edited: I need to think positive.:slight_smile:

There’s always tomorrow. :slight_smile:

Hello Scriptim.

Here is a little contribution to your solution:

tell application "System Events"
	set tpid to unix id of process "theAppletName"
end tell

Edit

This should be possible in one go, I use a unix “function” here (backticks).

set ScriptStr to "kill ` ps aux | grep -v grep |grep -i " & quoted form of PromptName & " | awk '{print $2;}' `"
do shell script ScriptStr

Wow, that’s way down there in the properties:

What the hell is that?! :slight_smile:

Backticks are deprecated, you should use $(command) instead.

I don’t take your word for it, mind you.

You can find the whole post here.

When the do shell script is executing the sh, as the command line interpreter, we are indeed using the legacy interpreter.

In the recent past, I have experienced that “bash niceties” haven’t worked for me in a do shell script setting, so that I have actually had to invoke bash with a command string, now, that is not a lot of overhead, comparing it to loading a webpage, but in our context, the overhead is considerable.

Therefore I do like the Romans when in Rome. I only use sh features with do shell script, to assure that the solution allways works. (I may have done stuff to my system, to hamstring it to only work with a pure sh environment, but if I have accomplished that, then other uses may have accomplished the same.) :wink: