mxc 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Cargo.lock +1500 -0
- data/Cargo.toml +6 -0
- data/LICENSE +21 -0
- data/NOTICE +34 -0
- data/README.md +140 -0
- data/ext/mxc/Cargo.toml +18 -0
- data/ext/mxc/build.rs +28 -0
- data/ext/mxc/extconf.rb +24 -0
- data/ext/mxc/src/lib.rs +384 -0
- data/ext/mxc/src/proxy.rs +480 -0
- data/lib/mxc/availability.rb +45 -0
- data/lib/mxc/backend.rb +36 -0
- data/lib/mxc/chunk.rb +33 -0
- data/lib/mxc/configuration.rb +28 -0
- data/lib/mxc/error.rb +36 -0
- data/lib/mxc/native.rb +29 -0
- data/lib/mxc/preflight.rb +82 -0
- data/lib/mxc/process.rb +100 -0
- data/lib/mxc/result.rb +63 -0
- data/lib/mxc/sandbox.rb +366 -0
- data/lib/mxc/startup_failure.rb +42 -0
- data/lib/mxc/version.rb +6 -0
- data/lib/mxc/windows_arguments.rb +18 -0
- data/lib/mxc.rb +109 -0
- metadata +87 -0
data/lib/mxc.rb
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'mxc/version'
|
|
4
|
+
require 'mxc/error'
|
|
5
|
+
require 'mxc/configuration'
|
|
6
|
+
require 'mxc/native'
|
|
7
|
+
require 'mxc/preflight'
|
|
8
|
+
require 'mxc/startup_failure'
|
|
9
|
+
require 'mxc/chunk'
|
|
10
|
+
require 'mxc/result'
|
|
11
|
+
require 'mxc/backend'
|
|
12
|
+
require 'mxc/availability'
|
|
13
|
+
require 'mxc/process'
|
|
14
|
+
require 'mxc/windows_arguments'
|
|
15
|
+
require 'mxc/sandbox'
|
|
16
|
+
|
|
17
|
+
# Runs commands in sandboxes through Microsoft's MXC.
|
|
18
|
+
#
|
|
19
|
+
# result = MXC.run("python3 build.py", readable: "app/skills", writable: "tmp/out", timeout: 30)
|
|
20
|
+
# result.stdout
|
|
21
|
+
module MXC
|
|
22
|
+
@availability = {}
|
|
23
|
+
@availability_lock = Mutex.new
|
|
24
|
+
|
|
25
|
+
class << self
|
|
26
|
+
# Returns the global Configuration.
|
|
27
|
+
def config
|
|
28
|
+
@config ||= Configuration.new
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Yields the global Configuration to change the defaults every sandbox starts from.
|
|
32
|
+
#
|
|
33
|
+
# MXC.configure do |config|
|
|
34
|
+
# config.timeout = 60
|
|
35
|
+
# end
|
|
36
|
+
def configure
|
|
37
|
+
yield config
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns a new Sandbox, optionally configured with the same keywords as Sandbox.new.
|
|
41
|
+
def sandbox(**)
|
|
42
|
+
Sandbox.new(**)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Runs +command+ in a new sandbox and returns its Result. Takes the command the same
|
|
46
|
+
# way as Sandbox#run, one String for the shell or a program and its arguments, and the
|
|
47
|
+
# same keywords as Sandbox.new. A block receives each Chunk of output as it arrives.
|
|
48
|
+
#
|
|
49
|
+
# MXC.run("python3 build.py", readable: "app/skills", timeout: 30)
|
|
50
|
+
# MXC.run("python3", "convert.py", params[:filename], readable: "app/skills")
|
|
51
|
+
def run(*command, **, &)
|
|
52
|
+
sandbox(**).run(*command, &)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Starts +command+ in a new sandbox and returns its Process. Takes the command the
|
|
56
|
+
# same way as Sandbox#run, and the same keywords as Sandbox.new.
|
|
57
|
+
#
|
|
58
|
+
# MXC.spawn("python3", "-i", "-q", timeout: 60)
|
|
59
|
+
def spawn(*command, **)
|
|
60
|
+
sandbox(**).spawn(*command)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Returns true when this host can start a sandbox with +backend+.
|
|
64
|
+
#
|
|
65
|
+
# The answer comes from starting one real sandbox, once per backend and process.
|
|
66
|
+
def supported?(backend: config.backend)
|
|
67
|
+
availability(backend:).supported?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Returns the Availability of +backend+ on this host, with the reason and remediation
|
|
71
|
+
# when it is unsupported. Pass <tt>refresh: true</tt> to probe the host again.
|
|
72
|
+
def availability(backend: config.backend, refresh: false)
|
|
73
|
+
backend = Sandbox.backend_name(backend)
|
|
74
|
+
@availability_lock.synchronize do
|
|
75
|
+
@availability.delete(backend) if refresh
|
|
76
|
+
@availability[backend] ||= Availability.probe(backend)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Returns the sandbox backends MXC finds on this host, as Backend objects.
|
|
81
|
+
def backends
|
|
82
|
+
Native.backend_attributes.map { |attributes| Backend.new(**attributes) }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Returns true when this host supports +capability+ with the configured backend.
|
|
86
|
+
#
|
|
87
|
+
# +capability+ is <tt>:network</tt> for unrestricted network access,
|
|
88
|
+
# <tt>:network_policy</tt> for host allow-lists, or any capability a Backend reports.
|
|
89
|
+
def supports?(capability)
|
|
90
|
+
return false unless supported?
|
|
91
|
+
|
|
92
|
+
case capability
|
|
93
|
+
when :network then Preflight.problem(network: true).nil?
|
|
94
|
+
when :network_policy then Preflight.problem(network: { allow: [] }).nil? && proxy_enforcement?
|
|
95
|
+
else configured_backends.any? { |backend| backend.supports?(capability) }
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
def proxy_enforcement?
|
|
102
|
+
!Preflight.linux? || configured_backends.any? { |backend| backend.supports?(:proxy_enforcement) }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def configured_backends
|
|
106
|
+
backends.select { |backend| config.backend == :auto || backend.name == config.backend }
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mxc
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Carmine Paolino
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rb_sys
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.9.130
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 0.9.130
|
|
26
|
+
description: An unofficial Ruby binding to Microsoft's MXC. Run commands in Bubblewrap,
|
|
27
|
+
Seatbelt or Windows ProcessContainer sandboxes with filesystem, network, environment
|
|
28
|
+
and timeout policies.
|
|
29
|
+
email:
|
|
30
|
+
- carmine@paolino.me
|
|
31
|
+
executables: []
|
|
32
|
+
extensions:
|
|
33
|
+
- ext/mxc/extconf.rb
|
|
34
|
+
extra_rdoc_files: []
|
|
35
|
+
files:
|
|
36
|
+
- Cargo.lock
|
|
37
|
+
- Cargo.toml
|
|
38
|
+
- LICENSE
|
|
39
|
+
- NOTICE
|
|
40
|
+
- README.md
|
|
41
|
+
- ext/mxc/Cargo.toml
|
|
42
|
+
- ext/mxc/build.rs
|
|
43
|
+
- ext/mxc/extconf.rb
|
|
44
|
+
- ext/mxc/src/lib.rs
|
|
45
|
+
- ext/mxc/src/proxy.rs
|
|
46
|
+
- lib/mxc.rb
|
|
47
|
+
- lib/mxc/availability.rb
|
|
48
|
+
- lib/mxc/backend.rb
|
|
49
|
+
- lib/mxc/chunk.rb
|
|
50
|
+
- lib/mxc/configuration.rb
|
|
51
|
+
- lib/mxc/error.rb
|
|
52
|
+
- lib/mxc/native.rb
|
|
53
|
+
- lib/mxc/preflight.rb
|
|
54
|
+
- lib/mxc/process.rb
|
|
55
|
+
- lib/mxc/result.rb
|
|
56
|
+
- lib/mxc/sandbox.rb
|
|
57
|
+
- lib/mxc/startup_failure.rb
|
|
58
|
+
- lib/mxc/version.rb
|
|
59
|
+
- lib/mxc/windows_arguments.rb
|
|
60
|
+
homepage: https://crmne.github.io/mxc/
|
|
61
|
+
licenses:
|
|
62
|
+
- MIT
|
|
63
|
+
metadata:
|
|
64
|
+
homepage_uri: https://crmne.github.io/mxc/
|
|
65
|
+
source_code_uri: https://github.com/crmne/mxc
|
|
66
|
+
bug_tracker_uri: https://github.com/crmne/mxc/issues
|
|
67
|
+
changelog_uri: https://github.com/crmne/mxc/releases
|
|
68
|
+
funding_uri: https://github.com/sponsors/crmne
|
|
69
|
+
rubygems_mfa_required: 'true'
|
|
70
|
+
rdoc_options: []
|
|
71
|
+
require_paths:
|
|
72
|
+
- lib
|
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
74
|
+
requirements:
|
|
75
|
+
- - ">="
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: 3.2.0
|
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
requirements: []
|
|
84
|
+
rubygems_version: 4.0.20
|
|
85
|
+
specification_version: 4
|
|
86
|
+
summary: Run untrusted commands in OS sandboxes from Ruby, through Microsoft's MXC.
|
|
87
|
+
test_files: []
|