smart_proxy_remote_execution_ssh 0.2.1 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81a9638ca473014a1f61251fa81823fb907cf725ae0b56a5921c0ad96c6b39be
4
- data.tar.gz: 850685e0501af25d38a42061e1422db61b28fe99d2f56aff6edcdfd5501eb69c
3
+ metadata.gz: edd3c4b54f9e85e4eab99273ececb03dc221e9f96dab79cc0b2a563fb9e5c938
4
+ data.tar.gz: f231fd22622005ab2b478a5295af4c4d7ac8f825a56f2d83b2e14f94b9892e50
5
5
  SHA512:
6
- metadata.gz: ce27e71082ff1eed48c4b32bedaf6ea6f8a2998bae010e154938b24de3704ff8297e1000ca3b75a33fc76c46593f555c10236b7a9cb38389322d65d05466cd08
7
- data.tar.gz: c733a1a0a5865180b3e62a9b10d2bff8e38dca375fed0acc3a0cb80202784d0dec6b185919d00e8e096d55b8c9ef4c6353d376cc06fae99c307094123dbd6255
6
+ metadata.gz: d4d125a98ac8c5a615ffcf5dbef8e1f966352f414b4c077e3fe96e0d85fb5280c6f53f29d956b2e055e9dc5bf4d9dc86d262ac40ab069b20bede175efeabe1db
7
+ data.tar.gz: 6f4f9298569ae9360ae92c0dac359902f7471d1306570c7f1f1dda25f9e9cdf78cb9181c82d83c833bf5511e4afef75fec1c65e71d35fe43a26218a69259903f
@@ -1,3 +1,6 @@
1
+ require 'net/ssh'
2
+ require 'base64'
3
+
1
4
  module Proxy::RemoteExecution
2
5
  module Ssh
3
6
 
@@ -17,6 +20,23 @@ module Proxy::RemoteExecution
17
20
  session.hijack!
18
21
  101
19
22
  end
23
+
24
+ delete '/known_hosts/:name' do |name|
25
+ do_authorize_any
26
+ keys = Net::SSH::KnownHosts.search_for(name)
27
+ return [204] if keys.empty?
28
+ ssh_keys = keys.map { |key| Base64.strict_encode64 key.to_blob }
29
+ Net::SSH::KnownHosts.hostfiles({}, :user)
30
+ .map { |file| File.expand_path file }
31
+ .select { |file| File.readable?(file) && File.writable?(file) }
32
+ .each do |host_file|
33
+ lines = File.foreach(host_file).reject do |line|
34
+ ssh_keys.any? { |key| line.end_with? "#{key}\n" }
35
+ end
36
+ File.open(host_file, 'w') { |f| f.write lines.join }
37
+ end
38
+ 204
39
+ end
20
40
  end
21
41
  end
22
42
  end
@@ -9,7 +9,8 @@ module Proxy::RemoteExecution
9
9
  extend Forwardable
10
10
 
11
11
  # The list of methods taken from OpenSSL::SSL::SocketForwarder for the object to act like a socket
12
- def_delegators(:@socket, :to_io, :addr, :peeraddr, :setsockopt, :getsockopt, :fcntl, :close, :closed?, :do_not_reverse_lookup=)
12
+ def_delegators(:@socket, :to_io, :addr, :peeraddr, :setsockopt,
13
+ :getsockopt, :fcntl, :close, :closed?, :do_not_reverse_lookup=)
13
14
 
14
15
  def initialize(socket)
15
16
  @socket = socket
@@ -29,7 +30,7 @@ module Proxy::RemoteExecution
29
30
  end
30
31
 
31
32
  def self.build(socket)
32
- klass = [OpenSSLBufferedSocket, StandardBufferedSocket].find do |potential_class|
33
+ klass = [OpenSSLBufferedSocket, MiniSSLBufferedSocket, StandardBufferedSocket].find do |potential_class|
33
34
  potential_class.applies_for?(socket)
34
35
  end
35
36
  raise "No suitable implementation of buffered socket available for #{socket.inspect}" unless klass
@@ -57,7 +58,7 @@ module Proxy::RemoteExecution
57
58
  # To drain a SSLSocket before we can go back to the event
58
59
  # loop, we need to repeatedly call read_nonblock; a single
59
60
  # call is not enough.
60
- while true
61
+ loop do
61
62
  res += @socket.read_nonblock(n)
62
63
  end
63
64
  rescue IO::WaitReadable
@@ -79,14 +80,31 @@ module Proxy::RemoteExecution
79
80
  end
80
81
 
81
82
  def send(mesg, flags)
82
- begin
83
- @socket.write_nonblock(mesg)
84
- rescue IO::WaitWritable
85
- 0
86
- rescue IO::WaitReadable
87
- IO.select([@socket.to_io])
88
- retry
89
- end
83
+ @socket.write_nonblock(mesg)
84
+ rescue IO::WaitWritable
85
+ 0
86
+ rescue IO::WaitReadable
87
+ IO.select([@socket.to_io])
88
+ retry
89
+ end
90
+ end
91
+
92
+ class MiniSSLBufferedSocket < BufferedSocket
93
+ def self.applies_for?(socket)
94
+ socket.is_a? ::Puma::MiniSSL::Socket
95
+ end
96
+ def_delegators(:@socket, :read_nonblock, :write_nonblock, :close)
97
+
98
+ def recv(n)
99
+ @socket.read_nonblock(n)
100
+ end
101
+
102
+ def send(mesg, flags)
103
+ @socket.write_nonblock(mesg)
104
+ end
105
+
106
+ def closed?
107
+ @socket.to_io.closed?
90
108
  end
91
109
  end
92
110
 
@@ -103,8 +121,8 @@ module Proxy::RemoteExecution
103
121
 
104
122
  def hijack!
105
123
  @socket = nil
106
- if @env['WEBRICK_SOCKET']
107
- @socket = @env['WEBRICK_SOCKET']
124
+ if @env['ext.hijack!']
125
+ @socket = @env['ext.hijack!'].call
108
126
  elsif @env['rack.hijack?']
109
127
  begin
110
128
  @env['rack.hijack'].call
@@ -154,7 +172,7 @@ module Proxy::RemoteExecution
154
172
  ssh.listen_to(buf_socket)
155
173
 
156
174
  ch.on_process do
157
- if buf_socket.available > 0
175
+ if buf_socket.available.positive?
158
176
  ch.send_data(buf_socket.read_available)
159
177
  end
160
178
  if buf_socket.closed?
@@ -169,7 +187,7 @@ module Proxy::RemoteExecution
169
187
 
170
188
  ch.on_request('exit-status') do |ch, data|
171
189
  code = data.read_long
172
- send_start.call if code.zero?
190
+ send_start if code.zero?
173
191
  err_buf += "Process exited with code #{code}.\r\n"
174
192
  ch.close
175
193
  end
@@ -232,12 +250,12 @@ module Proxy::RemoteExecution
232
250
  end
233
251
 
234
252
  def ssh_options
235
- auth_methods = %w(publickey)
253
+ auth_methods = %w[publickey]
236
254
  auth_methods.unshift('password') if params["ssh_password"]
237
255
 
238
- ret = { }
256
+ ret = {}
239
257
  ret[:port] = params["ssh_port"] if params["ssh_port"]
240
- ret[:keys] = [ key_file ] if key_file
258
+ ret[:keys] = [key_file] if key_file
241
259
  ret[:password] = params["ssh_password"] if params["ssh_password"]
242
260
  ret[:passphrase] = params[:ssh_key_passphrase] if params[:ssh_key_passphrase]
243
261
  ret[:keys_only] = true
@@ -247,6 +265,5 @@ module Proxy::RemoteExecution
247
265
  ret
248
266
  end
249
267
  end
250
-
251
268
  end
252
269
  end
@@ -1,7 +1,7 @@
1
1
  module Proxy
2
2
  module RemoteExecution
3
3
  module Ssh
4
- VERSION = '0.2.1'
4
+ VERSION = '0.3.0'
5
5
  end
6
6
  end
7
7
  end
@@ -3,7 +3,13 @@ module SmartProxyRemoteExecutionSsh
3
3
  # An extension to ::WEBrick::HTTPRequest to expost the socket object for highjacking for cockpit
4
4
  module HTTPRequestExt
5
5
  def meta_vars
6
- super.merge('WEBRICK_SOCKET' => @socket)
6
+ super.merge('ext.hijack!' => -> {
7
+ # This stops Webrick from sending its own reply.
8
+ @request_line = nil;
9
+ # This stops Webrick from trying to read the next request on the socket.
10
+ @keep_alive = false;
11
+ return @socket;
12
+ })
7
13
  end
8
14
  end
9
15
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_proxy_remote_execution_ssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nečas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-24 00:00:00.000000000 Z
11
+ date: 2020-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.7'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.7'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -98,16 +98,16 @@ dependencies:
98
98
  name: rubocop
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '='
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.32.1
103
+ version: 0.82.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '='
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.32.1
110
+ version: 0.82.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: smart_proxy_dynflow
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -181,8 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
181
  - !ruby/object:Gem::Version
182
182
  version: '0'
183
183
  requirements: []
184
- rubyforge_project:
185
- rubygems_version: 2.7.6
184
+ rubygems_version: 3.0.3
186
185
  signing_key:
187
186
  specification_version: 4
188
187
  summary: Ssh remote execution provider for Foreman Smart-Proxy