"I'll be back in a sex" and other freudian typos
24 Jun 08
Comments (View)
06 Jun 08
Comments (View)
28 May 08
Comments (View)
26 May 08
Comments (View)
30 Apr 08
  • Justin Ouellette: i couldn't resist, i got mario kart too
  • Justin Ouellette: the box was so big
  • Justin Ouellette: i was blinded
  • Peter McArthur: hahaha
  • Justin Ouellette: i'm going to use it to come down off gta iv sessions
  • Peter McArthur: you are cutting gta with mario kart
Comments (View)
Comments (View)
15 Apr 08
Comments (View)
13 Apr 08
If this shit doesn’t work, consider it pseudo-code. If it does work, I’m a badass
Life On The Edge With Merb, DataMapper & RSpec
Comments (View)
10 Apr 08

RubyCocoa and Keychain access

There have been a few posts asking how to access and manipulate the Keychain from within RubyCocoa but no answers supplied. As someone who is just getting into RubyCocoa (and Cocoa all together for that matter), I thought I’d document once and for all the process I took to get it working.

I am running on Leopard and while 10.5 is supposed to ship with BridgeSupport for most frameworks, the Security framework must have been left out. After playing around with using other frameworks (such as the AddressBook framework) and seeing how they were used, I did a bit of digging in the Apple Developer Documentation (incredible resource for anyone starting out) and stumbled across this gem: Generate Framework Metadata.

After reading this, I was accessing the keychain within 5 minutes. Here’s how:

  1. Run the following commands (first one will take some time):
    gen_bridge_metadata -f Security -o Security.bridgesupport
    mkdir -p /Library/BridgeSupport
    mv Security.bridgesupport /Library/BridgeSupport
  2. Open an IRB session to test it:
    >> require 'osx/cocoa'
    => true
    >> OSX.require_framework 'Security'
    => true
    >> defined? OSX::SecKeychainAddGenericPassword()
    => "method"

Hoorah! Two steps! Well, one because the second one was just testing… Now go make password-able RubyCocoa application! I am not sure how to pull this off with deployable apps but I suggest your apps could ship with the file or run those commands on first-run or if the Security.bridgesupport file doesn’t exist. Note: I have not tested either of those scenarios, but I would guess the latter would be more reliable for cross-version development (i.e. Tiger + Leopard)

[ADDITION:] I am just adding an explanation of how to actually use these methods.

  1. # Require needed libraries

    require 'osx/cocoa'
    include OSX
    require_framework 'Security'

  2. # Set up some relevant variables

    service = "Test Service"
    account = "MyUsername"
    password = "MyPassword"

  3. # Add password to default keychain (first param)

    SecKeychainAddGenericPassword(nil, service.length, service, account.length, account, password.length, password, nil)

  4. # Finding a password in default keychain (first param)

    status, *password = SecKeychainFindGenericPassword(nil, service.length, service, account.length, account)

    # Password-related data
    password_length = password.shift # => 10
    password_data = password.shift # OSX::ObjcPtr object
    password = password_data.bytestr(password_length)

    # The last item is another OSX::ObjcPtr. I haven't figured
    # out how to cast or use this yet but will post when I've
    # figured it out
    keychain_item = password.shift

    # Yay it works! You can also check the password exists
    # in the Keychain Access utility. I've confirmed that
    # this works
    puts password # => "MyPassword"
Comments (View)