2024-06-24 03:38:24 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2024-06-25 08:25:53 +02:00
|
|
|
module BSD
|
|
|
|
end unless defined?(BSD)
|
|
|
|
|
|
|
|
module BSD::Capsicum
|
2024-06-25 05:08:23 +02:00
|
|
|
require_relative "capsicum/version"
|
2024-06-25 15:39:04 +02:00
|
|
|
require_relative "capsicum/constants"
|
2024-06-25 09:37:54 +02:00
|
|
|
require_relative "capsicum/ffi"
|
2024-06-25 05:42:37 +02:00
|
|
|
extend self
|
2024-06-25 03:48:14 +02:00
|
|
|
|
|
|
|
##
|
2024-06-25 09:46:47 +02:00
|
|
|
# Check if we're in capability mode
|
2017-05-24 17:33:39 +02:00
|
|
|
#
|
2024-06-25 09:16:17 +02:00
|
|
|
# @see https://man.freebsd.org/cgi/man.cgi?query=cap_getmode&apropos=0&sektion=2&format=html cap_getmode(2)
|
2024-06-25 03:48:14 +02:00
|
|
|
# @raise [SystemCallError]
|
|
|
|
# Might raise a subclass of SystemCallError
|
|
|
|
# @return [Boolean]
|
2024-06-25 05:07:00 +02:00
|
|
|
# Returns true when the current process is in capability mode
|
2024-06-25 03:56:42 +02:00
|
|
|
def in_capability_mode?
|
2024-06-23 23:18:33 +02:00
|
|
|
uintp = Fiddle::Pointer.malloc(Fiddle::SIZEOF_UINT)
|
2024-06-25 09:37:54 +02:00
|
|
|
if FFI.cap_getmode(uintp).zero?
|
2024-06-24 03:38:24 +02:00
|
|
|
uintp[0, Fiddle::SIZEOF_UINT].unpack("i") == [1]
|
2017-05-24 02:18:47 +02:00
|
|
|
else
|
2024-06-23 23:18:33 +02:00
|
|
|
raise SystemCallError.new("cap_getmode", Fiddle.last_error)
|
2017-05-24 02:18:47 +02:00
|
|
|
end
|
2024-06-23 23:18:33 +02:00
|
|
|
ensure
|
|
|
|
uintp.call_free
|
2017-05-24 02:18:47 +02:00
|
|
|
end
|
2024-06-25 05:42:37 +02:00
|
|
|
alias_method :capability_mode?, :in_capability_mode?
|
2017-05-24 02:18:47 +02:00
|
|
|
|
2024-06-25 03:48:14 +02:00
|
|
|
##
|
2024-06-25 05:52:16 +02:00
|
|
|
# Enter a process into capability mode
|
2017-05-24 17:33:39 +02:00
|
|
|
#
|
2024-06-25 09:16:17 +02:00
|
|
|
# @see https://man.freebsd.org/cgi/man.cgi?query=cap_enter&apropos=0&sektion=2&format=html cap_enter(2)
|
2024-06-25 03:48:14 +02:00
|
|
|
# @raise [SystemCallError]
|
|
|
|
# Might raise a subclass of SystemCallError
|
|
|
|
# @return [Boolean]
|
2024-06-25 05:52:16 +02:00
|
|
|
# Returns true when successful
|
2017-05-24 02:18:47 +02:00
|
|
|
def enter!
|
2024-06-25 09:42:27 +02:00
|
|
|
FFI.cap_enter.zero? ||
|
|
|
|
raise(SystemCallError.new("cap_enter", Fiddle.last_error))
|
2017-05-24 02:18:47 +02:00
|
|
|
end
|
2024-06-25 13:19:05 +02:00
|
|
|
alias_method :enter_capability_mode!, :enter!
|
2024-06-25 15:39:04 +02:00
|
|
|
|
|
|
|
##
|
2024-07-12 09:49:20 +02:00
|
|
|
# Limit the capabilities of a file descriptor
|
2024-06-25 15:39:04 +02:00
|
|
|
#
|
|
|
|
# @see https://man.freebsd.org/cgi/man.cgi?query=cap_rights_limit&apropos=0&sektion=2&format=html cap_rights_limit(2)
|
2024-06-27 06:35:34 +02:00
|
|
|
# @see BSD::Capsicum::Constants See Constants for a full list of capabilities
|
2024-06-25 15:39:04 +02:00
|
|
|
# @example
|
2024-06-27 06:32:51 +02:00
|
|
|
# # Restrict capabilities of STDOUT to read / write
|
|
|
|
# BSD::Capsicum.set_rights!(STDOUT, %i[CAP_READ CAP_WRITE])
|
2024-06-25 15:39:04 +02:00
|
|
|
# @raise [SystemCallError]
|
|
|
|
# Might raise a subclass of SystemCallError
|
|
|
|
# @param [#to_i] io
|
|
|
|
# An IO object
|
2024-07-12 09:19:26 +02:00
|
|
|
# @param [Array<String>] capabilities
|
2024-06-25 15:39:04 +02:00
|
|
|
# An allowed set of capabilities
|
|
|
|
# @return [Boolean]
|
|
|
|
# Returns true when successful
|
2024-07-12 09:19:26 +02:00
|
|
|
def set_rights!(io, capabilities)
|
|
|
|
rights = Fiddle::Pointer.malloc(Constants::SIZEOF_CAP_RIGHTS_T)
|
|
|
|
FFI.cap_rights_init(rights, *capabilities)
|
2024-07-12 09:46:29 +02:00
|
|
|
FFI.cap_rights_limit(io.to_i, rights).zero? ||
|
|
|
|
raise(SystemCallError.new("cap_rights_limit", Fiddle.last_error))
|
2024-06-25 15:39:04 +02:00
|
|
|
ensure
|
2024-07-12 09:19:26 +02:00
|
|
|
rights.call_free
|
2024-06-25 15:39:04 +02:00
|
|
|
end
|
2017-05-24 02:18:05 +02:00
|
|
|
end
|