Street Art : MadC

MadC, de son vrai nom Claudia Walde est une street-artist allemande. Elle réalise en 2010 son désormais célèbre 700 Wall, une fresque de près de 700m2 qui la propulse sur le devant de la scène graffiti. Renommée internationalement pour ses énormes fresques (Jurassic Park Wall, 500 Wall, ...) qu'elle a l'habitude de réaliser seule, je lui préfère pourtant son travail sur les couleurs et la transparence, qu'elle maîtrise à la perfection.

Pour en savoir plus sur MadC : madc.tv

MadC - The Transparent Wall, 2010

MadC - The Neon Wall, 2011

MadC - Twenty Forty-Three (canvas)

MadC - Allemagne, 2012

MadC - Landsberg, 2015

OSX : Let's play with security

I have a few shellscripts that need username and passwords to accomplish some tasks. For example, I wrote a shellscript to backup some data in an encrypted sparsebundle file that is stored on an AFP share. So I have a username and a password to mount the share, and some others credentials to mount the sparsebundle.

When it comes to automating the backup process, I had to face a simple issue : where do I store these usernames and passwords ?

Hard-code them in the script ? Naaah.

Create some kind of read-only file with proper permissions ? Sounds rather risky.

So, what would be the right way to do this with OSX ?

The answer is kind of obvious : OSX ships with a nice tool called Keychain Access.app. This service is intended to store and retrieve credentials, keys, passwords, certificates,... in a secure fashion. But how can I access it from the shell ?

This is where security comes to the rescue ! security is a Command Line Interface that allows you to administer and manipulate keychains, keys and certificates. In other words, security allows you to access Keychain (the app) from the shell (local shell ! SSH ! shellscript !). Wonderful, isn't it ?

Although it comes with a manpage, let's see some examples.

Adding items to a keychain

First, let's add a generic password to the default keychain. Here is what I'm using to store the credentials for my sparsebundle file :

security add-generic-password -a "username" -D "Image Disk Password" -s "MyFile.sparsebundle" -w "THis_IS_so_s3crEt_!"

The -a option allows you to specify the account name. -D is for the description. -s allows you to specify the service name (here I chose to set it to the sparsebundle filename but you can put whatever you want). And -w allows you to specify the password.

Adding an Internet password is a little bit different :

security add-internet-password -a "username" -D "AFP Share Password" -s "myserver.example.com" -p "share" -r "afp " -l "My AFP Share" -w "THis_IS_4lso_very_s3crEt_!" /Library/Keychains/System.keychain

This time we had to specify the server with -s, a path (here, the name of the shared point) with -p, a label with -l and the protocol (could have been http, ftp, or whatever) with -r.

WARNING : the argument for the -r option MUST be exactly 4 characters long. So you have to write "afp ", not "afp".

Please also notice that we decided to add this entry to the System keychain which is located in /Library/Keychains/System.keychain. We could have chosen to add it to another existing keychain by providing the path to this keychain, or we could have created a brand new one with :

security create-keychain /path/to/my/new/Personnal.keychain

Retrieving items

Retrieving an item in a keychain is pretty easy. Here I choose to retrieve the item by service (remember the -s option we used when we created the entry ?) :

security find-generic-password -g -s "MyFile.sparsebundle"

Which outputs the following :

keychain: "/Users/francoiskubler/Library/Keychains/login.keychain"
class: "genp"
attributes:
    0x00000007 <blob>="MyFile.sparsebundle"
    0x00000008 <blob>=<NULL>
    "acct"<blob>="username"
    "cdat"<timedate>=0x32303134313232393130323735365A00  "20141229102756Z\000"
    "crtr"<uint32>=<NULL>
    "cusi"<sint32>=<NULL>
    "desc"<blob>="Image Disk Password"
    "gena"<blob>=<NULL>
    "icmt"<blob>=<NULL>
    "invi"<sint32>=<NULL>
    "mdat"<timedate>=0x32303134313232393130323735365A00  "20141229102756Z\000"
    "nega"<sint32>=<NULL>
    "prot"<blob>=<NULL>
    "scrp"<sint32>=<NULL>
    "svce"<blob>="MyFile.sparsebundle"
    "type"<uint32>=<NULL>
password: "THis_IS_so_s3crEt_!"

But I could have chosen to retrieve it by account name (remember the -a option ?) :

security find-generic-password -g -a "username"

Or by account name AND service AND description in a specific keychain file :

security find-generic-password -g -a "username" -s "MyFile.sparsebundle" -D "Image Disk Password" /path/to/my/new/Personnal.keychain

If you have more than one entry that matches your criteria, security will only output the first one that matches. So, be careful when you add a new entry in a keychain, and make sure you'll be able to retrieve it easily later by specifying a different label (-l option) or a comment (-j option) or whatever you prefer.

Parsing the output

Obviously, the output of the command is kind of useless and needs to be parsed. On OSX prior to 10.9, when retrieving a password with the -g option (which asks security to print the password), the password was printed on stderr, so you had to play with shell redirections and write something like the following :

my_precious=$(security 2>&1 > /dev/null find-generic-password -g -s "MyFile.sparsebundle" | cut -d "\"" -f 2)

Starting with OSX 10.9, you can drop the -g flag and use -w instead :

my_precious=$(security find-generic-password -w -s "MyFile.sparsebundle")

The cool part here is that you can retrieve more than just the password. You can also retrieve the username (tested on OSX >= 10.6) :

output=$(security 2>&1 find-internet-password -s "myserver.example.com" -r "afp " -g)
username=$(head -n 7 <<< "$output" | tail -n 1 | cut -d "\"" -f 4)
my_precious=$(head -n 1 <<< "$output" | cut -d "\"" -f 2)

Of course, depending on your needs, you'll have to modify the commands, but you should now get the idea. The most important part here is to remember that when called with the -g option, security will print the password to stderr instead of stdout.

More : Certificates, Keys, ...

There are a bunch of option that allows you to manage certificates, keys and identities (certificate + private key). I've never had to deal with that stuff so I can't provide any decent example. But they do exist and a quick look at the manpages should be enough to help you.

#JeSuisCharlie

Les évènements de cette semaine montrent à quel point nous avons échoué en tant que société.

← Billets de l'année 2014 - 2015