oxidized-ssh 0.1.3.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bcc185b0420ff278b2b9782255b0036beb264fce
4
- data.tar.gz: 868d41499ff0babbdd678874be8642bf23a8a5ba
3
+ metadata.gz: 71b59442e6764a1a33fc672f7c88eebdcf3554ea
4
+ data.tar.gz: 101b3ee28e337a24b5e19a8cdd2de9cb458fa804
5
5
  SHA512:
6
- metadata.gz: 743a57863c231902ab82a4cadefe21c1c7d6412c23cf1638c0e0ed0e63d9cae533b9ba7fdfdf20d97fc32cce2674fa5d190dcafca2b56b2e6a7181f92e417611
7
- data.tar.gz: 23f23c7bcfc4fd3d5f4c41c1902aa0f9d7301d081c9a14fd92d96f44066cbabdb83c4b0d334853e35fd06f7f808b29b6390393caf7c24f1639882ec3b37a03d9
6
+ metadata.gz: 85f572b4a3e433b5a44035d90072e25a005dea807697e3ffcf47cb2e2b3c25562e862a9720c1e25a06c6a5a40913750dbd7444b40ca6dd804b1ed5889a3ae58d
7
+ data.tar.gz: 8b03eb5281370825808abc64d3d1c3e1f51d6ea0ae2281e8bdcb8b583548e1a0d534175cfc31af746ec81e84bd3aa0df7ab327d3fc7c1268587d8f6b21a70a48
@@ -1,5 +1,6 @@
1
- module Oxidized
2
- module Ssh
3
- VERSION = "0.1.3.1"
4
- end
5
- end
1
+ module Oxidized
2
+ class SSHWrapper
3
+ VERSION = "0.2"
4
+ end
5
+ end
6
+
@@ -1,148 +1,181 @@
1
- require_relative "ssh/version"
2
- require 'net/ssh'
3
- require 'timeout'
4
- require 'awesome_print'
5
-
6
- module Oxidized
7
- class SSH
8
-
9
- attr_reader :connection, :ip, :username, :password
10
- attr_reader :prompt, :debug, :exec, :pty_options
11
- attr_reader :port, :output, :session
12
-
13
- def initialize(options)
14
- @ip = options[:ip]
15
- @username = options[:username]
16
- @password = options[:password]
17
- @verbose = options[:verbose]
18
- @debug = options[:debug]
19
- @prompt = options[:prompt]
20
- @exec = options[:exec]
21
- @pty_options = options[:pty_options] ||= { term: "vt100" }
22
- @port = options[:port] ||= 22
23
- @output = String.new
24
- @logger = options[:logger] ||= Logger.new(STDOUT)
25
- @auth_methods = options[:auth_methods] ||= ["publickey", "hostbased", "password"]
26
- @expectation_handler = options[:expectation_handler]
27
- end
28
-
29
- def start
30
- raise "MissingSSHLibrary" if !defined? Net::SSH
31
- @connection = Net::SSH.start(@ip, @username, password: @password, verbose: @verbose, port: @port, auth_methods: @auth_methods)
32
- return yield self if block_given?
33
- return (@connection and not @connection.closed?)
34
- end
35
-
36
- def exec!(params, expect = @prompt)
37
- check_for_connection
38
- exec(params, expect)
39
- sanitize_output_buffer("\n", /\r\n/)
40
- sanitize_output_buffer('', params)
41
- @output
42
- end
43
-
44
- def check_for_connection
45
- prep_connection unless @session
46
- end
47
-
48
- def exec(params, expectation)
49
- if @exec
50
- @logger.debug "sending exec command #{params}" if @debug
51
- @output = @connection.exec!(params)
52
- else
53
- @logger.debug "sending command #{params} with expectation of #{expectation}" if @debug
54
- collect_output(params, expectation)
55
- end
56
- end
57
-
58
- def collect_output(params, expectation)
59
- send_data((params + "\n"), expectation)
60
- return @output
61
- end
62
-
63
- def send_data(params, expectation)
64
- expect expectation
65
- reset_output_buffer
66
- send(params)
67
- @session.process
68
- expect expectation
69
- @output
70
- end
71
-
72
- def send(params)
73
- @session.send_data params
74
- end
75
-
76
- def expect *regexps
77
- regexps = [regexps].flatten
78
- @logger.debug "expecting #{regexps.inspect} at #{@ip}" if @debug
79
- @connection.loop(0.1) do
80
- sleep 0.1
81
- match = regexps.find { |regexp| @output.match regexp }
82
- return match if match
83
- true
84
- end
85
- end
86
-
87
- def prep_connection
88
- return true if @exec
89
- start_channel_requests
90
- end
91
-
92
- def start_channel_requests
93
- create_session
94
- end
95
-
96
- def create_session
97
- @session = @connection.open_channel do |channel|
98
- setup_channels(channel)
99
- end
100
- end
101
-
102
- def setup_channels(ch)
103
- set_data_hook(ch)
104
- request_channels(ch)
105
- end
106
-
107
- def set_data_hook(ch)
108
- ch.on_data do |_ch, data|
109
- @logger.debug "received #{data}" if @debug
110
- @output << data
111
- @output = expectation_list_handler(@output) if @expectation_handler
112
- end
113
- end
114
-
115
- def expectation_list_handler(data)
116
- @expectation_handler.each_slice(2) do |handler, meth|
117
- handler.method(meth.to_sym).call(self, data)
118
- end
119
- @output
120
- end
121
-
122
- def request_channels(ch)
123
- ch.request_pty @pty_options do |_ch, success_pty|
124
- raise NoShell, "Can't get PTY" unless success_pty
125
- ch.send_channel_request 'shell' do |_ch, success_shell|
126
- raise NoShell, "Can't get shell" unless success_shell
127
- end
128
- end
129
- end
130
-
131
- def reset_output_buffer
132
- @output = ''
133
- end
134
-
135
- def sanitize_output_buffer sub, *regexs
136
- @logger.debug "sanitizing #{regexs.join("|")} with #{sub}" if @debug
137
- @output.gsub!(/#{regexs.join("|")}/, sub)
138
- end
139
-
140
- def disconnect
141
- Timeout::timeout(5) { @connection.loop }
142
- rescue Errno::ECONNRESET, Net::SSH::Disconnect, IOError
143
- ensure
144
- (@connection.close rescue true) unless @connection.closed?
145
- end
146
-
147
- end
148
- end
1
+ require_relative "ssh/version"
2
+ require 'net/ssh'
3
+ require 'timeout'
4
+ require 'awesome_print'
5
+ require 'pry'
6
+
7
+ module Oxidized
8
+ class SSHWrapper
9
+
10
+ attr_reader :connection, :ip, :username, :password
11
+ attr_reader :prompt, :debug, :exec
12
+ attr_reader :port, :output, :session
13
+
14
+ attr_writer :login, :username_prompt, :password_prompt
15
+ attr_writer :pty_options
16
+
17
+ def initialize(options)
18
+ @ip = options[:ip]
19
+ @username = options[:username]
20
+ @password = options[:password]
21
+ @verbose = options[:verbose]
22
+ @debug = options[:debug]
23
+ @prompt = options[:prompt]
24
+ @exec = options[:exec] || false
25
+ @pty_options = options[:pty_options] ||= { term: "vt100" }
26
+ @port = options[:port] ||= 22
27
+ @output = String.new
28
+ @logger = options[:logger] ||= Logger.new(STDOUT)
29
+ @auth_methods = options[:auth_methods] ||= ["publickey", "hostbased", "password"]
30
+ @expectation_handler = options[:expectation_handler]
31
+ @proxy = prep_proxy(options[:proxy])
32
+ end
33
+
34
+ def prep_proxy(proxy)
35
+ if proxy_host = proxy
36
+ proxy_command = "ssh "
37
+ proxy_command += "-o StrictHostKeyChecking=no " #unless secure
38
+ proxy_command += "#{proxy_host} -W %h:%p"
39
+ return Net::SSH::Proxy::Command.new(proxy_command)
40
+ end
41
+ end
42
+
43
+ def start
44
+ raise "MissingSSHLibrary" if !defined? Net::SSH
45
+ @connection = Net::SSH.start(@ip, @username, password: @password, verbose: @verbose, port: @port, auth_methods: @auth_methods, proxy: @proxy)
46
+ return yield self if block_given?
47
+ return (@connection and not @connection.closed?)
48
+ end
49
+
50
+ def exec!(params, expect = @prompt)
51
+ check_for_connection
52
+ exec(params, expect)
53
+ sanitize_output_buffer("\n", /\r\n/)
54
+ sanitize_output_buffer('', params)
55
+ @logger.debug params if @debug
56
+ @output
57
+ end
58
+
59
+ def check_for_connection
60
+ prep_connection unless @session
61
+ end
62
+
63
+ def exec(params, expectation)
64
+ if @exec
65
+ @logger.debug "sending exec command #{params}" if @debug
66
+ @output = @connection.exec!(params)
67
+ else
68
+ @logger.debug "sending command #{params} with expectation of #{expectation}" if @debug
69
+ collect_output(params, expectation)
70
+ end
71
+ end
72
+
73
+ def collect_output(params, expectation)
74
+ send_data((params + "\n"), expectation)
75
+ return @output
76
+ end
77
+
78
+ def send_data(params, expectation)
79
+ reset_output_buffer
80
+ send(params)
81
+ @session.process
82
+ expect expectation if expectation
83
+ @output
84
+ end
85
+
86
+ def send(params)
87
+ @session.send_data params
88
+ end
89
+
90
+ def expect *regexps
91
+ regexps = [regexps].flatten
92
+ @logger.debug "expecting #{regexps.inspect} at #{@ip}" if @debug
93
+ @connection.loop(0.1) do
94
+ @logger.debug @output if @debug
95
+ sleep 0.1
96
+ match = regexps.find { |regexp| @output.match regexp }
97
+ return match if match
98
+ true
99
+ end
100
+ end
101
+
102
+ def prep_connection
103
+ return true if @exec
104
+ start_channel_requests
105
+ login
106
+ end
107
+
108
+ def login
109
+ if @login
110
+ match = expect @username_prompt, @prompt
111
+ if match == @login_prompt
112
+ exec @username, @password_prompt
113
+ exec @password
114
+ end
115
+ else
116
+ expect @prompt
117
+ end
118
+
119
+ end
120
+
121
+ def start_channel_requests
122
+ create_session
123
+ end
124
+
125
+ def create_session
126
+ @session = @connection.open_channel do |channel|
127
+ setup_channels(channel)
128
+ end
129
+ end
130
+
131
+ def setup_channels(ch)
132
+ set_data_hook(ch)
133
+ request_channels(ch)
134
+ end
135
+
136
+ def set_data_hook(ch)
137
+ ch.on_data do |_ch, data|
138
+ #@logger.debug "received #{data}" if @debug
139
+ @output << data
140
+ @output = expectation_list_handler(@output) if @expectation_handler
141
+ end
142
+ end
143
+
144
+ def expectation_list_handler(data)
145
+ @expectation_handler.each_slice(2) do |handler, meth|
146
+ handler.method(meth.to_sym).call(self, data)
147
+ end
148
+ @output
149
+ end
150
+
151
+ def request_channels(ch)
152
+ ch.request_pty @pty_options do |_ch, success_pty|
153
+ raise NoShell, "Can't get PTY" unless success_pty
154
+ ch.send_channel_request 'shell' do |_ch, success_shell|
155
+ raise NoShell, "Can't get shell" unless success_shell
156
+ end
157
+ end
158
+ end
159
+
160
+ def reset_output_buffer
161
+ @output = ''
162
+ end
163
+
164
+ def sanitize_output_buffer sub, *regexs
165
+ @logger.debug "sanitizing #{regexs.join("|")} with #{sub}" if @debug
166
+ @output.gsub!(/#{regexs.join("|")}/, sub)
167
+ end
168
+
169
+ def disconnect
170
+ Timeout::timeout(5) { @connection.loop }
171
+ rescue Errno::ECONNRESET, Net::SSH::Disconnect, IOError
172
+ ensure
173
+ (@connection.close rescue true) unless @connection.closed?
174
+ end
175
+
176
+ def connected?
177
+ @connection.closed?
178
+ end
179
+
180
+ end
181
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oxidized-ssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3.1
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Schylar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-18 00:00:00.000000000 Z
11
+ date: 2017-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-ssh
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: net-telnet
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'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: pry
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -101,8 +115,8 @@ executables: []
101
115
  extensions: []
102
116
  extra_rdoc_files: []
103
117
  files:
104
- - lib/oxidized/ssh.rb
105
118
  - lib/oxidized/ssh/version.rb
119
+ - lib/oxidized/sshwrapper.rb
106
120
  homepage: http://github.com/MajesticFalcon/oxidized-ssh
107
121
  licenses:
108
122
  - Apache-2.0
@@ -123,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
137
  version: '0'
124
138
  requirements: []
125
139
  rubyforge_project: oxidized-ssh
126
- rubygems_version: 2.6.7
140
+ rubygems_version: 2.5.1
127
141
  signing_key:
128
142
  specification_version: 4
129
143
  summary: Robust SSH client