4

I have background process running as the logged on user that frequently tries to mount an AFP share to backup some data. If the share cannot be mounted this should just be ignored.

In my script (bash, actually) I am mounting the share via an AppleScript mount volume snippet. In contrast to the mount or mount_afp commands, this appears to be the only way to automatically authenticate the user at the respective server with credentials from the Kerberos ticket or the user's keychain. In particular, I do not want to have to store a password in the script:

try
    mount volume "afp://server/share"
on error errText number errNum
    log {errText, errNum}
end try

This works generally fine, but despite the try ... on error block, the 'mount volume' command always opens a dialog in case of an error:

enter image description here

I am looking for :

  • a way to suppress this dialog, or
  • a solution to automatically dismiss it (maybe involving some SystemEvents trickery?), or
  • an approach to teach mount, respectively mount_afp to use the credentials from the Kerberos ticket and the user's keychain without having to provide a password.

I have googled and tried for a couple of hours, but not yet found any solution.

Daniel
  • 195
  • 1
  • 6
  • You can also try mount it with a bash script, and before mount pull the password from the users keychain. Read this http://hints.macworld.com/article.php?story=20130722033452283 – clt60 Mar 25 '14 at 16:41
  • @jm666: Thanks for the hint, I had forgotten about the `security` command. However, given a user process the capability to pull the password from keychain is IMHO only slightly better than storing it directly. – Daniel Mar 26 '14 at 12:38
  • Maybe understand wrong, but when do you using the `security` command, it not asking for a password when the user has unlocked keychain. (usually it unlocks at login time). So, if the user is already logged the `security` command will ask only for a _confirmation, to access items_ and if the users click _allow allways_, will not ask anymore. So, the mount password is secured in the keychain, can be pulled only from the unlocked keychain.But as i told, maybe my english isn't enough good to understand the problem ;) – clt60 Mar 26 '14 at 14:23
  • @jm666: Your English is fine :-) My point is that, if I click "Always allow", _any_ script can use the `security` command to pull the user's password from the keychain. This opens a big security hole, so the solution is IMHO only slightly better than storing it directly as plain text. – Daniel Apr 03 '14 at 10:54
  • Daniel, the keychain is opened _anyway_ for the logged user. So, the user _has_ rights anyway see his own keychain. You _cant use_ the security command on unlocked keychain without password - so i don't see any security hole, because if _other user_ will run the `security` command, for the this particular keychain, it is not opened for _him_. Simply, it is the best try is in real - without talking here about the _possibilities_ and threats... :) – clt60 Apr 03 '14 at 18:18

3 Answers3

3

I have been fighting this problem on my mac mini media server for ages and believe i finally have a solution.

I have split it into two scripts:

the first one runs on idle (rather than a repeat loop) and calls a second script every 10 seconds that handles the drive mounting.

--------------------------------------------------------------------------------------
--"On Idle Launch Basic Drive Mounter.app"

on idle
    try
        --script loads on startup, so first we wait 5 seconds to ensure network
        delay 5
        --run the mounter script which is on the desktop
        run script file ":Users:localusername:Desktop:Basic Drive Mounter.app"

    on error errStr number errorNumber
        --listen for the apple quit command and quit
        if the errorNumber is equal to -128 then
            quit
            return 1
        --listen for the unknown error and ignore it
        else if the errorNumber is equal to -5014 then
            return 5
        else
            --all other errors are also ignored
            return 5
        end if
    end try
    --return with a wait of 5 seconds before next idle run
    return 5

end idle
--------------------------------------------------------------------------------------

the second script does the checking of the network, then tries to mount the volume using a shell mount. i originally used a finder "mount volume" and that codes exists as comments too, but I didn't like the dialog popping up on errors; even if only for a second, so i moved on to shell script.

--------------------------------------------------------------------------------------
--"Basic Drive Mounter.app"
try
    set IP_address to "xxx.xxx.xxx.xxx"

    set IP_Valid to true

    try
        do shell script ("ping -c 2 " & IP_address)
    on error
        set IP_Valid to false
    end try

    if IP_Valid then
        tell application "Finder"
            if disk "work" exists then
            else
                -->>shell script version
                try
                    do shell script "mkdir /Volumes/work"
                end try
                do shell script "mount_afp afp://xxx.xxx.xxx.xxx/work /Volumes/work/"
                --<<shell script version
                -->>finder mount volume version
                --with timeout of 1 second
                --  mount volume "afp://xxx.xxx.xxx.xxx/work"
                --end timeout
                --<<finder mount volume version
            end if
        end tell
    end if
on error
    -->>finder mount volume version
    --on error finder returns an error dialog which needs to be closed to go back and  retry
    --tell application "System Events"
    --  keystroke return
    --end tell
    --<<finder mount volume version
    return 0
end try    
--------------------------------------------------------------------------------------

not all of this is my own code, so many thanks goes out to the applescript community and google - remember to pay it forward

dunean
  • 166
  • 4
  • Thanks for sharing this! However, this does not solve my problem with the `mount_afp` command, which asks for explicit credentials (username/password) instead of automatically authenticating the user at the respective server with credentials from the Kerberos ticket or the user's keychain. – Daniel Dec 07 '14 at 22:16
  • @daniel -- I use this against a local nas and the user signed into osx is the same as the user on the nas, the password is stored in the keychain and it works with mount_afp. But of course a kerberos authentication is a lot tricker and thus might be the issue. Did you try the other option in the code with hitting return? Not as elegant though. – dunean Dec 09 '14 at 06:20
2

Apologies for the crappy answer. I think if you try something like this you won't be bothered with dialogs (but you can still have your script respond to errors).

(below is a simple version. Documentation for mount_afp with username/password is here: http://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man8/mount_afp.8.html )

    try
        alias (POSIX file "/Volumes/yourMountedVolumeName")--hacky check for mount point
    on error
        --does not exist, so make dir
        do shell script "mkdir /Volumes/yourMountedVolumeName"
    end try

    --now use do shell to mount
    try
        do shell script "mount_afp 'afp://yourServer/yourMountedVolumeName/' /Volumes/yourMountedVolumeName"

    on error errText number errnum
        log {errText, errnum}
    end try

[insufficient answer below]

Some of this might be obvious, but you'll need to

  1. watch for that dialog (or, obviously, a successful mount), and
  2. if it comes up, dismiss it.

I believe this will work to kill the dialog w/o resorting to System Events ... in terminal or shell:

killall NetAuthAgent

or via AppleScript:

do shell script "killall NetAuthAgent"

Of course, you have to be careful not to kill it during the authentication process.

CRGreen
  • 3,406
  • 1
  • 14
  • 24
  • 1
    Could you be a bit more specific on _how_ to accomplish the _"watch for that dialog"_ and _"if it comes up, dismiss it"_ part? – Daniel Mar 26 '14 at 12:40
  • Thanks for your efforts. However, as explicitly described in the question the main point is to **not have to pass the password**, but implicitly use the credentials from the user's keychain. This is what 'mount volume' in AppleScript provides, but apparently there is no comparable shell command ('mount' and 'mount_afp' require a password). – Daniel Apr 03 '14 at 10:49
  • I apologize, but the question stated that you didn't want to "store" the password in the script. It is true that you'd have to ask for and submit a password, but you wouldn't have to store it. – CRGreen Apr 03 '14 at 15:40
  • Sorry for the confusion. – Daniel Apr 03 '14 at 16:26
2

To mount the drives, make an apple script like this:

tell application "Finder"

    try

        mount volume "afp://192.168.0.0/test"

    end try

end tell

Then, to close the warning message that comes up, use another script like this:

delay 2
tell application "System Events"
    click UI element "OK" of window 1 of application process "NetAuthAgent"
end tell

The delay just gives the message box a chance to appear, but you might not need it.

If you run this last script from the terminal using osacompile then osascript, you will need to give accessibility access to the terminal.

magarnicle
  • 186
  • 6
  • I know this is a few years old, but I'm in exactly this same situation and this answer did not work for me. The code for dismissing the error dialog, never clicks anything and the dialog just sits. – JVC Apr 09 '20 at 17:38
  • 1
    I haven't used this code in a long time, so I don't know if OS changes have broken it. I derived the code using MacOS Automator's record function and then cleaned up the code it produced. – magarnicle Apr 14 '20 at 01:04
  • Oh wow that's a great idea, I forgot there even *was* a record function. I may play around with that... thanks! – JVC Apr 14 '20 at 12:22
  • YW. If you solve it come back and post the solution here. – magarnicle Apr 15 '20 at 00:19