hrr_rb_ssh 0.4.0.pre1 → 0.4.0.pre2

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -8
  3. data/demo/client.rb +1 -3
  4. data/demo/echo_server.rb +1 -3
  5. data/demo/more_flexible_auth.rb +1 -3
  6. data/demo/multi_step_auth.rb +1 -3
  7. data/demo/server.rb +1 -3
  8. data/demo/subsystem_echo_server.rb +1 -3
  9. data/hrr_rb_ssh.gemspec +1 -1
  10. data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2.rb +12 -9
  11. data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss.rb +10 -7
  12. data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa.rb +9 -6
  13. data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/context.rb +9 -8
  14. data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_request.rb +6 -5
  15. data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_response.rb +5 -2
  16. data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive.rb +12 -10
  17. data/lib/hrr_rb_ssh/authentication/method/none/context.rb +7 -6
  18. data/lib/hrr_rb_ssh/authentication/method/none.rb +10 -8
  19. data/lib/hrr_rb_ssh/authentication/method/password/context.rb +7 -6
  20. data/lib/hrr_rb_ssh/authentication/method/password.rb +10 -8
  21. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/functionable.rb +13 -11
  22. data/lib/hrr_rb_ssh/authentication/method/publickey/context.rb +5 -2
  23. data/lib/hrr_rb_ssh/authentication/method/publickey.rb +16 -14
  24. data/lib/hrr_rb_ssh/authentication.rb +28 -27
  25. data/lib/hrr_rb_ssh/client.rb +58 -56
  26. data/lib/hrr_rb_ssh/codable.rb +20 -10
  27. data/lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb +20 -18
  28. data/lib/hrr_rb_ssh/connection/channel/channel_type/forwarded_tcpip.rb +20 -18
  29. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain/chain_context.rb +0 -3
  30. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain.rb +0 -2
  31. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env/context.rb +5 -4
  32. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env.rb +2 -5
  33. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec/context.rb +5 -4
  34. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec.rb +2 -5
  35. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req/context.rb +5 -4
  36. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req.rb +2 -5
  37. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell/context.rb +5 -4
  38. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell.rb +2 -5
  39. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb +5 -4
  40. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem.rb +2 -5
  41. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb +5 -4
  42. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change.rb +2 -5
  43. data/lib/hrr_rb_ssh/connection/channel/channel_type/session.rb +14 -12
  44. data/lib/hrr_rb_ssh/connection/channel.rb +73 -71
  45. data/lib/hrr_rb_ssh/connection/global_request_handler.rb +14 -12
  46. data/lib/hrr_rb_ssh/connection/request_handler/reference_env_request_handler.rb +0 -2
  47. data/lib/hrr_rb_ssh/connection/request_handler/reference_exec_request_handler.rb +4 -6
  48. data/lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb +10 -12
  49. data/lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb +4 -6
  50. data/lib/hrr_rb_ssh/connection/request_handler/reference_window_change_request_handler.rb +0 -2
  51. data/lib/hrr_rb_ssh/connection/request_handler.rb +1 -3
  52. data/lib/hrr_rb_ssh/connection.rb +53 -53
  53. data/lib/hrr_rb_ssh/loggable.rb +42 -0
  54. data/lib/hrr_rb_ssh/server.rb +11 -9
  55. data/lib/hrr_rb_ssh/transport/compression_algorithm/functionable.rb +5 -3
  56. data/lib/hrr_rb_ssh/transport/compression_algorithm/unfunctionable.rb +5 -3
  57. data/lib/hrr_rb_ssh/transport/encryption_algorithm/functionable.rb +5 -3
  58. data/lib/hrr_rb_ssh/transport/encryption_algorithm/unfunctionable.rb +5 -3
  59. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman.rb +9 -8
  60. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb +13 -12
  61. data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman.rb +9 -8
  62. data/lib/hrr_rb_ssh/transport/mac_algorithm/functionable.rb +5 -3
  63. data/lib/hrr_rb_ssh/transport/mac_algorithm/unfunctionable.rb +5 -3
  64. data/lib/hrr_rb_ssh/transport/receiver.rb +8 -7
  65. data/lib/hrr_rb_ssh/transport/sender.rb +5 -3
  66. data/lib/hrr_rb_ssh/transport/sequence_number.rb +0 -4
  67. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/functionable.rb +5 -3
  68. data/lib/hrr_rb_ssh/transport.rb +41 -40
  69. data/lib/hrr_rb_ssh/version.rb +1 -1
  70. data/lib/hrr_rb_ssh.rb +0 -1
  71. metadata +6 -6
  72. data/lib/hrr_rb_ssh/logger.rb +0 -56
@@ -1,30 +1,32 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
- require 'hrr_rb_ssh/logger'
4
+ require 'hrr_rb_ssh/loggable'
5
5
 
6
6
  module HrrRbSsh
7
7
  class Authentication
8
8
  class Method
9
9
  class Password < Method
10
+ include Loggable
11
+
10
12
  NAME = 'password'
11
13
  PREFERENCE = 10
12
14
 
13
- def initialize transport, options, variables, authentication_methods
14
- @logger = Logger.new(self.class.name)
15
+ def initialize transport, options, variables, authentication_methods, logger: nil
16
+ self.logger = logger
15
17
  @transport = transport
16
- @authenticator = options.fetch( 'authentication_password_authenticator', Authenticator.new { false } )
18
+ @authenticator = options.fetch( 'authentication_password_authenticator', Authenticator.new{ false } )
17
19
  @options = options
18
20
  @variables = variables
19
21
  @authentication_methods = authentication_methods
20
22
  end
21
23
 
22
24
  def authenticate userauth_request_message
23
- @logger.info { "authenticate" }
24
- @logger.debug { "userauth request: " + userauth_request_message.inspect }
25
+ log_info { "authenticate" }
26
+ log_debug { "userauth request: " + userauth_request_message.inspect }
25
27
  username = userauth_request_message[:'user name']
26
28
  password = userauth_request_message[:'plaintext password']
27
- context = Context.new(username, password, @variables, @authentication_methods)
29
+ context = Context.new(username, password, @variables, @authentication_methods, logger: logger)
28
30
  @authenticator.authenticate context
29
31
  end
30
32
 
@@ -38,7 +40,7 @@ module HrrRbSsh
38
40
  :"FALSE" => false,
39
41
  :"plaintext password" => password,
40
42
  }
41
- payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message
43
+ payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message, logger: logger
42
44
  @transport.send payload
43
45
 
44
46
  payload = @transport.receive
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
- require 'hrr_rb_ssh/logger'
4
+ require 'hrr_rb_ssh/loggable'
5
5
  require 'hrr_rb_ssh/algorithm/publickey'
6
6
 
7
7
  module HrrRbSsh
@@ -10,16 +10,18 @@ module HrrRbSsh
10
10
  class Publickey
11
11
  class Algorithm
12
12
  module Functionable
13
- def initialize
14
- @logger = Logger.new(self.class.name)
13
+ include Loggable
14
+
15
+ def initialize logger: nil
16
+ self.logger = logger
15
17
  end
16
18
 
17
19
  def verify_public_key public_key_algorithm_name, public_key, public_key_blob
18
20
  begin
19
- publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new public_key
21
+ publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new public_key, logger: logger
20
22
  public_key_algorithm_name == self.class::NAME && public_key_blob == publickey.to_public_key_blob
21
23
  rescue => e
22
- @logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
24
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
23
25
  false
24
26
  end
25
27
  end
@@ -36,22 +38,22 @@ module HrrRbSsh
36
38
  :'public key algorithm name' => message[:'public key algorithm name'],
37
39
  :'public key blob' => message[:'public key blob'],
38
40
  }
39
- signature_blob = SignatureBlob.encode signature_blob_h
40
- publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new message[:'public key blob']
41
+ signature_blob = SignatureBlob.encode signature_blob_h, logger: logger
42
+ publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new message[:'public key blob'], logger: logger
41
43
  publickey.verify message[:'signature'], signature_blob
42
44
  rescue => e
43
- @logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
45
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
44
46
  false
45
47
  end
46
48
  end
47
49
 
48
50
  def generate_public_key_blob secret_key
49
- publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new secret_key
51
+ publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new secret_key, logger: logger
50
52
  publickey.to_public_key_blob
51
53
  end
52
54
 
53
55
  def generate_signature session_id, username, service_name, method_name, secret_key
54
- publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new secret_key
56
+ publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new secret_key, logger: logger
55
57
  publickey_blob = publickey.to_public_key_blob
56
58
  signature_blob_h = {
57
59
  :'session identifier' => session_id,
@@ -63,7 +65,7 @@ module HrrRbSsh
63
65
  :'public key algorithm name' => self.class::NAME,
64
66
  :'public key blob' => publickey_blob
65
67
  }
66
- signature_blob = SignatureBlob.encode signature_blob_h
68
+ signature_blob = SignatureBlob.encode signature_blob_h, logger: logger
67
69
  publickey.sign signature_blob
68
70
  end
69
71
  end
@@ -1,13 +1,15 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
- require 'hrr_rb_ssh/logger'
4
+ require 'hrr_rb_ssh/loggable'
5
5
 
6
6
  module HrrRbSsh
7
7
  class Authentication
8
8
  class Method
9
9
  class Publickey
10
10
  class Context
11
+ include Loggable
12
+
11
13
  attr_reader \
12
14
  :username,
13
15
  :session_id,
@@ -22,7 +24,8 @@ module HrrRbSsh
22
24
  :public_key_blob,
23
25
  :signature
24
26
 
25
- def initialize username, algorithm, session_id, message, variables, authentication_methods
27
+ def initialize username, algorithm, session_id, message, variables, authentication_methods, logger: nil
28
+ self.logger = logger
26
29
  @username = username
27
30
  @algorithm = algorithm
28
31
  @session_id = session_id
@@ -1,21 +1,23 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
- require 'hrr_rb_ssh/logger'
4
+ require 'hrr_rb_ssh/loggable'
5
5
 
6
6
  module HrrRbSsh
7
7
  class Authentication
8
8
  class Method
9
9
  class Publickey < Method
10
+ include Loggable
11
+
10
12
  NAME = 'publickey'
11
13
  PREFERENCE = 20
12
14
 
13
- def initialize transport, options, variables, authentication_methods
14
- @logger = Logger.new(self.class.name)
15
+ def initialize transport, options, variables, authentication_methods, logger: nil
16
+ self.logger = logger
15
17
  @transport = transport
16
18
  @options = options
17
19
  @session_id = options['session id']
18
- @authenticator = options.fetch( 'authentication_publickey_authenticator', Authenticator.new { false } )
20
+ @authenticator = options.fetch( 'authentication_publickey_authenticator', Authenticator.new{ false } )
19
21
  @variables = variables
20
22
  @authentication_methods = authentication_methods
21
23
  end
@@ -23,18 +25,18 @@ module HrrRbSsh
23
25
  def authenticate userauth_request_message
24
26
  public_key_algorithm_name = userauth_request_message[:'public key algorithm name']
25
27
  unless Algorithm.list_preferred.include?(public_key_algorithm_name)
26
- @logger.info { "unsupported public key algorithm: #{public_key_algorithm_name}" }
28
+ log_info { "unsupported public key algorithm: #{public_key_algorithm_name}" }
27
29
  return false
28
30
  end
29
31
  unless userauth_request_message[:'with signature']
30
- @logger.info { "public key algorithm is ok, require signature" }
32
+ log_info { "public key algorithm is ok, require signature" }
31
33
  public_key_blob = userauth_request_message[:'public key blob']
32
34
  userauth_pk_ok_message public_key_algorithm_name, public_key_blob
33
35
  else
34
- @logger.info { "verify signature" }
36
+ log_info { "verify signature" }
35
37
  username = userauth_request_message[:'user name']
36
- algorithm = Algorithm[public_key_algorithm_name].new
37
- context = Context.new(username, algorithm, @session_id, userauth_request_message, @variables, @authentication_methods)
38
+ algorithm = Algorithm[public_key_algorithm_name].new logger: logger
39
+ context = Context.new(username, algorithm, @session_id, userauth_request_message, @variables, @authentication_methods, logger: logger)
38
40
  @authenticator.authenticate context
39
41
  end
40
42
  end
@@ -45,7 +47,7 @@ module HrrRbSsh
45
47
  :'public key algorithm name from the request' => public_key_algorithm_name,
46
48
  :'public key blob from the request' => public_key_blob,
47
49
  }
48
- payload = Message::SSH_MSG_USERAUTH_PK_OK.encode message
50
+ payload = Message::SSH_MSG_USERAUTH_PK_OK.encode message, logger: logger
49
51
  end
50
52
 
51
53
  def request_authentication username, service_name
@@ -62,7 +64,7 @@ module HrrRbSsh
62
64
  end
63
65
 
64
66
  def send_request_without_signature username, service_name, public_key_algorithm_name, secret_key
65
- algorithm = Algorithm[public_key_algorithm_name].new
67
+ algorithm = Algorithm[public_key_algorithm_name].new logger: logger
66
68
  public_key_blob = algorithm.generate_public_key_blob(secret_key)
67
69
  message = {
68
70
  :'message number' => Message::SSH_MSG_USERAUTH_REQUEST::VALUE,
@@ -73,12 +75,12 @@ module HrrRbSsh
73
75
  :'public key algorithm name' => public_key_algorithm_name,
74
76
  :'public key blob' => public_key_blob,
75
77
  }
76
- payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message
78
+ payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message, logger: logger
77
79
  @transport.send payload
78
80
  end
79
81
 
80
82
  def send_request_with_signature username, service_name, public_key_algorithm_name, secret_key
81
- algorithm = Algorithm[public_key_algorithm_name].new
83
+ algorithm = Algorithm[public_key_algorithm_name].new logger: logger
82
84
  public_key_blob = algorithm.generate_public_key_blob(secret_key)
83
85
  signature = algorithm.generate_signature(@session_id, username, service_name, 'publickey', secret_key)
84
86
  message = {
@@ -91,7 +93,7 @@ module HrrRbSsh
91
93
  :'public key blob' => public_key_blob,
92
94
  :'signature' => signature,
93
95
  }
94
- payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message
96
+ payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message, logger: logger
95
97
  @transport.send payload
96
98
  end
97
99
  end
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
- require 'hrr_rb_ssh/logger'
4
+ require 'hrr_rb_ssh/loggable'
5
5
  require 'hrr_rb_ssh/message'
6
6
  require 'hrr_rb_ssh/error/closed_authentication'
7
7
  require 'hrr_rb_ssh/authentication/constant'
@@ -10,15 +10,16 @@ require 'hrr_rb_ssh/authentication/method'
10
10
 
11
11
  module HrrRbSsh
12
12
  class Authentication
13
+ include Loggable
13
14
  include Constant
14
15
 
15
- def initialize transport, mode, options={}
16
+ def initialize transport, mode, options={}, logger: nil
17
+ self.logger = logger
18
+
16
19
  @transport = transport
17
20
  @mode = mode
18
21
  @options = options
19
22
 
20
- @logger = Logger.new self.class.name
21
-
22
23
  @transport.register_acceptable_service SERVICE_NAME
23
24
 
24
25
  @closed = nil
@@ -81,42 +82,42 @@ module HrrRbSsh
81
82
 
82
83
  def respond_to_authentication
83
84
  authentication_methods = (@options['authentication_preferred_authentication_methods'].dup rescue nil) || Method.list_preferred # rescue nil.dup for Ruby version < 2.4
84
- @logger.info { "preferred authentication methods: #{authentication_methods}" }
85
+ log_info { "preferred authentication methods: #{authentication_methods}" }
85
86
  loop do
86
87
  payload = @transport.receive
87
88
  case payload[0,1].unpack("C")[0]
88
89
  when Message::SSH_MSG_USERAUTH_REQUEST::VALUE
89
- userauth_request_message = Message::SSH_MSG_USERAUTH_REQUEST.decode payload
90
+ userauth_request_message = Message::SSH_MSG_USERAUTH_REQUEST.decode payload, logger: logger
90
91
  method_name = userauth_request_message[:'method name']
91
- @logger.info { "authentication method: #{method_name}" }
92
- method = Method[method_name].new(@transport, {'session id' => @transport.session_id}.merge(@options), @variables, authentication_methods)
92
+ log_info { "authentication method: #{method_name}" }
93
+ method = Method[method_name].new(@transport, {'session id' => @transport.session_id}.merge(@options), @variables, authentication_methods, logger: logger)
93
94
  result = method.authenticate(userauth_request_message)
94
95
  case result
95
96
  when true, SUCCESS
96
- @logger.info { "verified" }
97
+ log_info { "verified" }
97
98
  send_userauth_success
98
99
  @username = userauth_request_message[:'user name']
99
100
  @closed = false
100
101
  break
101
102
  when PARTIAL_SUCCESS
102
- @logger.info { "partially verified" }
103
+ log_info { "partially verified" }
103
104
  authentication_methods.delete method_name
104
- @logger.debug { "authentication methods that can continue: #{authentication_methods}" }
105
+ log_debug { "authentication methods that can continue: #{authentication_methods}" }
105
106
  if authentication_methods.empty?
106
- @logger.info { "verified" }
107
+ log_info { "verified" }
107
108
  send_userauth_success
108
109
  @username = userauth_request_message[:'user name']
109
110
  @closed = false
110
111
  break
111
112
  else
112
- @logger.info { "continue" }
113
+ log_info { "continue" }
113
114
  send_userauth_failure authentication_methods, true
114
115
  end
115
116
  when String
116
- @logger.info { "send method specific message to continue" }
117
+ log_info { "send method specific message to continue" }
117
118
  send_method_specific_message result
118
119
  else # when false, FAILURE
119
- @logger.info { "verify failed" }
120
+ log_info { "verify failed" }
120
121
  send_userauth_failure authentication_methods, false
121
122
  end
122
123
  else
@@ -128,33 +129,33 @@ module HrrRbSsh
128
129
 
129
130
  def request_authentication
130
131
  authentication_methods = (@options['authentication_preferred_authentication_methods'].dup rescue nil) || Method.list_preferred # rescue nil.dup for Ruby version < 2.4
131
- @logger.info { "preferred authentication methods: #{authentication_methods}" }
132
+ log_info { "preferred authentication methods: #{authentication_methods}" }
132
133
  next_method_name = "none"
133
- @logger.info { "authentication request begins with none method" }
134
+ log_info { "authentication request begins with none method" }
134
135
  loop do
135
- @logger.info { "authentication method: #{next_method_name}" }
136
- method = Method[next_method_name].new(@transport, {'session id' => @transport.session_id}.merge(@options), @variables, authentication_methods)
136
+ log_info { "authentication method: #{next_method_name}" }
137
+ method = Method[next_method_name].new(@transport, {'session id' => @transport.session_id}.merge(@options), @variables, authentication_methods, logger: logger)
137
138
  payload = method.request_authentication @options['username'], "ssh-connection"
138
139
  case payload[0,1].unpack("C")[0]
139
140
  when Message::SSH_MSG_USERAUTH_SUCCESS::VALUE
140
- @logger.info { "verified" }
141
+ log_info { "verified" }
141
142
  @username = @options['username']
142
143
  @closed = false
143
144
  break
144
145
  when Message::SSH_MSG_USERAUTH_FAILURE::VALUE
145
- message = Message::SSH_MSG_USERAUTH_FAILURE.decode payload
146
+ message = Message::SSH_MSG_USERAUTH_FAILURE.decode payload, logger: logger
146
147
  partial_success = message[:'partial success']
147
148
  if partial_success
148
- @logger.info { "partially verified" }
149
+ log_info { "partially verified" }
149
150
  end
150
151
  authentication_methods_that_can_continue = message[:'authentications that can continue']
151
- @logger.debug { "authentication methods that can continue: #{authentication_methods_that_can_continue}" }
152
+ log_debug { "authentication methods that can continue: #{authentication_methods_that_can_continue}" }
152
153
  next_method_name = authentication_methods.find{ |local_m| authentication_methods_that_can_continue.find{ |remote_m| local_m == remote_m } }
153
154
  if next_method_name
154
155
  authentication_methods.delete next_method_name
155
- @logger.info { "continue" }
156
+ log_info { "continue" }
156
157
  else
157
- @logger.info { "no more available authentication methods" }
158
+ log_info { "no more available authentication methods" }
158
159
  @closed = true
159
160
  raise "failed authentication"
160
161
  end
@@ -168,7 +169,7 @@ module HrrRbSsh
168
169
  :'authentications that can continue' => authentication_methods,
169
170
  :'partial success' => partial_success,
170
171
  }
171
- payload = Message::SSH_MSG_USERAUTH_FAILURE.encode message
172
+ payload = Message::SSH_MSG_USERAUTH_FAILURE.encode message, logger: logger
172
173
  @transport.send payload
173
174
  end
174
175
 
@@ -176,7 +177,7 @@ module HrrRbSsh
176
177
  message = {
177
178
  :'message number' => Message::SSH_MSG_USERAUTH_SUCCESS::VALUE,
178
179
  }
179
- payload = Message::SSH_MSG_USERAUTH_SUCCESS.encode message
180
+ payload = Message::SSH_MSG_USERAUTH_SUCCESS.encode message, logger: logger
180
181
  @transport.send payload
181
182
  end
182
183
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'socket'
5
5
  require 'stringio'
6
- require 'hrr_rb_ssh/logger'
6
+ require 'hrr_rb_ssh/loggable'
7
7
  require 'hrr_rb_ssh/mode'
8
8
  require 'hrr_rb_ssh/transport'
9
9
  require 'hrr_rb_ssh/authentication'
@@ -11,6 +11,8 @@ require 'hrr_rb_ssh/connection'
11
11
 
12
12
  module HrrRbSsh
13
13
  class Client
14
+ include Loggable
15
+
14
16
  def self.start target, options={}
15
17
  client = self.new target, options
16
18
  client.start
@@ -26,7 +28,6 @@ module HrrRbSsh
26
28
  end
27
29
 
28
30
  def initialize target, tmp_options={}
29
- @logger = Logger.new self.class.name
30
31
  @closed = true
31
32
  options = initialize_options tmp_options
32
33
  io = case target
@@ -38,24 +39,25 @@ module HrrRbSsh
38
39
  port = 22
39
40
  io = TCPSocket.new target, port
40
41
  end
41
- transport = HrrRbSsh::Transport.new io, HrrRbSsh::Mode::CLIENT, options
42
- authentication = HrrRbSsh::Authentication.new transport, HrrRbSsh::Mode::CLIENT, options
43
- @connection = HrrRbSsh::Connection.new authentication, HrrRbSsh::Mode::CLIENT, options
42
+ transport = HrrRbSsh::Transport.new io, HrrRbSsh::Mode::CLIENT, options, logger: logger
43
+ authentication = HrrRbSsh::Authentication.new transport, HrrRbSsh::Mode::CLIENT, options, logger: logger
44
+ @connection = HrrRbSsh::Connection.new authentication, HrrRbSsh::Mode::CLIENT, options, logger: logger
44
45
  end
45
46
 
46
47
  def initialize_options tmp_options
47
48
  tmp_options = Hash[tmp_options.map{|k, v| [k.to_s, v]}]
49
+ self.logger = tmp_options['logger']
48
50
  options = {}
49
51
  options['username'] = tmp_options['username']
50
52
  options['authentication_preferred_authentication_methods'] = tmp_options['authentication_preferred_authentication_methods']
51
- options['client_authentication_password'] = tmp_options['password']
52
- options['client_authentication_publickey'] = tmp_options['publickey']
53
- options['client_authentication_keyboard_interactive'] = tmp_options['keyboard_interactive']
54
- options['transport_preferred_encryption_algorithms'] = tmp_options['transport_preferred_encryption_algorithms']
55
- options['transport_preferred_server_host_key_algorithms'] = tmp_options['transport_preferred_server_host_key_algorithms']
56
- options['transport_preferred_kex_algorithms'] = tmp_options['transport_preferred_kex_algorithms']
57
- options['transport_preferred_mac_algorithms'] = tmp_options['transport_preferred_mac_algorithms']
58
- options['transport_preferred_compression_algorithms'] = tmp_options['transport_preferred_compression_algorithms']
53
+ options['client_authentication_password'] = tmp_options['password']
54
+ options['client_authentication_publickey'] = tmp_options['publickey']
55
+ options['client_authentication_keyboard_interactive'] = tmp_options['keyboard_interactive']
56
+ options['transport_preferred_encryption_algorithms'] = tmp_options['transport_preferred_encryption_algorithms']
57
+ options['transport_preferred_server_host_key_algorithms'] = tmp_options['transport_preferred_server_host_key_algorithms']
58
+ options['transport_preferred_kex_algorithms'] = tmp_options['transport_preferred_kex_algorithms']
59
+ options['transport_preferred_mac_algorithms'] = tmp_options['transport_preferred_mac_algorithms']
60
+ options['transport_preferred_compression_algorithms'] = tmp_options['transport_preferred_compression_algorithms']
59
61
  options
60
62
  end
61
63
 
@@ -73,20 +75,20 @@ module HrrRbSsh
73
75
  end
74
76
 
75
77
  def close
76
- @logger.debug { "closing client" }
78
+ log_debug { "closing client" }
77
79
  @closed = true
78
80
  @connection.close
79
- @logger.debug { "client closed" }
81
+ log_debug { "client closed" }
80
82
  end
81
83
 
82
84
  def exec! command, pty: false, env: {}
83
- @logger.debug { "start exec!: #{command}" }
85
+ log_debug { "start exec!: #{command}" }
84
86
  out_buf = StringIO.new
85
87
  err_buf = StringIO.new
86
88
  begin
87
- @logger.info { "Opning channel" }
89
+ log_info { "Opning channel" }
88
90
  channel = @connection.request_channel_open "session"
89
- @logger.info { "Channel opened" }
91
+ log_info { "Channel opened" }
90
92
  if pty
91
93
  channel.send_channel_request_pty_req 'xterm', 80, 24, 580, 336, ''
92
94
  end
@@ -116,34 +118,34 @@ module HrrRbSsh
116
118
  begin
117
119
  t.join
118
120
  rescue => e
119
- @logger.warn { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
121
+ log_warn { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
120
122
  end
121
123
  }
122
124
  rescue => e
123
- @logger.error { "Failed opening channel" }
124
- @logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
125
+ log_error { "Failed opening channel" }
126
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
125
127
  raise "Error in exec!"
126
128
  ensure
127
129
  if channel
128
- @logger.info { "closing channel IOs" }
130
+ log_info { "closing channel IOs" }
129
131
  channel.io.each{ |io| io.close rescue nil }
130
- @logger.info { "channel IOs closed" }
131
- @logger.info { "closing channel" }
132
- @logger.info { "wait until threads closed in channel" }
132
+ log_info { "channel IOs closed" }
133
+ log_info { "closing channel" }
134
+ log_info { "wait until threads closed in channel" }
133
135
  channel.wait_until_closed
134
136
  channel.close
135
- @logger.info { "channel closed" }
137
+ log_info { "channel closed" }
136
138
  end
137
139
  end
138
140
  [out_buf.string, err_buf.string]
139
141
  end
140
142
 
141
143
  def exec command, pty: false, env: {}
142
- @logger.debug { "start exec: #{command}" }
144
+ log_debug { "start exec: #{command}" }
143
145
  begin
144
- @logger.info { "Opning channel" }
146
+ log_info { "Opning channel" }
145
147
  channel = @connection.request_channel_open "session"
146
- @logger.info { "Channel opened" }
148
+ log_info { "Channel opened" }
147
149
  if pty
148
150
  channel.send_channel_request_pty_req 'xterm', 80, 24, 580, 336, ''
149
151
  end
@@ -153,30 +155,30 @@ module HrrRbSsh
153
155
  channel.send_channel_request_exec command
154
156
  yield channel.io
155
157
  rescue => e
156
- @logger.error { "Failed opening channel" }
157
- @logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
158
+ log_error { "Failed opening channel" }
159
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
158
160
  raise "Error in shell"
159
161
  ensure
160
162
  if channel
161
- @logger.info { "closing channel IOs" }
163
+ log_info { "closing channel IOs" }
162
164
  channel.io.each{ |io| io.close rescue nil }
163
- @logger.info { "channel IOs closed" }
164
- @logger.info { "closing channel" }
165
- @logger.info { "wait until threads closed in channel" }
165
+ log_info { "channel IOs closed" }
166
+ log_info { "closing channel" }
167
+ log_info { "wait until threads closed in channel" }
166
168
  channel.wait_until_closed
167
169
  channel.close
168
- @logger.info { "channel closed" }
170
+ log_info { "channel closed" }
169
171
  end
170
172
  end
171
173
  channel_exit_status = channel.exit_status rescue nil
172
174
  end
173
175
 
174
176
  def shell env: {}
175
- @logger.debug { "start shell" }
177
+ log_debug { "start shell" }
176
178
  begin
177
- @logger.info { "Opning channel" }
179
+ log_info { "Opning channel" }
178
180
  channel = @connection.request_channel_open "session"
179
- @logger.info { "Channel opened" }
181
+ log_info { "Channel opened" }
180
182
  channel.send_channel_request_pty_req 'xterm', 80, 24, 580, 336, ''
181
183
  env.each{ |variable_name, variable_value|
182
184
  channel.send_channel_request_env variable_name, variable_value
@@ -184,46 +186,46 @@ module HrrRbSsh
184
186
  channel.send_channel_request_shell
185
187
  yield channel.io
186
188
  rescue => e
187
- @logger.error { "Failed opening channel" }
188
- @logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
189
+ log_error { "Failed opening channel" }
190
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
189
191
  raise "Error in shell"
190
192
  ensure
191
193
  if channel
192
- @logger.info { "closing channel IOs" }
194
+ log_info { "closing channel IOs" }
193
195
  channel.io.each{ |io| io.close rescue nil }
194
- @logger.info { "channel IOs closed" }
195
- @logger.info { "closing channel" }
196
- @logger.info { "wait until threads closed in channel" }
196
+ log_info { "channel IOs closed" }
197
+ log_info { "closing channel" }
198
+ log_info { "wait until threads closed in channel" }
197
199
  channel.wait_until_closed
198
200
  channel.close
199
- @logger.info { "channel closed" }
201
+ log_info { "channel closed" }
200
202
  end
201
203
  end
202
204
  channel_exit_status = channel.exit_status rescue nil
203
205
  end
204
206
 
205
207
  def subsystem name
206
- @logger.debug { "start subsystem" }
208
+ log_debug { "start subsystem" }
207
209
  begin
208
- @logger.info { "Opning channel" }
210
+ log_info { "Opning channel" }
209
211
  channel = @connection.request_channel_open "session"
210
- @logger.info { "Channel opened" }
212
+ log_info { "Channel opened" }
211
213
  channel.send_channel_request_subsystem name
212
214
  yield channel.io
213
215
  rescue => e
214
- @logger.error { "Failed opening channel" }
215
- @logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
216
+ log_error { "Failed opening channel" }
217
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
216
218
  raise "Error in subsystem"
217
219
  ensure
218
220
  if channel
219
- @logger.info { "closing channel IOs" }
221
+ log_info { "closing channel IOs" }
220
222
  channel.io.each{ |io| io.close rescue nil }
221
- @logger.info { "channel IOs closed" }
222
- @logger.info { "closing channel" }
223
- @logger.info { "wait until threads closed in channel" }
223
+ log_info { "channel IOs closed" }
224
+ log_info { "closing channel" }
225
+ log_info { "wait until threads closed in channel" }
224
226
  channel.wait_until_closed
225
227
  channel.close
226
- @logger.info { "channel closed" }
228
+ log_info { "channel closed" }
227
229
  end
228
230
  end
229
231
  channel_exit_status = channel.exit_status rescue nil