bsdcapsicum.rb/lib/capsicum.rb

74 lines
1.6 KiB
Ruby
Raw Normal View History

2017-05-24 02:18:05 +02:00
require "capsicum/version"
2017-05-24 02:18:47 +02:00
require 'ffi'
2017-05-24 02:18:05 +02:00
module Capsicum
2017-05-24 02:18:47 +02:00
class IntPtr < FFI::Struct
layout :value, :int
end
module LibC
extend FFI::Library
ffi_lib [FFI::CURRENT_PROCESS, 'c']
attach_variable :errno, :int
attach_function :cap_enter, [], :int
attach_function :cap_getmode, [IntPtr], :int
end
2017-05-24 17:33:39 +02:00
# Check if we're in capability mode.
#
# @see cap_getmode(2)
#
# @return [Boolean] true if we've entered capability mode
# @raise [Errno::ENOTCAPABLE] - Capsicum not enabled.
2017-05-24 02:18:47 +02:00
def sandboxed?
ptr = IntPtr.new
ret = LibC.cap_getmode(ptr)
if ret == 0
ptr[:value] == 1
else
raise SystemCallError.new("cap_getmode", LibC.errno)
end
end
2017-05-24 17:33:39 +02:00
# Enter capability sandbox mode.
#
# @see cap_enter(2)
#
# @return [Boolean] true if we've entered capability mode.
# @raise [Errno::ENOTCAPABLE] - Capsicum not enabled.
2017-05-24 02:18:47 +02:00
def enter!
ret = LibC.cap_enter
if ret == 0
return true
else
raise SystemCallError.new("cap_enter", LibC.errno)
end
end
2017-05-24 17:33:39 +02:00
# Run the block within a forked process in capability mode and wait for it to
# complete.
#
# @yield block to run within the forked child.
# @return [Process::Status] exit status of the forked child.
2017-05-24 02:18:47 +02:00
def within_sandbox
raise NotImplementedError, "fork() not supported" unless Process.respond_to? :fork
2017-05-24 02:18:47 +02:00
return enum_for(:within_sandbox) unless block_given?
pid = fork do
Capsicum.enter!
yield
end
Process.waitpid2(pid).last
end
module_function :sandboxed?
module_function :enter!
module_function :within_sandbox
2017-05-24 02:18:05 +02:00
end