How to pull a password from Keychain to use in a script

Jul 24, '13 11:30:00AM

Contributed by: poenn

Quite some time ago, I needed to create a script which would mount a network volume. I did not want to hardcode username and password into the script, so I kept looking for ways to accomplish this using OS Xís built-in Keychain. The following example uses a script to mount a network volume, using variables for the currently logged-in user, and fetches its password from the Keychain. Of course, you can do other things with this approach, so I figured it might be of use to someone out there.

The following is a combination of these 2 links:

This script gets the password for the currently logged in user and pulls its password from the Keychain. It then mounts a share using the variables without hardcoded username/password. The mount point is not in /Volumes on purpose, because mounting the volume would not work for User B when Fast User Switching is in use and User A remains logged in without having unmounted the volume. echo $USER gets the username of the currently logged in user.
$(get_pw) contains the password retrieved from the userís keychain.

In this case I am mounting an AFP volume, but it could be any other protocol, as well as something completely different which has nothing to do with mounting volumes.

get_pw () {
  security 2>&1 >/dev/null find-generic-password -ga $USER 
  |ruby -e 'print $1 if STDIN.gets =~ /^password: "(.*)"$/'
mkdir ~/Data
mount -t afp afp://$USER:$(get_pw)@ ~/Data
Before running this script you have to create a new entry using Keychain Access with the username and its (server) password.

The steps are as follows:

Manually create a Keychain entry for the AFP user account. To do so open Keychain and hit cmd+n. Keychain Item Name does not matter, but Account and Password have to be filled out with the userís username+password. That is the login info of the AFP account on the server!

Then create a shell script the way you prefer. I usually use pico, but thereís also a "run shell script" workflow in Automator if you want to use it. The script is shown above. Hereís a short explanation of whatís happening in the script:

We issue the security command which itself is able to read info from the keychain. It fills the variable $get_pw with the password it retrieved from the keychain. Thatís why you need to create the keychain entry mentioned above. Instead of hardcoding which userís password to get we use another variable called $USER. This always represents the currently logged in user (try echo $USER in Terminal as an example). In the next step we create the mount point, but instead of the default location (/Volumes) we use ~/ to ensure the mount point is inside the user home. This prevents the mount point from being already in use when using Fast User Switching. The last step then mounts the desired share using both variables. In my case that is the share Data on the server which will be mounted at ~/Data.

In order for this to work you need to use network user accounts (Open Directory, LDAP, Active Directory, etc.) OR have to use the exact same username (password does not matter) for the local account and the account on the afp server. That is because $USER will always return the currently logged in userís name which will be the local account if you are not using network accounts. In my case it was perfect that way, because I use network accounts anyway. You could always replace $USER in the script with jon.doe while losing the flexibility of the solution. I wanted a script without hardcoded usernames or passwords which could get the needed information dynamically from the keychain, which is exactly what this does.

Comments (4)

Mac OS X Hints