smart_proxy_remote_execution_ssh 0.2.1 → 0.3.0

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
  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