class Keychain::Keychain
Wrapper class for individual keychains. Corresponds to a SecKeychainRef
Public Instance Methods
Add the keychain to the default searchlist
# File lib/keychain/keychain.rb, line 60 def add_to_search_list list = FFI::MemoryPointer.new(:pointer) status = Sec.SecKeychainCopySearchList(list) Sec.check_osstatus(status) ruby_list = CF::Base.typecast(list.read_pointer).release_on_gc.to_ruby ruby_list << self unless ruby_list.include?(self) status = Sec.SecKeychainSetSearchList(CF::Array.immutable(ruby_list)) Sec.check_osstatus(status) self end
Removes the keychain from the search path and deletes the corresponding file (SecKeychainDelete)
See developer.apple.com/library/mac/documentation/security/Reference/keychainservices/Reference/reference.html#//apple_ref/c/func/SecKeychainDelete @return self
# File lib/keychain/keychain.rb, line 159 def delete status = Sec.SecKeychainDelete(self) Sec.check_osstatus(status) self end
# File lib/keychain/keychain.rb, line 219 def exists? begin readable? true rescue NoSuchKeychainError false end end
Returns a scope for generic passwords contained in this keychain
@return [Keychain::Scope] a new scope object
# File lib/keychain/keychain.rb, line 112 def generic_passwords Scope.new(Sec::Classes::GENERIC, self) end
Imports item from string or file to this keychain
@param [IO, String] input IO object or String with raw data to import @param [Array <String>] app_list List of applications which will be permitted to access imported items @return [Array <SecKeychainItem>] List of imported keychain objects, each of which may be a SecCertificate, SecKey, or SecIdentity instance
# File lib/keychain/keychain.rb, line 123 def import(input, app_list=[]) input = input.read if input.is_a? IO # Create array of TrustedApplication objects trusted_apps = get_trusted_apps(app_list) # Create an Access object access_buffer = FFI::MemoryPointer.new(:pointer) status = Sec.SecAccessCreate(path.to_cf, trusted_apps, access_buffer) Sec.check_osstatus status access = CF::Base.typecast(access_buffer.read_pointer) key_params = Sec::SecItemImportExportKeyParameters.new key_params[:accessRef] = access # Import item to the keychain cf_data = CF::Data.from_string(input).release_on_gc cf_array = FFI::MemoryPointer.new(:pointer) status = Sec.SecItemImport(cf_data, nil, :kSecFormatUnknown, :kSecItemTypeUnknown, :kSecItemPemArmour, key_params, self, cf_array) access.release Sec.check_osstatus status item_array = CF::Base.typecast(cf_array.read_pointer).release_on_gc item_array.to_ruby end
returns a description of the keychain @return [String]
# File lib/keychain/keychain.rb, line 151 def inspect "<SecKeychain 0x#{@ptr.address.to_s(16)}: #{path}>" end
Returns a scope for internet passwords contained in this keychain
@return [Keychain::Scope] a new scope object
# File lib/keychain/keychain.rb, line 105 def internet_passwords Scope.new(Sec::Classes::INTERNET, self) end
Locks the keychain
# File lib/keychain/keychain.rb, line 183 def lock! status = Sec.SecKeychainLock(self) Sec.check_osstatus status end
Returns the duration (in seconds) after which the keychain will be locked
@return [Boolean]
# File lib/keychain/keychain.rb, line 82 def lock_interval get_settings[:lock_interval] end
Sets the duration (in seconds) after which the keychain will be locked
@param [Integer] value dutarion in seconds
# File lib/keychain/keychain.rb, line 98 def lock_interval= value put_settings(get_settings.tap {|s| s[:lock_interval] = value}) end
Set whether the keychain will be locked if the machine goes to sleep
@param [Boolean] value
# File lib/keychain/keychain.rb, line 90 def lock_on_sleep= value put_settings(get_settings.tap {|s| s[:lock_on_sleep] = value ? 1 : 0}) end
Returns whether the keychain will be locked if the machine goes to sleep
@return [Boolean]
# File lib/keychain/keychain.rb, line 74 def lock_on_sleep? get_settings[:lock_on_sleep] != 0 end
Returns whether the keychain is locked @return [Boolean]
# File lib/keychain/keychain.rb, line 203 def locked? !status_flag?(:kSecUnlockStateStatus) end
Returns the path at which the keychain is stored
@return [String] path to the keychain file
# File lib/keychain/keychain.rb, line 170 def path out_buffer = FFI::MemoryPointer.new(:uchar, 2048) io_size = FFI::MemoryPointer.new(:uint32) io_size.put_uint32(0, out_buffer.size) status = Sec.SecKeychainGetPath(self,io_size, out_buffer) Sec.check_osstatus(status) out_buffer.read_string(io_size.get_uint32(0)).force_encoding(Encoding::UTF_8) end
Returns whether the keychain is readable @return [Boolean]
# File lib/keychain/keychain.rb, line 209 def readable? status_flag?(:kSecReadPermStatus) end
Unlocks the keychain
@param [optional, String] password the password to unlock the keychain with. If no password is supplied the keychain will prompt the user for a password
# File lib/keychain/keychain.rb, line 191 def unlock! password=nil if password password = password.encode(Encoding::UTF_8) status = Sec.SecKeychainUnlock self, password.bytesize, password, 1 else status = Sec.SecKeychainUnlock self, 0, nil, 0 end Sec.check_osstatus status end
Returns whether the keychain is writable @return [Boolean]
# File lib/keychain/keychain.rb, line 215 def writeable? status_flag?(:kSecWritePermStatus) end
Private Instance Methods
# File lib/keychain/keychain.rb, line 237 def get_settings settings = Sec::KeychainSettings.new settings[:version] = 1 status = Sec.SecKeychainCopySettings(self, settings) Sec.check_osstatus status settings end
# File lib/keychain/keychain.rb, line 245 def get_trusted_apps apps trusted_app_array = apps.map do |path| trusted_app_buffer = FFI::MemoryPointer.new(:pointer) status = Sec.SecTrustedApplicationCreateFromPath( path.encode(Encoding::UTF_8), trusted_app_buffer) Sec.check_osstatus(status) CF::Base.typecast(trusted_app_buffer.read_pointer).release_on_gc end trusted_app_array.to_cf end
# File lib/keychain/keychain.rb, line 256 def put_settings settings status = Sec.SecKeychainSetSettings(self, settings) Sec.check_osstatus status settings end
# File lib/keychain/keychain.rb, line 230 def status_flag? enum_name out = FFI::MemoryPointer.new(:uint32) status = Sec.SecKeychainGetStatus(self,out); Sec.check_osstatus status (out.get_uint32(0) & Sec.enum_value(enum_name)).nonzero? end