hrr_rb_ssh 0.2.2 → 0.3.0.pre1
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 +4 -4
- data/.travis.yml +3 -3
- data/README.md +22 -3
- data/demo/echo_server.rb +2 -2
- data/demo/server.rb +2 -2
- data/demo/subsystem_echo_server.rb +2 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env/context.rb +6 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env.rb +2 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec/context.rb +6 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec.rb +2 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req/context.rb +6 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req.rb +2 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell/context.rb +6 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell.rb +2 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb +6 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem.rb +2 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb +6 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change.rb +2 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session.rb +1 -1
- data/lib/hrr_rb_ssh/server.rb +12 -6
- data/lib/hrr_rb_ssh/transport.rb +1 -1
- data/lib/hrr_rb_ssh/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08be357edfafa61b913c4f28f6d97a29e7aa0c94eaef933a3ea2dce9bc51c9a3'
|
4
|
+
data.tar.gz: 4b87367e0ac95045fcfac372fd1e8735e896436a2d26a2987b94daad2244379f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f830b32cb263e45ca84596b310889cee768fcf870fc78093c818d2a8dff9fa59c09c334bb7942bf56b344d6d9ce9bcff609962880fcd7e4ac9b74aa1a703c8a5
|
7
|
+
data.tar.gz: 31f317c5fc929b0b04b78fa19d9f85be1f9e4aef4c57474e8fe06039e8f947818eb7e0033da21b80bd9f7e8fa8d3a544c348a468ba31da4cf509812013b2a550
|
data/.travis.yml
CHANGED
@@ -10,6 +10,7 @@ rvm:
|
|
10
10
|
- 2.3
|
11
11
|
- 2.4
|
12
12
|
- 2.5
|
13
|
+
- 2.6
|
13
14
|
- ruby-head
|
14
15
|
os:
|
15
16
|
- linux
|
@@ -17,10 +18,9 @@ matrix:
|
|
17
18
|
allow_failures:
|
18
19
|
- rvm: ruby-head
|
19
20
|
before_install:
|
20
|
-
- gem
|
21
|
-
- gem
|
21
|
+
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
|
22
|
+
- gem install bundler -v '< 2'
|
22
23
|
install:
|
23
|
-
- gem install bundler --no-document
|
24
24
|
- bundle install --path vendor/bundle
|
25
25
|
before_script:
|
26
26
|
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
data/README.md
CHANGED
@@ -27,6 +27,7 @@ With hrr_rb_ssh, it is possible to write an SSH server easily, and also possible
|
|
27
27
|
- [Reference request handlers](#reference-request-handlers)
|
28
28
|
- [Custom request handlers](#custom-request-handlers)
|
29
29
|
- [Defining preferred algorithms (optional)](#defining-preferred-algorithms-optional)
|
30
|
+
- [Hiding and/or simulating local SSH version](#hiding-and-or-simulating-local-ssh-version)
|
30
31
|
- [Demo](#demo)
|
31
32
|
- [Supported Features](#supported-features)
|
32
33
|
- [Connection layer](#connection-layer)
|
@@ -79,8 +80,8 @@ loop do
|
|
79
80
|
Thread.new(server.accept) do |io|
|
80
81
|
pid = fork do
|
81
82
|
begin
|
82
|
-
server = HrrRbSsh::Server.new
|
83
|
-
server.start
|
83
|
+
server = HrrRbSsh::Server.new options
|
84
|
+
server.start io
|
84
85
|
ensure
|
85
86
|
io.close
|
86
87
|
end
|
@@ -274,7 +275,8 @@ options['connection_channel_request_shell'] = conn_echo
|
|
274
275
|
In `HrrRbSsh::Connection::RequestHandler.new` block, context variable basically provides the followings.
|
275
276
|
|
276
277
|
- `#io => [in, out, err]` : `in` is readable and read data is sent by remote. `out` and `err` are writable. `out` is for standard output and written data is sent as channel data. `err` is for standard error and written data is sent as channel extended data.
|
277
|
-
- `#chain_proc => {|chain| ... }` : When a session channel is opened, a background thread is started and is waitng for a
|
278
|
+
- `#chain_proc => {|chain| ... }` : When a session channel is opened, a background thread is started and is waitng for a chained block registered. This `#chain_proc` is used to define how to handle subsequent communications between local and remote. The `chain` variable provides `#call_next` method. In `#proc_chain` block, it is possible to call subsequent block that is defined in another request handler. For instance, shell request must called after pty-req request. The `chain` in pty-req request handler's `#chain_proc` calls `#next_proc` and then subsequent shell request handler's `#chain_proc` will be called.
|
279
|
+
- `#close_session` : In most cases, input and output between a client and the server is handled in `#chain_proc` and closing the `#chain_proc` block will lead closing the underlying session channel. This means that to close the underlying session channel it is required to write at least one `#chain_proc` block. If it is not required to use `#chain_proc` block or is required to close the underlying session channel from outside of `#chain_proc` block, `#close_session` can be used. The `#close_session` will close the background thread that calls `#chain_proc` blocks.
|
278
280
|
|
279
281
|
And request handler's `context` variable also provides additional methods based on request type. See `lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/<request type>/context.rb`.
|
280
282
|
|
@@ -321,6 +323,23 @@ p HrrRbSsh::Transport::CompressionAlgorithm.list_preferred
|
|
321
323
|
# => ["none", "zlib"]
|
322
324
|
```
|
323
325
|
|
326
|
+
#### Hiding and/or simulating local SSH version
|
327
|
+
|
328
|
+
By default, hrr_rb_ssh sends `SSH-2.0-HrrRbSsh-#{VERSION}` string at initial negotiation with remote peer. To address security concerns, it is possible to replace the version string.
|
329
|
+
|
330
|
+
```ruby
|
331
|
+
# Hiding version
|
332
|
+
options['local_version'] = "SSH-2.0-HrrRbSsh"
|
333
|
+
|
334
|
+
# Simulating OpenSSH
|
335
|
+
options['local_version'] = "SSH-2.0-OpenSSH_x.x"
|
336
|
+
|
337
|
+
# Simulating OpenSSH and hiding version
|
338
|
+
options['local_version'] = "SSH-2.0-OpenSSH"
|
339
|
+
```
|
340
|
+
|
341
|
+
Please note that the beginning of the string must be `SSH-2.0-`. Otherwise SSH 2.0 remote peer cannot continue negotiation with the local peer.
|
342
|
+
|
324
343
|
### Demo
|
325
344
|
|
326
345
|
The `demo/server.rb` shows a good example on how to use the hrr_rb_ssh library in SSH server mode.
|
data/demo/echo_server.rb
CHANGED
@@ -39,8 +39,8 @@ def start_service io, logger=nil
|
|
39
39
|
options['authentication_password_authenticator'] = auth_password
|
40
40
|
options['connection_channel_request_shell'] = conn_echo
|
41
41
|
|
42
|
-
server = HrrRbSsh::Server.new
|
43
|
-
server.start
|
42
|
+
server = HrrRbSsh::Server.new options
|
43
|
+
server.start io
|
44
44
|
end
|
45
45
|
|
46
46
|
logger = Logger.new STDOUT
|
data/demo/server.rb
CHANGED
@@ -89,8 +89,8 @@ OfeosJOO9twerD7pPhmXREkygblPsEXaVA==
|
|
89
89
|
options['connection_channel_request_exec'] = HrrRbSsh::Connection::RequestHandler::ReferenceExecRequestHandler.new
|
90
90
|
options['connection_channel_request_window_change'] = HrrRbSsh::Connection::RequestHandler::ReferenceWindowChangeRequestHandler.new
|
91
91
|
|
92
|
-
server = HrrRbSsh::Server.new
|
93
|
-
server.start
|
92
|
+
server = HrrRbSsh::Server.new options
|
93
|
+
server.start io
|
94
94
|
end
|
95
95
|
|
96
96
|
|
@@ -47,8 +47,8 @@ def start_service io, logger=nil
|
|
47
47
|
options['authentication_password_authenticator'] = auth_password
|
48
48
|
options['connection_channel_request_subsystem'] = conn_echo
|
49
49
|
|
50
|
-
server = HrrRbSsh::Server.new
|
51
|
-
server.start
|
50
|
+
server = HrrRbSsh::Server.new options
|
51
|
+
server.start io
|
52
52
|
end
|
53
53
|
|
54
54
|
logger = Logger.new STDOUT
|
@@ -20,7 +20,7 @@ module HrrRbSsh
|
|
20
20
|
:variable_name,
|
21
21
|
:variable_value
|
22
22
|
|
23
|
-
def initialize proc_chain, username, io, variables, message
|
23
|
+
def initialize proc_chain, username, io, variables, message, session
|
24
24
|
@logger = Logger.new self.class.name
|
25
25
|
|
26
26
|
@proc_chain = proc_chain
|
@@ -28,6 +28,7 @@ module HrrRbSsh
|
|
28
28
|
@io = io
|
29
29
|
@variables = variables
|
30
30
|
@vars = variables
|
31
|
+
@session = session
|
31
32
|
|
32
33
|
@variable_name = message[:'variable name']
|
33
34
|
@variable_value = message[:'variable value']
|
@@ -36,6 +37,10 @@ module HrrRbSsh
|
|
36
37
|
def chain_proc &block
|
37
38
|
@proc = block || @proc
|
38
39
|
end
|
40
|
+
|
41
|
+
def close_session
|
42
|
+
@session.close
|
43
|
+
end
|
39
44
|
end
|
40
45
|
end
|
41
46
|
end
|
@@ -13,10 +13,10 @@ module HrrRbSsh
|
|
13
13
|
class Env < RequestType
|
14
14
|
NAME = 'env'
|
15
15
|
|
16
|
-
def self.run proc_chain, username, io, variables, message, options
|
16
|
+
def self.run proc_chain, username, io, variables, message, options, session
|
17
17
|
logger = Logger.new self.class.name
|
18
18
|
|
19
|
-
context = Context.new proc_chain, username, io, variables, message
|
19
|
+
context = Context.new proc_chain, username, io, variables, message, session
|
20
20
|
handler = options.fetch('connection_channel_request_env', RequestHandler.new {})
|
21
21
|
handler.run context
|
22
22
|
|
@@ -19,7 +19,7 @@ module HrrRbSsh
|
|
19
19
|
:vars,
|
20
20
|
:command
|
21
21
|
|
22
|
-
def initialize proc_chain, username, io, variables, message
|
22
|
+
def initialize proc_chain, username, io, variables, message, session
|
23
23
|
@logger = Logger.new self.class.name
|
24
24
|
|
25
25
|
@proc_chain = proc_chain
|
@@ -27,6 +27,7 @@ module HrrRbSsh
|
|
27
27
|
@io = io
|
28
28
|
@variables = variables
|
29
29
|
@vars = variables
|
30
|
+
@session = session
|
30
31
|
|
31
32
|
@command = message[:'command']
|
32
33
|
end
|
@@ -34,6 +35,10 @@ module HrrRbSsh
|
|
34
35
|
def chain_proc &block
|
35
36
|
@proc = block || @proc
|
36
37
|
end
|
38
|
+
|
39
|
+
def close_session
|
40
|
+
@session.close
|
41
|
+
end
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
@@ -13,10 +13,10 @@ module HrrRbSsh
|
|
13
13
|
class Exec < RequestType
|
14
14
|
NAME = 'exec'
|
15
15
|
|
16
|
-
def self.run proc_chain, username, io, variables, message, options
|
16
|
+
def self.run proc_chain, username, io, variables, message, options, session
|
17
17
|
logger = Logger.new self.class.name
|
18
18
|
|
19
|
-
context = Context.new proc_chain, username, io, variables, message
|
19
|
+
context = Context.new proc_chain, username, io, variables, message, session
|
20
20
|
handler = options.fetch('connection_channel_request_exec', RequestHandler.new {})
|
21
21
|
handler.run context
|
22
22
|
|
@@ -24,7 +24,7 @@ module HrrRbSsh
|
|
24
24
|
:terminal_height_pixels,
|
25
25
|
:encoded_terminal_modes
|
26
26
|
|
27
|
-
def initialize proc_chain, username, io, variables, message
|
27
|
+
def initialize proc_chain, username, io, variables, message, session
|
28
28
|
@logger = Logger.new self.class.name
|
29
29
|
|
30
30
|
@proc_chain = proc_chain
|
@@ -32,6 +32,7 @@ module HrrRbSsh
|
|
32
32
|
@io = io
|
33
33
|
@variables = variables
|
34
34
|
@vars = variables
|
35
|
+
@session = session
|
35
36
|
|
36
37
|
@term_environment_variable_value = message[:'TERM environment variable value']
|
37
38
|
@terminal_width_characters = message[:'terminal width, characters']
|
@@ -44,6 +45,10 @@ module HrrRbSsh
|
|
44
45
|
def chain_proc &block
|
45
46
|
@proc = block || @proc
|
46
47
|
end
|
48
|
+
|
49
|
+
def close_session
|
50
|
+
@session.close
|
51
|
+
end
|
47
52
|
end
|
48
53
|
end
|
49
54
|
end
|
@@ -13,10 +13,10 @@ module HrrRbSsh
|
|
13
13
|
class PtyReq < RequestType
|
14
14
|
NAME = 'pty-req'
|
15
15
|
|
16
|
-
def self.run proc_chain, username, io, variables, message, options
|
16
|
+
def self.run proc_chain, username, io, variables, message, options, session
|
17
17
|
logger = Logger.new self.class.name
|
18
18
|
|
19
|
-
context = Context.new proc_chain, username, io, variables, message
|
19
|
+
context = Context.new proc_chain, username, io, variables, message, session
|
20
20
|
handler = options.fetch('connection_channel_request_pty_req', RequestHandler.new {})
|
21
21
|
handler.run context
|
22
22
|
|
@@ -18,7 +18,7 @@ module HrrRbSsh
|
|
18
18
|
:variables,
|
19
19
|
:vars
|
20
20
|
|
21
|
-
def initialize proc_chain, username, io, variables, message
|
21
|
+
def initialize proc_chain, username, io, variables, message, session
|
22
22
|
@logger = Logger.new self.class.name
|
23
23
|
|
24
24
|
@proc_chain = proc_chain
|
@@ -26,11 +26,16 @@ module HrrRbSsh
|
|
26
26
|
@io = io
|
27
27
|
@variables = variables
|
28
28
|
@vars = variables
|
29
|
+
@session = session
|
29
30
|
end
|
30
31
|
|
31
32
|
def chain_proc &block
|
32
33
|
@proc = block || @proc
|
33
34
|
end
|
35
|
+
|
36
|
+
def close_session
|
37
|
+
@session.close
|
38
|
+
end
|
34
39
|
end
|
35
40
|
end
|
36
41
|
end
|
@@ -13,10 +13,10 @@ module HrrRbSsh
|
|
13
13
|
class Shell < RequestType
|
14
14
|
NAME = 'shell'
|
15
15
|
|
16
|
-
def self.run proc_chain, username, io, variables, message, options
|
16
|
+
def self.run proc_chain, username, io, variables, message, options, session
|
17
17
|
logger = Logger.new self.class.name
|
18
18
|
|
19
|
-
context = Context.new proc_chain, username, io, variables, message
|
19
|
+
context = Context.new proc_chain, username, io, variables, message, session
|
20
20
|
handler = options.fetch('connection_channel_request_shell', RequestHandler.new {})
|
21
21
|
handler.run context
|
22
22
|
|
data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb
CHANGED
@@ -19,7 +19,7 @@ module HrrRbSsh
|
|
19
19
|
:vars,
|
20
20
|
:subsystem_name
|
21
21
|
|
22
|
-
def initialize proc_chain, username, io, variables, message
|
22
|
+
def initialize proc_chain, username, io, variables, message, session
|
23
23
|
@logger = Logger.new self.class.name
|
24
24
|
|
25
25
|
@proc_chain = proc_chain
|
@@ -27,6 +27,7 @@ module HrrRbSsh
|
|
27
27
|
@io = io
|
28
28
|
@variables = variables
|
29
29
|
@vars = variables
|
30
|
+
@session = session
|
30
31
|
|
31
32
|
@subsystem_name = message[:'subsystem name']
|
32
33
|
end
|
@@ -34,6 +35,10 @@ module HrrRbSsh
|
|
34
35
|
def chain_proc &block
|
35
36
|
@proc = block || @proc
|
36
37
|
end
|
38
|
+
|
39
|
+
def close_session
|
40
|
+
@session.close
|
41
|
+
end
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
@@ -13,10 +13,10 @@ module HrrRbSsh
|
|
13
13
|
class Subsystem < RequestType
|
14
14
|
NAME = 'subsystem'
|
15
15
|
|
16
|
-
def self.run proc_chain, username, io, variables, message, options
|
16
|
+
def self.run proc_chain, username, io, variables, message, options, session
|
17
17
|
logger = Logger.new self.class.name
|
18
18
|
|
19
|
-
context = Context.new proc_chain, username, io, variables, message
|
19
|
+
context = Context.new proc_chain, username, io, variables, message, session
|
20
20
|
handler = options.fetch('connection_channel_request_subsystem', RequestHandler.new {})
|
21
21
|
handler.run context
|
22
22
|
|
data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb
CHANGED
@@ -22,7 +22,7 @@ module HrrRbSsh
|
|
22
22
|
:terminal_width_pixels,
|
23
23
|
:terminal_height_pixels
|
24
24
|
|
25
|
-
def initialize proc_chain, username, io, variables, message
|
25
|
+
def initialize proc_chain, username, io, variables, message, session
|
26
26
|
@logger = Logger.new self.class.name
|
27
27
|
|
28
28
|
@proc_chain = proc_chain
|
@@ -30,6 +30,7 @@ module HrrRbSsh
|
|
30
30
|
@io = io
|
31
31
|
@variables = variables
|
32
32
|
@vars = variables
|
33
|
+
@session = session
|
33
34
|
|
34
35
|
@terminal_width_columns = message[:'terminal width, columns']
|
35
36
|
@terminal_height_rows = message[:'terminal height, rows']
|
@@ -40,6 +41,10 @@ module HrrRbSsh
|
|
40
41
|
def chain_proc &block
|
41
42
|
@proc = block || @proc
|
42
43
|
end
|
44
|
+
|
45
|
+
def close_session
|
46
|
+
@session.close
|
47
|
+
end
|
43
48
|
end
|
44
49
|
end
|
45
50
|
end
|
@@ -13,10 +13,10 @@ module HrrRbSsh
|
|
13
13
|
class WindowChange < RequestType
|
14
14
|
NAME = 'window-change'
|
15
15
|
|
16
|
-
def self.run proc_chain, username, io, variables, message, options
|
16
|
+
def self.run proc_chain, username, io, variables, message, options, session
|
17
17
|
logger = Logger.new self.class.name
|
18
18
|
|
19
|
-
context = Context.new proc_chain, username, io, variables, message
|
19
|
+
context = Context.new proc_chain, username, io, variables, message, session
|
20
20
|
handler = options.fetch('connection_channel_request_window_change', RequestHandler.new {})
|
21
21
|
handler.run context
|
22
22
|
|
@@ -30,7 +30,7 @@ module HrrRbSsh
|
|
30
30
|
|
31
31
|
def request message
|
32
32
|
request_type = message[:'request type']
|
33
|
-
RequestType[request_type].run @proc_chain, @connection.username, @channel.io, @variables, message, @connection.options
|
33
|
+
RequestType[request_type].run @proc_chain, @connection.username, @channel.io, @variables, message, @connection.options, self
|
34
34
|
end
|
35
35
|
|
36
36
|
def proc_chain_thread
|
data/lib/hrr_rb_ssh/server.rb
CHANGED
@@ -8,16 +8,22 @@ require 'hrr_rb_ssh/connection'
|
|
8
8
|
|
9
9
|
module HrrRbSsh
|
10
10
|
class Server
|
11
|
-
def
|
11
|
+
def self.start io, options={}
|
12
|
+
server = self.new options
|
13
|
+
server.start io
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize options={}
|
12
17
|
@logger = Logger.new self.class.name
|
13
|
-
@
|
14
|
-
@authentication = HrrRbSsh::Authentication.new @transport, options
|
15
|
-
@connection = HrrRbSsh::Connection.new @authentication, options
|
18
|
+
@options = options
|
16
19
|
end
|
17
20
|
|
18
|
-
def start
|
21
|
+
def start io
|
19
22
|
@logger.info { "start server service" }
|
20
|
-
@
|
23
|
+
transport = HrrRbSsh::Transport.new io, HrrRbSsh::Mode::SERVER, @options
|
24
|
+
authentication = HrrRbSsh::Authentication.new transport, @options
|
25
|
+
connection = HrrRbSsh::Connection.new authentication, @options
|
26
|
+
connection.start
|
21
27
|
end
|
22
28
|
end
|
23
29
|
end
|
data/lib/hrr_rb_ssh/transport.rb
CHANGED
@@ -67,7 +67,7 @@ module HrrRbSsh
|
|
67
67
|
@sender_monitor = Monitor.new
|
68
68
|
@receiver_monitor = Monitor.new
|
69
69
|
|
70
|
-
@local_version = "SSH-2.0-HrrRbSsh-#{VERSION}".force_encoding(Encoding::ASCII_8BIT)
|
70
|
+
@local_version = @options.delete('local_version') || "SSH-2.0-HrrRbSsh-#{VERSION}".force_encoding(Encoding::ASCII_8BIT)
|
71
71
|
@remote_version = "".force_encoding(Encoding::ASCII_8BIT)
|
72
72
|
|
73
73
|
@incoming_sequence_number = SequenceNumber.new
|
data/lib/hrr_rb_ssh/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hrr_rb_ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hirura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ed25519
|
@@ -316,9 +316,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
316
316
|
version: 2.0.0
|
317
317
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
318
318
|
requirements:
|
319
|
-
- - "
|
319
|
+
- - ">"
|
320
320
|
- !ruby/object:Gem::Version
|
321
|
-
version:
|
321
|
+
version: 1.3.1
|
322
322
|
requirements: []
|
323
323
|
rubyforge_project:
|
324
324
|
rubygems_version: 2.7.6
|