hrr_rb_ssh 0.4.0.pre1 → 0.4.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
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