Class: Straycall::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/straycall/config.rb

Constant Summary collapse

MODES =
%i[fail warn record prompt].freeze
TOP_LEVEL_KEYS =
%w[network write exec on_violation report_backtrace report_path].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfig

Returns a new instance of Config.



30
31
32
33
34
35
36
37
38
# File 'lib/straycall/config.rb', line 30

def initialize
  @network = Policy::Network.new
  @filesystem = Policy::Filesystem.new
  @exec = Policy::Exec.new
  @on_violation = :fail
  @report_backtrace = true
  @report_path = nil
  @allow_io_uring = false
end

Instance Attribute Details

#execObject (readonly)

Returns the value of attribute exec.



27
28
29
# File 'lib/straycall/config.rb', line 27

def exec
  @exec
end

#filesystemObject (readonly)

Returns the value of attribute filesystem.



27
28
29
# File 'lib/straycall/config.rb', line 27

def filesystem
  @filesystem
end

#networkObject (readonly)

Returns the value of attribute network.



27
28
29
# File 'lib/straycall/config.rb', line 27

def network
  @network
end

#report_backtraceObject

Returns the value of attribute report_backtrace.



28
29
30
# File 'lib/straycall/config.rb', line 28

def report_backtrace
  @report_backtrace
end

#report_pathObject

Returns the value of attribute report_path.



28
29
30
# File 'lib/straycall/config.rb', line 28

def report_path
  @report_path
end

Class Method Details

.load(path) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/straycall/config.rb', line 13

def self.load(path)
  data = YAML.safe_load_file(path, permitted_classes: [], aliases: false) || {}
  raise ConfigurationError, "configuration must be a mapping" unless data.is_a?(Hash)

  unknown = data.keys.map(&:to_s) - TOP_LEVEL_KEYS
  raise ConfigurationError, "unknown configuration keys: #{unknown.join(", ")}" unless unknown.empty?

  new.tap { |config| config.apply(data) }
rescue Psych::Exception => error
  raise ConfigurationError, "invalid YAML: #{error.message}"
rescue SystemCallError => error
  raise ConfigurationError, "cannot read configuration: #{error.message}"
end

Instance Method Details

#allow_exec(*paths) ⇒ Object



76
77
78
# File 'lib/straycall/config.rb', line 76

def allow_exec(*paths)
  paths.each { |path| exec.allow(path) }
end

#allow_exec_under(*paths) ⇒ Object



80
81
82
# File 'lib/straycall/config.rb', line 80

def allow_exec_under(*paths)
  paths.each { |path| exec.allow_under(path) }
end

#allow_host(host, ports: nil) ⇒ Object



52
53
54
# File 'lib/straycall/config.rb', line 52

def allow_host(host, ports: nil)
  network.allow_host(host, ports:)
end

#allow_io_uring!Object



92
93
94
# File 'lib/straycall/config.rb', line 92

def allow_io_uring!
  @allow_io_uring = true
end

#allow_loopback(ports: nil) ⇒ Object



44
45
46
# File 'lib/straycall/config.rb', line 44

def allow_loopback(ports: nil)
  network.allow_loopback(ports:)
end

#allow_socket_domain(domain) ⇒ Object



56
57
58
# File 'lib/straycall/config.rb', line 56

def allow_socket_domain(domain)
  network.allow_domain(domain)
end

#allow_unbound_listen!Object



60
61
62
# File 'lib/straycall/config.rb', line 60

def allow_unbound_listen!
  network.allow_unbound_listen!
end

#allow_unix(path) ⇒ Object



48
49
50
# File 'lib/straycall/config.rb', line 48

def allow_unix(path)
  network.allow_unix(path)
end

#allow_write_under(*paths) ⇒ Object



64
65
66
# File 'lib/straycall/config.rb', line 64

def allow_write_under(*paths)
  paths.each { |path| filesystem.allow_write_under(path) }
end

#apply(data) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/straycall/config.rb', line 125

def apply(data)
  apply_network(section(data, "network")) if key?(data, "network")
  apply_write(section(data, "write")) if key?(data, "write")
  apply_exec(section(data, "exec")) if key?(data, "exec")
  self.on_violation = fetch(data, "on_violation") if key?(data, "on_violation")
  self.report_backtrace = boolean(data, "report_backtrace") if key?(data, "report_backtrace")
  if key?(data, "report_path")
    raise ConfigurationError, "report_path must be a string" unless fetch(data, "report_path").is_a?(String)

    self.report_path = fetch(data, "report_path")
  end
  self
end

#deny_exec(*paths) ⇒ Object



88
89
90
# File 'lib/straycall/config.rb', line 88

def deny_exec(*paths)
  paths.each { |path| exec.deny(path) }
end

#deny_exec_elsewhere!Object



84
85
86
# File 'lib/straycall/config.rb', line 84

def deny_exec_elsewhere!
  exec.deny_elsewhere!
end

#deny_network!Object



40
41
42
# File 'lib/straycall/config.rb', line 40

def deny_network!
  network.deny!
end

#deny_read(*paths) ⇒ Object



72
73
74
# File 'lib/straycall/config.rb', line 72

def deny_read(*paths)
  paths.each { |path| filesystem.deny_read(path) }
end

#deny_write_elsewhere!Object



68
69
70
# File 'lib/straycall/config.rb', line 68

def deny_write_elsewhere!
  filesystem.deny_write_elsewhere!
end

#io_uring_allowed?Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/straycall/config.rb', line 96

def io_uring_allowed?
  @allow_io_uring
end

#on_violationObject



100
101
102
# File 'lib/straycall/config.rb', line 100

def on_violation
  @on_violation
end

#on_violation=(mode) ⇒ Object

Raises:



118
119
120
121
122
123
# File 'lib/straycall/config.rb', line 118

def on_violation=(mode)
  mode = mode.to_sym if mode.respond_to?(:to_sym)
  raise ConfigurationError, "on_violation must be one of: #{MODES.join(", ")}" unless MODES.include?(mode)

  @on_violation = mode
end