retrieving password from keychain
Hi there, I am having a strange problem that other people don't seem to be having because I can't find any references to in google searches. I am using MacRuby 0.4 installed from the binary available on the macruby binary releases page (MacRuby version 0.4 (ruby 1.9.1) [universal-darwin9.5, x86_64]) I have an application which stores username/passwords in the keychain. I can add items to the keychain (so I can call SecKeychainAddGenericPassword() fine and therefore I think my setup must be OK), but I cannot retrieve them. When I call: status, *data = SecKeychainFindGenericPassword( nil, service.length, service, username.length, username) I get an error: Configuration.app/Contents/Resources/Controller.rb:99:in `SecKeychainFindGenericPassword': wrong number of arguments (5 for 8) (ArgumentError) The method signature is this: OSStatus SecKeychainFindGenericPassword ( CFTypeRef keychainOrArray, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef ); All the examples I've read suggest that this method in macruby should only take 5 args and return the status, password length, password string and item reference (the last 3 extracted from *data) instead of passing in pointers (which I don't know how to do BTW). What gives? Anyone have any idea or had the same problem? -- Karl Varga kjvarga@gmail.com Cell: +61 (0)4 2075 1356
Hi Karl, On Apr 19, 2009, at 8:17 PM, Karl Varga wrote:
Hi there,
I am having a strange problem that other people don't seem to be having because I can't find any references to in google searches. I am using MacRuby 0.4 installed from the binary available on the macruby binary releases page (MacRuby version 0.4 (ruby 1.9.1) [universal-darwin9.5, x86_64])
I have an application which stores username/passwords in the keychain. I can add items to the keychain (so I can call SecKeychainAddGenericPassword() fine and therefore I think my setup must be OK), but I cannot retrieve them. When I call:
status, *data = SecKeychainFindGenericPassword( nil, service.length, service, username.length, username)
I get an error:
Configuration.app/Contents/Resources/Controller.rb:99:in `SecKeychainFindGenericPassword': wrong number of arguments (5 for 8) (ArgumentError)
The method signature is this:
OSStatus SecKeychainFindGenericPassword ( CFTypeRef keychainOrArray, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef );
All the examples I've read suggest that this method in macruby should only take 5 args and return the status, password length, password string and item reference (the last 3 extracted from *data) instead of passing in pointers (which I don't know how to do BTW).
What gives? Anyone have any idea or had the same problem?
I am surprised you were able to call SecKeychainFindGenericPassword() from MacRuby, did you generate a BridgeSupport file for the Security framework? As for your question, MacRuby currently doesn't support the RubyCocoa way of dealing with returned-by-reference arguments (which is what you're trying to do I think), so you must allocate Pointer objects instead. In the case of this call it may be painful, so I would recommend to wrap this in an Objective-C class in the interim and use that class from MacRuby. HTH, Laurent
Thanks for the reply Laurent. Yes I did generate a BridgeSupport file and included it in my build. I did try to call the method and pass in a pointer for the item reference (using Pointer.new_for_type('@')) but the object that was assigned after the call was some weird NSCFType object which, when I googled it, basically translates to "you're screwed" :) I do get some malloc warnings when I include the bridgesupport file so I was a bit uneasy about the whole thing. I'll try writing my own Objective-C class. I'm looking forward to getting past this issue. Cheers, Karl On Tue, Apr 21, 2009 at 6:44 AM, Laurent Sansonetti <lsansonetti@apple.com> wrote:
Hi Karl,
On Apr 19, 2009, at 8:17 PM, Karl Varga wrote:
Hi there,
I am having a strange problem that other people don't seem to be having because I can't find any references to in google searches. I am using MacRuby 0.4 installed from the binary available on the macruby binary releases page (MacRuby version 0.4 (ruby 1.9.1) [universal-darwin9.5, x86_64])
I have an application which stores username/passwords in the keychain. I can add items to the keychain (so I can call SecKeychainAddGenericPassword() fine and therefore I think my setup must be OK), but I cannot retrieve them. When I call:
status, *data = SecKeychainFindGenericPassword( nil, service.length, service, username.length, username)
I get an error:
Configuration.app/Contents/Resources/Controller.rb:99:in `SecKeychainFindGenericPassword': wrong number of arguments (5 for 8) (ArgumentError)
The method signature is this:
OSStatus SecKeychainFindGenericPassword ( CFTypeRef keychainOrArray, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef );
All the examples I've read suggest that this method in macruby should only take 5 args and return the status, password length, password string and item reference (the last 3 extracted from *data) instead of passing in pointers (which I don't know how to do BTW).
What gives? Anyone have any idea or had the same problem?
I am surprised you were able to call SecKeychainFindGenericPassword() from MacRuby, did you generate a BridgeSupport file for the Security framework?
As for your question, MacRuby currently doesn't support the RubyCocoa way of dealing with returned-by-reference arguments (which is what you're trying to do I think), so you must allocate Pointer objects instead. In the case of this call it may be painful, so I would recommend to wrap this in an Objective-C class in the interim and use that class from MacRuby.
HTH, Laurent
-- Karl Varga kjvarga@gmail.com Cell: +61 (0)4 2075 1356
Thanks for the reply Laurent. Yes I did generate a BridgeSupport file and included it in my build. I did try to call the method and pass in a pointer for the item reference (using Pointer.new_for_type('@')) but the object that was assigned after the call was some weird NSCFType object which, when I googled it, basically translates to "you're screwed" :) I do get some malloc warnings when I include the bridgesupport file so I was a bit uneasy about the whole thing.
Actually, in this particular case an NSCFType is exactly what you expect, since SecKeychainItemRef isn’t toll-free bridged with an Objective-C type. -Ben
participants (3)
-
Benjamin Stiglitz
-
Karl Varga
-
Laurent Sansonetti