polyssh 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/.gitignore +12 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +59 -0
- data/Rakefile +10 -0
- data/bin/polyssh +8 -0
- data/lib/polyssh/cli.rb +55 -0
- data/lib/polyssh/command_builder.rb +70 -0
- data/lib/polyssh/node.rb +54 -0
- data/lib/polyssh/version.rb +3 -0
- data/lib/polyssh/visitor_pattern.rb +15 -0
- data/lib/polyssh.rb +13 -0
- data/polyssh.gemspec +28 -0
- metadata +129 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cff4e8939d9e01ad6748d5bf6d5a8b3ba04f5317
|
4
|
+
data.tar.gz: 1b2888b7bccfdef7b0f95aa631f032127dae99c3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8c8f9d54fca3c5803a4b4e9a93ff8528a934a2fc995975da09fb3181854bda8a15f980c50be1903171e68e15ccb7493b81647d11c9eb8a4f23bef41b0c94f27c
|
7
|
+
data.tar.gz: 47522e72ebb4ee588da407a26aa4b3efa5b533eb1c5424fbd20e76cfddc3a972764e96fcdcb8fd2fc3cbd45a29545784a1e9ed20fbfd20919fdf9730d4b5f1e9
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Glenn Y. Rolland
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
PolySSH
|
2
|
+
=======
|
3
|
+
|
4
|
+
[](https://travis-ci.org/glenux/polyssh)
|
5
|
+
[](https://codeclimate.com/github/glenux/polyssh)
|
6
|
+
|
7
|
+
|
8
|
+
A multi-hop SSH connection tool.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Simply type :
|
13
|
+
|
14
|
+
$ gem install polyssh
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
$ polyssh [..list of ssh options and intermediate hosts...] user@host:port
|
19
|
+
|
20
|
+
You can use as many intermediate hosts as you need.
|
21
|
+
|
22
|
+
### Example 1 : Traversing a single machine
|
23
|
+
|
24
|
+
We want to connect
|
25
|
+
|
26
|
+
* to a remote host called ``destination`` (as user ``bob``, on default port)
|
27
|
+
* via a firewall (as user ``alice``, on non-default port 7222)
|
28
|
+
|
29
|
+
The corresponding command using polyssh is :
|
30
|
+
|
31
|
+
$ polyssh alice@firewall:7222 bob@destination
|
32
|
+
|
33
|
+
## Example 2 : traversing two machines with options
|
34
|
+
|
35
|
+
We want to connect
|
36
|
+
|
37
|
+
* to a remote host called ``destination`` (as user ``charlie``, on default port)
|
38
|
+
* via a firewall (as user ``alice``, on non-default port 7222)
|
39
|
+
* then via a router (as user ``bob``, on default), with parameters (FIXME)
|
40
|
+
|
41
|
+
Type the following command using polyssh :
|
42
|
+
|
43
|
+
$ polyssh alice@firewall:7222 -verbose Cypherbob@router charlie@destination
|
44
|
+
|
45
|
+
|
46
|
+
## Credits
|
47
|
+
|
48
|
+
* Initial idea : [Bob Muller on Stack Overflow](http://superuser.com/a/377215)
|
49
|
+
* Ruby rewrite & packaging : Glenn Y. Rolland
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/glenux/polyssh.
|
54
|
+
|
55
|
+
|
56
|
+
## License
|
57
|
+
|
58
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
59
|
+
|
data/Rakefile
ADDED
data/bin/polyssh
ADDED
data/lib/polyssh/cli.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
require 'net/ssh'
|
3
|
+
require 'net/scp'
|
4
|
+
|
5
|
+
module PolySSH
|
6
|
+
class Cli
|
7
|
+
attr_reader :chain
|
8
|
+
|
9
|
+
def self.start args
|
10
|
+
app = self.new
|
11
|
+
app.parse_cmdline args
|
12
|
+
|
13
|
+
app.build_commands app.chain
|
14
|
+
|
15
|
+
#app.run commands
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@chain = NodeList.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_cmdline args
|
24
|
+
args_current = []
|
25
|
+
args.each do |arg|
|
26
|
+
if arg =~ /^-/ then
|
27
|
+
args_current << arg
|
28
|
+
elsif arg =~ /^((.+)@)?([^:]+):?(\d+)?$/ then
|
29
|
+
# ssh_options = Net::SSH::Config.for($3)
|
30
|
+
# pp ssh_options
|
31
|
+
node_new = NodeEntry.new(
|
32
|
+
user: $2,
|
33
|
+
host: $3,
|
34
|
+
port: $4 || 22,
|
35
|
+
args: args_current
|
36
|
+
)
|
37
|
+
@chain << node_new
|
38
|
+
args_current = []
|
39
|
+
|
40
|
+
else
|
41
|
+
STDERR.puts "ERROR: Unexpected argument #{arg}"
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
return @chain
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def build_commands chain
|
50
|
+
commands = chain.accept(CommandBuilder.new)
|
51
|
+
return commands
|
52
|
+
end
|
53
|
+
end #class
|
54
|
+
end #module
|
55
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
|
2
|
+
module PolySSH
|
3
|
+
class CommandBuilder
|
4
|
+
include VisitorBase
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@commands = []
|
8
|
+
@last_command = ""
|
9
|
+
@baseport = 18000 + rand(2000)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Visit node list
|
13
|
+
def visit_polyssh_nodelist node_list
|
14
|
+
if node_list.count > 0 then
|
15
|
+
node_list.first.accept(self)
|
16
|
+
end
|
17
|
+
@commands.each do |cmd|
|
18
|
+
puts cmd
|
19
|
+
fork { exec cmd + " >/dev/null 2>&1 " }
|
20
|
+
sleep 2
|
21
|
+
end
|
22
|
+
puts @last_command
|
23
|
+
system @last_command
|
24
|
+
end
|
25
|
+
|
26
|
+
# Visit each node entry
|
27
|
+
def visit_polyssh_nodeentry node_entry
|
28
|
+
cmd=""
|
29
|
+
if node_entry.next.nil? then
|
30
|
+
cmd = ("ssh " +
|
31
|
+
"-o ForwardAgent=yes " +
|
32
|
+
"-o UserKnownHostsFile=/dev/null " +
|
33
|
+
"-o StrictHostKeyChecking=no " +
|
34
|
+
"-p #{@baseport} " +
|
35
|
+
"-l #{node_entry.user} " +
|
36
|
+
"localhost "
|
37
|
+
)
|
38
|
+
@last_command = cmd
|
39
|
+
else
|
40
|
+
get_port
|
41
|
+
next_entry = node_entry.next
|
42
|
+
cmd = (
|
43
|
+
"ssh " +
|
44
|
+
"-o ForwardAgent=yes " +
|
45
|
+
"-o UserKnownHostsFile=/dev/null " +
|
46
|
+
"-o StrictHostKeyChecking=no " +
|
47
|
+
"-N " +
|
48
|
+
"-L#{@baseport}:#{next_entry.host}:#{next_entry.port} " +
|
49
|
+
"-l #{node_entry.user} #{node_entry.host} "
|
50
|
+
)
|
51
|
+
@commands << cmd
|
52
|
+
next_entry.accept(self)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Detect next available port
|
57
|
+
def get_port
|
58
|
+
@baseport += 1
|
59
|
+
while !port_open?(@baseport) do
|
60
|
+
@baseport += 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Test if given port is locally used
|
65
|
+
def port_open?(port)
|
66
|
+
!system("lsof -i:#{port}", out: '/dev/null')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
data/lib/polyssh/node.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# vim: set ts=2 sw=2 et:
|
2
|
+
|
3
|
+
module PolySSH
|
4
|
+
class NodeList
|
5
|
+
include Visitable
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def each
|
9
|
+
ptr = @head
|
10
|
+
while not ptr.nil? do
|
11
|
+
yield ptr
|
12
|
+
ptr = ptr.next
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@head = nil
|
18
|
+
@tail = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def <<(node)
|
22
|
+
if @head.nil? then
|
23
|
+
@head = node
|
24
|
+
@tail = node
|
25
|
+
else
|
26
|
+
@tail.next = node
|
27
|
+
@tail = node
|
28
|
+
end
|
29
|
+
self
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class NodeEntry
|
34
|
+
include Visitable
|
35
|
+
|
36
|
+
attr_accessor :port
|
37
|
+
attr_accessor :user
|
38
|
+
attr_accessor :host
|
39
|
+
|
40
|
+
attr_accessor :next
|
41
|
+
attr_accessor :args
|
42
|
+
|
43
|
+
def initialize(user:, host:, port: nil, args: nil)
|
44
|
+
@user = user
|
45
|
+
@host = host
|
46
|
+
@port = port || 22
|
47
|
+
@args = args || []
|
48
|
+
|
49
|
+
# Linked list part
|
50
|
+
@next = nil
|
51
|
+
end
|
52
|
+
end #class
|
53
|
+
end #module
|
54
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module PolySSH
|
2
|
+
module VisitorBase
|
3
|
+
def do_visit object
|
4
|
+
object.accept(self)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
module Visitable
|
10
|
+
def accept visitor
|
11
|
+
class_name = self.class.name.gsub('::','_').downcase
|
12
|
+
visitor.send 'visit_' + class_name, self
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/polyssh.rb
ADDED
data/polyssh.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'polyssh/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'polyssh'
|
8
|
+
spec.version = PolySSH::VERSION
|
9
|
+
spec.authors = ["Glenn Y. Rolland"]
|
10
|
+
spec.email = ['glenux@glenux.net']
|
11
|
+
|
12
|
+
spec.summary = %q{Multi-hop SSH tunneling tool.}
|
13
|
+
spec.description = %q{Multi-hop SSH tunneling tool.}
|
14
|
+
spec.homepage = 'https://github.com/glenux/polyssh'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "bin"
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_runtime_dependency "net-scp"
|
23
|
+
spec.add_runtime_dependency "net-ssh"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "minitest"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: polyssh
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Glenn Y. Rolland
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: net-scp
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: net-ssh
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.10'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Multi-hop SSH tunneling tool.
|
84
|
+
email:
|
85
|
+
- glenux@glenux.net
|
86
|
+
executables:
|
87
|
+
- polyssh
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".travis.yml"
|
93
|
+
- Gemfile
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- bin/polyssh
|
98
|
+
- lib/polyssh.rb
|
99
|
+
- lib/polyssh/cli.rb
|
100
|
+
- lib/polyssh/command_builder.rb
|
101
|
+
- lib/polyssh/node.rb
|
102
|
+
- lib/polyssh/version.rb
|
103
|
+
- lib/polyssh/visitor_pattern.rb
|
104
|
+
- polyssh.gemspec
|
105
|
+
homepage: https://github.com/glenux/polyssh
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
metadata: {}
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
requirements: []
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 2.4.5.1
|
126
|
+
signing_key:
|
127
|
+
specification_version: 4
|
128
|
+
summary: Multi-hop SSH tunneling tool.
|
129
|
+
test_files: []
|