Class: Keychain::Keychain

Inherits:
Sec::Base
  • Object
show all
Defined in:
lib/keychain/keychain.rb

Overview

Wrapper class for individual keychains. Corresponds to a SecKeychainRef

Instance Attribute Summary

Attributes inherited from Sec::Base

#attributes

Instance Method Summary collapse

Methods inherited from Sec::Base

define_attributes, #initialize, #keychain, #load_attributes, register_type, #update_self_from_dictionary

Constructor Details

This class inherits a constructor from Sec::Base

Instance Method Details

#add_to_search_listObject

Add the keychain to the default searchlist



60
61
62
63
64
65
66
67
68
69
# 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

#deleteObject

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

Returns:

  • self



159
160
161
162
163
# File 'lib/keychain/keychain.rb', line 159

def delete
  status = Sec.SecKeychainDelete(self)
  Sec.check_osstatus(status)
  self
end

#exists?Boolean

Returns:

  • (Boolean)


219
220
221
222
223
224
225
226
# File 'lib/keychain/keychain.rb', line 219

def exists?
  begin
    readable?
    true
  rescue NoSuchKeychainError
    false
  end
end

#generic_passwordsKeychain::Scope

Returns a scope for generic passwords contained in this keychain

Returns:



112
113
114
# File 'lib/keychain/keychain.rb', line 112

def generic_passwords
  Scope.new(Sec::Classes::GENERIC, self)
end

#import(input, app_list = []) ⇒ Array <SecKeychainItem>

Imports item from string or file to this keychain

permitted to access imported items each of which may be a SecCertificate, SecKey, or SecIdentity instance

Parameters:

  • input (IO, String)

    IO object or String with raw data to import

  • app_list (Array <String>) (defaults to: [])

    List of applications which will be

Returns:

  • (Array <SecKeychainItem>)

    List of imported keychain objects,



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# 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)
  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

#inspectString

returns a description of the keychain

Returns:

  • (String)


151
152
153
# File 'lib/keychain/keychain.rb', line 151

def inspect
  "<SecKeychain 0x#{@ptr.address.to_s(16)}: #{path}>"
end

#internet_passwordsKeychain::Scope

Returns a scope for internet passwords contained in this keychain

Returns:



105
106
107
# File 'lib/keychain/keychain.rb', line 105

def internet_passwords
  Scope.new(Sec::Classes::INTERNET, self)
end

#lock!Object

Locks the keychain



183
184
185
186
# File 'lib/keychain/keychain.rb', line 183

def lock!
  status = Sec.SecKeychainLock(self)
  Sec.check_osstatus status
end

#lock_intervalBoolean

Returns the duration (in seconds) after which the keychain will be locked

Returns:

  • (Boolean)


82
83
84
# File 'lib/keychain/keychain.rb', line 82

def lock_interval
  get_settings[:lock_interval]
end

#lock_interval=(value) ⇒ Object

Sets the duration (in seconds) after which the keychain will be locked

Parameters:

  • value (Integer)

    dutarion in seconds



98
99
100
# File 'lib/keychain/keychain.rb', line 98

def lock_interval= value
  put_settings(get_settings.tap {|s| s[:lock_interval] = value})
end

#lock_on_sleep=(value) ⇒ Object

Set whether the keychain will be locked if the machine goes to sleep

Parameters:

  • value (Boolean)


90
91
92
# 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

#lock_on_sleep?Boolean

Returns whether the keychain will be locked if the machine goes to sleep

Returns:

  • (Boolean)


74
75
76
# File 'lib/keychain/keychain.rb', line 74

def lock_on_sleep?
  get_settings[:lock_on_sleep] != 0
end

#locked?Boolean

Returns whether the keychain is locked

Returns:

  • (Boolean)


203
204
205
# File 'lib/keychain/keychain.rb', line 203

def locked?
  !status_flag?(:kSecUnlockStateStatus)
end

#pathString

Returns:

  • (String)

    path to the keychain file



170
171
172
173
174
175
176
177
178
179
# 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

#readable?Boolean

Returns whether the keychain is readable

Returns:

  • (Boolean)


209
210
211
# File 'lib/keychain/keychain.rb', line 209

def readable?
  status_flag?(:kSecReadPermStatus)
end

#unlock!(password = nil) ⇒ Object

Unlocks the keychain

Parameters:

  • password (optional, String) (defaults to: nil)

    the password to unlock the keychain with. If no password is supplied the keychain will prompt the user for a password



191
192
193
194
195
196
197
198
199
# 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

#writeable?Boolean

Returns whether the keychain is writable

Returns:

  • (Boolean)


215
216
217
# File 'lib/keychain/keychain.rb', line 215

def writeable?
  status_flag?(:kSecWritePermStatus)
end