Class: Keyutils::Key
- Inherits:
-
Object
- Object
- Keyutils::Key
- Defined in:
- lib/keyutils/key.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#id ⇒ Fixnum
(also: #to_i, #hash)
Numeric identifier of the key this object points to.
Class Method Summary collapse
-
.find(type, description, destination = nil) ⇒ Key?
Find a key by type and description.
-
.renounce_authority ⇒ void
De-assume the currently assumed authority.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Key equality.
-
#assume_authority ⇒ Key
Assume the authority to instantiate the key.
-
#chown(uid = nil, gid = nil) ⇒ Key
Change the user and group ownership details of the key.
-
#describe ⇒ Hash
Describe the attributes of the key.
-
#description ⇒ String
The key description.
-
#eql?(other) ⇒ Boolean
Key handle equality.
-
#exists? ⇒ Boolean
Check if this key exists in the kernel.
-
#gid ⇒ Fixnum
The key GID.
-
#instantiate(payload, destination = nil) ⇒ Key
Instantiate a key.
-
#invalidate ⇒ Key
Invalidate the key.
-
#perm ⇒ Fixnum
The key permission mask.
-
#read ⇒ String
(also: #to_s)
Read the key.
-
#reject(timeout_s, error = Errno::ENOKEY, destination = nil) ⇒ Key
Negatively instantiate a key.
-
#revoke ⇒ Key
Mark the key as being revoked.
-
#security ⇒ String
Retrieve the key’s security context.
-
#serial ⇒ Fixnum
Get the serial number of this key.
-
#set_timeout(timeout_s) ⇒ Key
Set the expiration timer on a key.
-
#setperm(permissions) ⇒ Key
Change the permissions mask on the key.
-
#type ⇒ Symbol
The key type name.
-
#uid ⇒ Fixnum
The key UID.
-
#update(payload) ⇒ Key
Update the payload of the key if the key type permits it.
Instance Attribute Details
#id ⇒ Fixnum Also known as: to_i, hash
Numeric identifier of the key this object points to.
9 10 11 |
# File 'lib/keyutils/key.rb', line 9 def id @id end |
Class Method Details
.find(type, description, destination = nil) ⇒ Key?
Find a key by type and description
Searches for a key with the given type and exact description, firstly in the thread, process and session keyrings to which a process is subscribed and secondly in /proc/keys.
If a key is found, and destination is not nil and specifies a keyring, then the found key will be linked into it.
525 526 527 528 529 530 531 532 533 |
# File 'lib/keyutils/key.rb', line 525 def find type, description, destination = nil serial = Lib.find_key_by_type_and_desc \ type.to_s, description, destination.to_i new_dispatch serial, type.intern, description rescue Errno::ENOKEY nil end |
.renounce_authority ⇒ void
This method returns an undefined value.
De-assume the currently assumed authority.
538 539 540 |
# File 'lib/keyutils/key.rb', line 538 def Lib. 0 end |
Instance Method Details
#==(other) ⇒ Boolean
Key equality
487 488 489 |
# File 'lib/keyutils/key.rb', line 487 def == other serial == other.serial end |
#assume_authority ⇒ Key
This is a per-thread setting and not a per-process setting so that a multithreaded process can be used to instantiate several keys at once.
Assume the authority to instantiate the key.
Assumes the authority for the calling thread to deal with and instantiate this uninstantiated key.
The calling thread must have the appropriate authorisation key resident in one of its keyrings for this to succeed, and that authority must not have been revoked.
The authorising key is allocated by request_key(2) when it needs to invoke userspace to generate a key for the requesting process. This is then attached to one of the keyrings of the userspace process to which the task of instantiating the key is given:
requester ⟶ request_key() ⟶ instantiator
Calling this function modifies the way request works when called thereafter by the calling (instantiator) thread; once the authority is assumed, the keyrings of the initial process are added to the search path, using the initial process’s UID, GID, groups and security context.
If a thread has multiple instantiations to deal with, it may call this function to change the authorisation key currently in effect.
386 387 388 389 |
# File 'lib/keyutils/key.rb', line 386 def Lib. id self end |
#chown(uid = nil, gid = nil) ⇒ Key
Change the user and group ownership details of the key.
A setting of -1 or nil on either uid or gid will cause that setting to be ignored.
A process that does not have the SysAdmin capability may not change a key’s UID or set the key’s GID to a value that does not match the process’s GID or one of its group list.
The caller must have setattr permission on a key to be able change its ownership.
123 124 125 126 |
# File 'lib/keyutils/key.rb', line 123 def chown uid = nil, gid = nil Lib.keyctl_chown id, uid || -1, gid || -1 self end |
#describe ⇒ Hash
Describe the attributes of the key.
The caller must have view permission on a key to be able to get attributes of it.
Attributes are returned as a hash of the following keys:
-
:type[Symbol], -
:uid[Fixnum], -
:gid[Fixnum], -
:perm[Fixnum], -
:desc[String].
243 244 245 246 247 248 249 250 251 |
# File 'lib/keyutils/key.rb', line 243 def describe buf = FFI::MemoryPointer.new :char, 64 len = Lib.keyctl_describe id, buf, buf.size while len > buf.size buf = FFI::MemoryPointer.new :char, len len = Lib.keyctl_describe id, buf, buf.size end Key.send :parse_describe, buf.read_string(len - 1) end |
#description ⇒ String
Returns the key description.
194 195 196 |
# File 'lib/keyutils/key.rb', line 194 def description @description ||= describe[:desc] end |
#eql?(other) ⇒ Boolean
Key handle equality
Same as #==, except it doesn’t dereference the special handles such as Keyutils::Keyring::Session. This means #eql? can be false even if the argument points to the same keyring, as long as only one of them is a special handle.
500 501 502 |
# File 'lib/keyutils/key.rb', line 500 def eql? other to_i == other.to_i end |
#exists? ⇒ Boolean
Check if this key exists in the kernel.
The key may not exist eg. if it has been removed by another process, or if this is a special keyring handle (such as Keyutils::Keyring::Thread) and the keyring has not been instantiated yet.
43 44 45 46 47 48 49 |
# File 'lib/keyutils/key.rb', line 43 def exists? Lib.keyctl_get_keyring_ID(id, false) && true rescue Errno::EACCES true rescue Errno::ENOKEY false end |
#gid ⇒ Fixnum
Returns the key GID.
210 211 212 |
# File 'lib/keyutils/key.rb', line 210 def gid describe[:gid] end |
#instantiate(payload, destination = nil) ⇒ Key
Instantiate a key
Instantiate the payload of an uninstantiated key from the data specified. payload specifies the data for the new payload. payload may be nil if the key type permits that. The key type may reject the data if it’s in the wrong format or in some other way invalid.
Only a key for which authority has been assumed may be instantiated or negatively instantiated, and once instantiated, the authorisation key will be revoked and the requesting process will be able to resume.
The destination keyring, if given, is assumed to belong to the initial requester, and not the instantiating process. Therefore, the special keyring objects (such as Keyutils::Keyring::Session) refer to the requesting process’s keyrings, not the caller’s, and the requester’s UID, etc. will be used to access them.
The destination keyring can be nil if no extra link is desired.
The requester, not the caller, must have write permission on the destination for a link to be made there.
318 319 320 321 322 323 324 |
# File 'lib/keyutils/key.rb', line 318 def instantiate payload, destination = nil Lib.keyctl_instantiate id, payload && payload.to_s, payload && payload.to_s.length || 0, destination.to_i self end |
#invalidate ⇒ Key
Invalidate the key.
The key is scheduled for immediate removal from all the keyrings that point to it, after which it will be deleted. The key will be ignored by all searches once this function is called even if it is not yet fully dealt with.
The caller must have search permission on a key to be able to invalidate it.
478 479 480 481 |
# File 'lib/keyutils/key.rb', line 478 def invalidate Lib.keyctl_invalidate id self end |
#perm ⇒ Fixnum
Returns the key permission mask.
217 218 219 |
# File 'lib/keyutils/key.rb', line 217 def perm describe[:perm] end |
#read ⇒ String Also known as: to_s
Read the key.
Reads the payload of a key if the key type supports it.
The caller must have read permission on a key to be able to read it.
267 268 269 270 271 272 273 274 275 |
# File 'lib/keyutils/key.rb', line 267 def read buf = FFI::MemoryPointer.new :char, 64 len = Lib.keyctl_read id, buf, buf.size while len > buf.size buf = FFI::MemoryPointer.new :char, len len = Lib.keyctl_read id, buf, buf.size end buf.read_string len end |
#reject(timeout_s, error = Errno::ENOKEY, destination = nil) ⇒ Key
On some kernel versions error setting is not supported. In this case it will fall back to always raising Errno::ENOKEY.
Negatively instantiate a key
Marks a key as negatively instantiated and sets the expiration timer on it. Attempts to access the key will raise the given error.
Only a key for which authority has been assumed may be negatively instantiated, and once instantiated, the authorisation key will be revoked and the requesting process will be able to resume.
The destination keyring, if given, is assumed to belong to the initial requester, and not the instantiating process. Therefore, the special keyring objects (such as Keyutils::Keyring::Session) refer to the requesting process’s keyrings, not the caller’s, and the requester’s UID, etc. will be used to access them.
The destination keyring can be nil if no extra link is desired.
The requester, not the caller, must have write permission on the destination for a link to be made there.
458 459 460 461 |
# File 'lib/keyutils/key.rb', line 458 def reject timeout_s, error = Errno::ENOKEY, destination = nil Lib.keyctl_reject id, timeout_s, error::Errno, keyring.to_i self end |
#revoke ⇒ Key
Mark the key as being revoked.
After this operation has been performed on a key, attempts to access it will meet with error EKEYREVOKED.
The caller must have write permission on a key to be able revoke it.
93 94 95 96 |
# File 'lib/keyutils/key.rb', line 93 def revoke Lib.keyctl_revoke id self end |
#security ⇒ String
Retrieve the key’s security context.
This will be rendered in a form appropriate to the LSM in force—for instance, with SELinux, it may look like
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
The caller must have view permission on a key to be able to get its security context.
406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/keyutils/key.rb', line 406 def security return @security if @security buf = FFI::MemoryPointer.new :char, 64 len = Lib.keyctl_get_security id, buf, buf.size while len > buf.size buf = FFI::MemoryPointer.new :char, len len = Lib.keyctl_get_security id, buf, buf.size end @security = buf.read_string (len - 1) end |
#serial ⇒ Fixnum
Get the serial number of this key.
For ordinary keys, #serial == #id, and this method always succeeds.
For special key handles (such as Keyutils::Keyring::Session), this method will resolve the actual serial number of the key it points to.
Note if this is a special key handle and the key(ring) is not already instantiated, calling this method will attempt to create it. For this reason it can fail if memory or quota is exhausted.
31 32 33 34 |
# File 'lib/keyutils/key.rb', line 31 def serial return id unless id < 0 Lib.keyctl_get_keyring_ID id, true end |
#set_timeout(timeout_s) ⇒ Key
Set the expiration timer on a key
Sets the expiration timer on a key to timeout_s seconds into the future. Setting timeout to zero cancels the expiration, assuming the key hasn’t already expired.
When the key expires, further attempts to access it will be met with error EKEYEXPIRED.
The caller must have setattr permission on a key to be able change its timeout.
345 346 347 348 |
# File 'lib/keyutils/key.rb', line 345 def set_timeout timeout_s Lib.keyctl_set_timeout id, timeout_s self end |
#setperm(permissions) ⇒ Key
Change the permissions mask on the key.
A process that does not have the SysAdmin capability may not change the permissions mask on a key that doesn’t have the same UID as the caller.
The caller must have setattr permission on a key to be able change its permissions mask.
The permissions mask is a bitwise-OR of the following flags:
-
KEY_xxx_VIEWGrant permission to view the attributes of a key. -
KEY_xxx_READGrant permission to read the payload of a key or to list a keyring. -
KEY_xxx_WRITEGrant permission to modify the payload of a key or to add or remove links to/from a keyring. -
KEY_xxx_SEARCHGrant permission to find a key or to search a keyring. -
KEY_xxx_LINKGrant permission to make links to a key. -
KEY_xxx_SETATTRGrant permission to change the ownership and permissions attributes of a key. -
KEY_xxx_ALLGrant all the above.
The ‘xxx’ in the above should be replaced by one of:
-
POSGrant the permission to a process that possesses the key (has it attached searchably to one of the process’s keyrings). -
USRGrant the permission to a process with the same UID as the key. -
GRPGrant the permission to a process with the same GID as the key, or with a match for the key’s GID amongst that process’s Groups list. -
OTHGrant the permission to any other process.
Examples include: Keyutils::KeyPerm::KEY_POS_VIEW, Keyutils::KeyPerm::KEY_USR_READ, Keyutils::KeyPerm::KEY_GRP_SEARCH and Keyutils::KeyPerm::KEY_OTH_ALL.
User, group and other grants are exclusive: if a process qualifies in the ‘user’ category, it will not qualify in the ‘groups’ category; and if a process qualifies in either ‘user’ or ‘groups’ then it will not qualify in the ‘other’ category.
Possessor grants are cumulative with the grants from the ‘user’, ‘groups’ and ‘other’ categories.
183 184 185 186 |
# File 'lib/keyutils/key.rb', line 183 def setperm Lib.keyctl_setperm id, self end |
#type ⇒ Symbol
Returns the key type name.
189 190 191 |
# File 'lib/keyutils/key.rb', line 189 def type @type ||= describe[:type] end |
#uid ⇒ Fixnum
Returns the key UID.
202 203 204 |
# File 'lib/keyutils/key.rb', line 202 def uid describe[:uid] end |
#update(payload) ⇒ Key
Update the payload of the key if the key type permits it.
The caller must have write permission on the key to be able to update it.
payload specifies the data for the new payload; it may be nil if the key type permits that. The key type may reject the data if it’s in the wrong format or in some other way invalid.
72 73 74 75 76 77 78 |
# File 'lib/keyutils/key.rb', line 72 def update payload Lib.keyctl_update \ id, payload && payload.to_s, payload && payload.to_s.length || 0 self end |