harbr 0.2.10 → 2.8.1

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 (179) hide show
  1. checksums.yaml +4 -4
  2. data/.DS_Store +0 -0
  3. data/exe/harbr +225 -150
  4. data/lib/examples/container.toml +13 -0
  5. data/lib/harbr/container.rb +14 -10
  6. data/lib/harbr/host.rb +21 -0
  7. data/lib/harbr/version.rb +1 -1
  8. data/lib/harbr.rb +21 -6
  9. data/vendor/bundle/ruby/3.2.0/cache/dddr-1.0.8.gem +0 -0
  10. data/vendor/bundle/ruby/3.2.0/cache/dddr-1.1.0.gem +0 -0
  11. data/vendor/bundle/ruby/3.2.0/cache/dddr-1.1.1.gem +0 -0
  12. data/vendor/bundle/ruby/3.2.0/cache/net-ssh-7.2.1.gem +0 -0
  13. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/.DS_Store +0 -0
  14. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/.rspec +3 -0
  15. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/.standard.yml +3 -0
  16. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/CHANGELOG.md +5 -0
  17. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/CODE_OF_CONDUCT.md +84 -0
  18. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/LICENSE.txt +21 -0
  19. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/README.md +96 -0
  20. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/Rakefile +10 -0
  21. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/hero.png +0 -0
  22. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/lib/dddr/version.rb +5 -0
  23. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/lib/dddr.rb +205 -0
  24. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/sig/dddr.rbs +4 -0
  25. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/.DS_Store +0 -0
  26. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/.rspec +3 -0
  27. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/.standard.yml +3 -0
  28. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/CHANGELOG.md +5 -0
  29. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/CODE_OF_CONDUCT.md +84 -0
  30. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/LICENSE.txt +21 -0
  31. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/README.md +96 -0
  32. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/Rakefile +10 -0
  33. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/hero.png +0 -0
  34. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/lib/dddr/version.rb +5 -0
  35. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/lib/dddr.rb +182 -0
  36. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/sig/dddr.rbs +4 -0
  37. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/.DS_Store +0 -0
  38. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/.rspec +3 -0
  39. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/.standard.yml +3 -0
  40. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/CHANGELOG.md +5 -0
  41. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/CODE_OF_CONDUCT.md +84 -0
  42. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/LICENSE.txt +21 -0
  43. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/README.md +96 -0
  44. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/Rakefile +10 -0
  45. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/hero.png +0 -0
  46. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/lib/dddr/version.rb +5 -0
  47. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/lib/dddr.rb +184 -0
  48. data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/sig/dddr.rbs +4 -0
  49. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.dockerignore +6 -0
  50. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.github/FUNDING.yml +1 -0
  51. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.github/config/rubocop_linter_action.yml +4 -0
  52. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.github/workflows/ci-with-docker.yml +44 -0
  53. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.github/workflows/ci.yml +94 -0
  54. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.github/workflows/rubocop.yml +16 -0
  55. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.gitignore +15 -0
  56. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.rubocop.yml +22 -0
  57. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.rubocop_todo.yml +1081 -0
  58. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/CHANGES.txt +738 -0
  59. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/DEVELOPMENT.md +23 -0
  60. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Dockerfile +29 -0
  61. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Dockerfile.openssl3 +17 -0
  62. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Gemfile +13 -0
  63. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Gemfile.noed25519 +12 -0
  64. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Gemfile.norbnacl +12 -0
  65. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/ISSUE_TEMPLATE.md +30 -0
  66. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/LICENSE.txt +19 -0
  67. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Manifest +132 -0
  68. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/README.md +298 -0
  69. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Rakefile +192 -0
  70. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/SECURITY.md +4 -0
  71. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/THANKS.txt +110 -0
  72. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/appveyor.yml +58 -0
  73. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/docker-compose.yml +25 -0
  74. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/agent.rb +284 -0
  75. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/certificate.rb +183 -0
  76. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/constants.rb +20 -0
  77. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/ed25519.rb +186 -0
  78. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
  79. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/key_manager.rb +327 -0
  80. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/abstract.rb +79 -0
  81. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/hostbased.rb +72 -0
  82. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/keyboard_interactive.rb +77 -0
  83. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/none.rb +34 -0
  84. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/password.rb +80 -0
  85. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/publickey.rb +137 -0
  86. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/pageant.rb +497 -0
  87. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  88. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/session.rb +172 -0
  89. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/buffer.rb +449 -0
  90. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/buffered_io.rb +202 -0
  91. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/config.rb +406 -0
  92. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/channel.rb +694 -0
  93. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/constants.rb +33 -0
  94. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/event_loop.rb +123 -0
  95. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/keepalive.rb +59 -0
  96. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/session.rb +712 -0
  97. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/term.rb +180 -0
  98. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/errors.rb +106 -0
  99. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/key_factory.rb +218 -0
  100. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/known_hosts.rb +265 -0
  101. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/loggable.rb +62 -0
  102. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/packet.rb +106 -0
  103. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/prompt.rb +62 -0
  104. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/command.rb +123 -0
  105. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/errors.rb +16 -0
  106. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/http.rb +98 -0
  107. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/https.rb +50 -0
  108. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/jump.rb +54 -0
  109. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/socks4.rb +67 -0
  110. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/socks5.rb +140 -0
  111. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/service/forward.rb +426 -0
  112. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/channel.rb +147 -0
  113. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/extensions.rb +173 -0
  114. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/kex.rb +46 -0
  115. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/local_packet.rb +53 -0
  116. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/packet.rb +101 -0
  117. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/remote_packet.rb +40 -0
  118. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/script.rb +180 -0
  119. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/socket.rb +65 -0
  120. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test.rb +94 -0
  121. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/algorithms.rb +524 -0
  122. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
  123. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
  124. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/cipher_factory.rb +128 -0
  125. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/constants.rb +40 -0
  126. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/ctr.rb +115 -0
  127. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/abstract.rb +97 -0
  128. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/md5.rb +10 -0
  129. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/md5_96.rb +9 -0
  130. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/none.rb +13 -0
  131. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/ripemd160.rb +11 -0
  132. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha1.rb +11 -0
  133. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha1_96.rb +9 -0
  134. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_256.rb +11 -0
  135. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_256_96.rb +9 -0
  136. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  137. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_512.rb +11 -0
  138. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_512_96.rb +9 -0
  139. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  140. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac.rb +47 -0
  141. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/identity_cipher.rb +65 -0
  142. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/abstract.rb +130 -0
  143. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  144. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  145. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  146. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +37 -0
  147. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  148. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +122 -0
  149. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +72 -0
  150. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +11 -0
  151. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +39 -0
  152. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +21 -0
  153. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +21 -0
  154. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex.rb +31 -0
  155. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/key_expander.rb +30 -0
  156. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/openssl.rb +274 -0
  157. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
  158. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/packet_stream.rb +301 -0
  159. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/server_version.rb +77 -0
  160. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/session.rb +354 -0
  161. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/state.rb +208 -0
  162. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/verifiers/accept_new.rb +33 -0
  163. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
  164. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/verifiers/always.rb +58 -0
  165. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/verifiers/never.rb +19 -0
  166. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/version.rb +68 -0
  167. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh.rb +338 -0
  168. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/net-ssh-public_cert.pem +20 -0
  169. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/net-ssh.gemspec +46 -0
  170. data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/support/ssh_tunnel_bug.rb +65 -0
  171. data/vendor/bundle/ruby/3.2.0/specifications/dddr-1.0.8.gemspec +27 -0
  172. data/vendor/bundle/ruby/3.2.0/specifications/dddr-1.1.0.gemspec +27 -0
  173. data/vendor/bundle/ruby/3.2.0/specifications/dddr-1.1.1.gemspec +27 -0
  174. data/vendor/bundle/ruby/3.2.0/specifications/net-ssh-7.2.1.gemspec +38 -0
  175. metadata +174 -9
  176. data/config/manifest.yml +0 -5
  177. data/lib/harbr/job.rb +0 -252
  178. data/lib/harbr/lxd/job.rb +0 -119
  179. data/lib/harbr/lxd/setup.rb +0 -45
@@ -0,0 +1,172 @@
1
+ require 'net/ssh/loggable'
2
+ require 'net/ssh/transport/constants'
3
+ require 'net/ssh/authentication/constants'
4
+ require 'net/ssh/authentication/key_manager'
5
+ require 'net/ssh/authentication/methods/none'
6
+ require 'net/ssh/authentication/methods/publickey'
7
+ require 'net/ssh/authentication/methods/hostbased'
8
+ require 'net/ssh/authentication/methods/password'
9
+ require 'net/ssh/authentication/methods/keyboard_interactive'
10
+
11
+ module Net
12
+ module SSH
13
+ module Authentication
14
+ # Raised if the current authentication method is not allowed
15
+ class DisallowedMethod < Net::SSH::Exception
16
+ end
17
+
18
+ # Represents an authentication session. It manages the authentication of
19
+ # a user over an established connection (the "transport" object, see
20
+ # Net::SSH::Transport::Session).
21
+ #
22
+ # The use of an authentication session to manage user authentication is
23
+ # internal to Net::SSH (specifically Net::SSH.start). Consumers of the
24
+ # Net::SSH library will never need to access this class directly.
25
+ class Session
26
+ include Loggable
27
+ include Constants
28
+ include Transport::Constants
29
+
30
+ # transport layer abstraction
31
+ attr_reader :transport
32
+
33
+ # the list of authentication methods to try
34
+ attr_reader :auth_methods
35
+
36
+ # the list of authentication methods that are allowed
37
+ attr_reader :allowed_auth_methods
38
+
39
+ # a hash of options, given at construction time
40
+ attr_reader :options
41
+
42
+ # Instantiates a new Authentication::Session object over the given
43
+ # transport layer abstraction.
44
+ def initialize(transport, options = {})
45
+ self.logger = transport.logger
46
+ @transport = transport
47
+
48
+ @auth_methods = options[:auth_methods] || Net::SSH::Config.default_auth_methods
49
+ @options = options
50
+
51
+ @allowed_auth_methods = @auth_methods
52
+ end
53
+
54
+ # Attempts to authenticate the given user, in preparation for the next
55
+ # service request. Returns true if an authentication method succeeds in
56
+ # authenticating the user, and false otherwise.
57
+ def authenticate(next_service, username, password = nil)
58
+ debug { "beginning authentication of `#{username}'" }
59
+
60
+ transport.send_message(transport.service_request("ssh-userauth"))
61
+ expect_message(SERVICE_ACCEPT)
62
+
63
+ key_manager = KeyManager.new(logger, options)
64
+ keys.each { |key| key_manager.add(key) } unless keys.empty?
65
+ keycerts.each { |keycert| key_manager.add_keycert(keycert) } unless keycerts.empty?
66
+ keycert_data.each { |data| key_manager.add_keycert_data(data) } unless keycert_data.empty?
67
+ key_data.each { |key2| key_manager.add_key_data(key2) } unless key_data.empty?
68
+ default_keys.each { |key| key_manager.add(key) } unless options.key?(:keys) || options.key?(:key_data)
69
+
70
+ attempted = []
71
+
72
+ @auth_methods.each do |name|
73
+ next unless @allowed_auth_methods.include?(name)
74
+
75
+ attempted << name
76
+
77
+ debug { "trying #{name}" }
78
+ begin
79
+ auth_class = Methods.const_get(name.split(/\W+/).map { |p| p.capitalize }.join)
80
+ method = auth_class.new(self,
81
+ key_manager: key_manager, password_prompt: options[:password_prompt],
82
+ pubkey_algorithms: options[:pubkey_algorithms] || nil)
83
+ rescue NameError
84
+ debug {"Mechanism #{name} was requested, but isn't a known type. Ignoring it."}
85
+ next
86
+ end
87
+
88
+ return true if method.authenticate(next_service, username, password)
89
+ rescue Net::SSH::Authentication::DisallowedMethod
90
+ end
91
+
92
+ error { "all authorization methods failed (tried #{attempted.join(', ')})" }
93
+ return false
94
+ ensure
95
+ key_manager.finish if key_manager
96
+ end
97
+
98
+ # Blocks until a packet is received. It silently handles USERAUTH_BANNER
99
+ # packets, and will raise an error if any packet is received that is not
100
+ # valid during user authentication.
101
+ def next_message
102
+ loop do
103
+ packet = transport.next_message
104
+
105
+ case packet.type
106
+ when USERAUTH_BANNER
107
+ info { packet[:message] }
108
+ # TODO add a hook for people to retrieve the banner when it is sent
109
+
110
+ when USERAUTH_FAILURE
111
+ @allowed_auth_methods = packet[:authentications].split(/,/)
112
+ debug { "allowed methods: #{packet[:authentications]}" }
113
+ return packet
114
+
115
+ when USERAUTH_METHOD_RANGE, SERVICE_ACCEPT
116
+ return packet
117
+
118
+ when USERAUTH_SUCCESS
119
+ transport.hint :authenticated
120
+ return packet
121
+
122
+ else
123
+ raise Net::SSH::Exception, "unexpected message #{packet.type} (#{packet})"
124
+ end
125
+ end
126
+ end
127
+
128
+ # Blocks until a packet is received, and returns it if it is of the given
129
+ # type. If it is not, an exception is raised.
130
+ def expect_message(type)
131
+ message = next_message
132
+ raise Net::SSH::Exception, "expected #{type}, got #{message.type} (#{message})" unless message.type == type
133
+
134
+ message
135
+ end
136
+
137
+ private
138
+
139
+ # Returns an array of paths to the key files usually defined
140
+ # by system default.
141
+ def default_keys
142
+ %w[~/.ssh/id_ed25519 ~/.ssh/id_rsa ~/.ssh/id_dsa ~/.ssh/id_ecdsa
143
+ ~/.ssh2/id_ed25519 ~/.ssh2/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_ecdsa]
144
+ end
145
+
146
+ # Returns an array of paths to the key files that should be used when
147
+ # attempting any key-based authentication mechanism.
148
+ def keys
149
+ Array(options[:keys])
150
+ end
151
+
152
+ # Returns an array of paths to the keycert files that should be used when
153
+ # attempting any key-based authentication mechanism.
154
+ def keycerts
155
+ Array(options[:keycerts])
156
+ end
157
+
158
+ # Returns an array of the keycert data that should be used when
159
+ # attempting any key-based authentication mechanism.
160
+ def keycert_data
161
+ Array(options[:keycert_data])
162
+ end
163
+
164
+ # Returns an array of the key data that should be used when
165
+ # attempting any key-based authentication mechanism.
166
+ def key_data
167
+ Array(options[:key_data])
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,449 @@
1
+ require 'net/ssh/transport/openssl'
2
+
3
+ require 'net/ssh/authentication/certificate'
4
+ require 'net/ssh/authentication/ed25519_loader'
5
+
6
+ module Net
7
+ module SSH
8
+ # Net::SSH::Buffer is a flexible class for building and parsing binary
9
+ # data packets. It provides a stream-like interface for sequentially
10
+ # reading data items from the buffer, as well as a useful helper method
11
+ # for building binary packets given a signature.
12
+ #
13
+ # Writing to a buffer always appends to the end, regardless of where the
14
+ # read cursor is. Reading, on the other hand, always begins at the first
15
+ # byte of the buffer and increments the read cursor, with subsequent reads
16
+ # taking up where the last left off.
17
+ #
18
+ # As a consumer of the Net::SSH library, you will rarely come into contact
19
+ # with these buffer objects directly, but it could happen. Also, if you
20
+ # are ever implementing a protocol on top of SSH (e.g. SFTP), this buffer
21
+ # class can be quite handy.
22
+ class Buffer
23
+ # This is a convenience method for creating and populating a new buffer
24
+ # from a single command. The arguments must be even in length, with the
25
+ # first of each pair of arguments being a symbol naming the type of the
26
+ # data that follows. If the type is :raw, the value is written directly
27
+ # to the hash.
28
+ #
29
+ # b = Buffer.from(:byte, 1, :string, "hello", :raw, "\1\2\3\4")
30
+ # #-> "\1\0\0\0\5hello\1\2\3\4"
31
+ #
32
+ # The supported data types are:
33
+ #
34
+ # * :raw => write the next value verbatim (#write)
35
+ # * :int64 => write an 8-byte integer (#write_int64)
36
+ # * :long => write a 4-byte integer (#write_long)
37
+ # * :byte => write a single byte (#write_byte)
38
+ # * :string => write a 4-byte length followed by character data (#write_string)
39
+ # * :mstring => same as string, but caller cannot resuse the string, avoids potential duplication (#write_moved)
40
+ # * :bool => write a single byte, interpreted as a boolean (#write_bool)
41
+ # * :bignum => write an SSH-encoded bignum (#write_bignum)
42
+ # * :key => write an SSH-encoded key value (#write_key)
43
+ #
44
+ # Any of these, except for :raw, accepts an Array argument, to make it
45
+ # easier to write multiple values of the same type in a briefer manner.
46
+ def self.from(*args)
47
+ raise ArgumentError, "odd number of arguments given" unless args.length % 2 == 0
48
+
49
+ buffer = new
50
+ 0.step(args.length - 1, 2) do |index|
51
+ type = args[index]
52
+ value = args[index + 1]
53
+ if type == :raw
54
+ buffer.append(value.to_s)
55
+ elsif Array === value
56
+ buffer.send("write_#{type}", *value)
57
+ else
58
+ buffer.send("write_#{type}", value)
59
+ end
60
+ end
61
+
62
+ buffer
63
+ end
64
+
65
+ # exposes the raw content of the buffer
66
+ attr_reader :content
67
+
68
+ # the current position of the pointer in the buffer
69
+ attr_accessor :position
70
+
71
+ # Creates a new buffer, initialized to the given content. The position
72
+ # is initialized to the beginning of the buffer.
73
+ def initialize(content = String.new)
74
+ @content = content.to_s
75
+ @position = 0
76
+ end
77
+
78
+ # Returns the length of the buffer's content.
79
+ def length
80
+ @content.length
81
+ end
82
+
83
+ # Returns the number of bytes available to be read (e.g., how many bytes
84
+ # remain between the current position and the end of the buffer).
85
+ def available
86
+ length - position
87
+ end
88
+
89
+ # Returns a copy of the buffer's content.
90
+ def to_s
91
+ (@content || "").dup
92
+ end
93
+
94
+ # Compares the contents of the two buffers, returning +true+ only if they
95
+ # are identical in size and content.
96
+ def ==(buffer)
97
+ to_s == buffer.to_s
98
+ end
99
+
100
+ # Returns +true+ if the buffer contains no data (e.g., it is of zero length).
101
+ def empty?
102
+ @content.empty?
103
+ end
104
+
105
+ # Resets the pointer to the start of the buffer. Subsequent reads will
106
+ # begin at position 0.
107
+ def reset!
108
+ @position = 0
109
+ end
110
+
111
+ # Returns true if the pointer is at the end of the buffer. Subsequent
112
+ # reads will return nil, in this case.
113
+ def eof?
114
+ @position >= length
115
+ end
116
+
117
+ # Resets the buffer, making it empty. Also, resets the read position to
118
+ # 0.
119
+ def clear!
120
+ @content = String.new
121
+ @position = 0
122
+ end
123
+
124
+ # Consumes n bytes from the buffer, where n is the current position
125
+ # unless otherwise specified. This is useful for removing data from the
126
+ # buffer that has previously been read, when you are expecting more data
127
+ # to be appended. It helps to keep the size of buffers down when they
128
+ # would otherwise tend to grow without bound.
129
+ #
130
+ # Returns the buffer object itself.
131
+ def consume!(n = position)
132
+ if n >= length
133
+ # optimize for a fairly common case
134
+ clear!
135
+ elsif n > 0
136
+ @content = @content[n..-1] || String.new
137
+ @position -= n
138
+ @position = 0 if @position < 0
139
+ end
140
+ self
141
+ end
142
+
143
+ # Appends the given text to the end of the buffer. Does not alter the
144
+ # read position. Returns the buffer object itself.
145
+ def append(text)
146
+ @content << text
147
+ self
148
+ end
149
+
150
+ # Returns all text from the current pointer to the end of the buffer as
151
+ # a new Net::SSH::Buffer object.
152
+ def remainder_as_buffer
153
+ Buffer.new(@content[@position..-1])
154
+ end
155
+
156
+ # Reads all data up to and including the given pattern, which may be a
157
+ # String, Fixnum, or Regexp and is interpreted exactly as String#index
158
+ # does. Returns nil if nothing matches. Increments the position to point
159
+ # immediately after the pattern, if it does match. Returns all data up to
160
+ # and including the text that matched the pattern.
161
+ def read_to(pattern)
162
+ index = @content.index(pattern, @position) or return nil
163
+ length = case pattern
164
+ when String then pattern.length
165
+ when Integer then 1
166
+ when Regexp then $&.length
167
+ end
168
+ index && read(index + length)
169
+ end
170
+
171
+ # Reads and returns the next +count+ bytes from the buffer, starting from
172
+ # the read position. If +count+ is +nil+, this will return all remaining
173
+ # text in the buffer. This method will increment the pointer.
174
+ def read(count = nil)
175
+ count ||= length
176
+ count = length - @position if @position + count > length
177
+ @position += count
178
+ @content[@position - count, count]
179
+ end
180
+
181
+ # Reads (as #read) and returns the given number of bytes from the buffer,
182
+ # and then consumes (as #consume!) all data up to the new read position.
183
+ def read!(count = nil)
184
+ data = read(count)
185
+ consume!
186
+ data
187
+ end
188
+
189
+ # Calls block(self) until the buffer is empty, and returns all results.
190
+ def read_all(&block)
191
+ Enumerator.new { |e| e << yield(self) until eof? }.to_a
192
+ end
193
+
194
+ # Return the next 8 bytes as a 64-bit integer (in network byte order).
195
+ # Returns nil if there are less than 8 bytes remaining to be read in the
196
+ # buffer.
197
+ def read_int64
198
+ hi = read_long or return nil
199
+ lo = read_long or return nil
200
+ return (hi << 32) + lo
201
+ end
202
+
203
+ # Return the next four bytes as a long integer (in network byte order).
204
+ # Returns nil if there are less than 4 bytes remaining to be read in the
205
+ # buffer.
206
+ def read_long
207
+ b = read(4) or return nil
208
+ b.unpack("N").first
209
+ end
210
+
211
+ # Read and return the next byte in the buffer. Returns nil if called at
212
+ # the end of the buffer.
213
+ def read_byte
214
+ b = read(1) or return nil
215
+ b.getbyte(0)
216
+ end
217
+
218
+ # Read and return an SSH2-encoded string. The string starts with a long
219
+ # integer that describes the number of bytes remaining in the string.
220
+ # Returns nil if there are not enough bytes to satisfy the request.
221
+ def read_string
222
+ length = read_long or return nil
223
+ read(length)
224
+ end
225
+
226
+ # Read a single byte and convert it into a boolean, using 'C' rules
227
+ # (i.e., zero is false, non-zero is true).
228
+ def read_bool
229
+ b = read_byte or return nil
230
+ b != 0
231
+ end
232
+
233
+ # Read a bignum (OpenSSL::BN) from the buffer, in SSH2 format. It is
234
+ # essentially just a string, which is reinterpreted to be a bignum in
235
+ # binary format.
236
+ def read_bignum
237
+ data = read_string
238
+ return unless data
239
+
240
+ OpenSSL::BN.new(data, 2)
241
+ end
242
+
243
+ # Read a key from the buffer. The key will start with a string
244
+ # describing its type. The remainder of the key is defined by the
245
+ # type that was read.
246
+ def read_key
247
+ type = read_string
248
+ return (type ? read_keyblob(type) : nil)
249
+ end
250
+
251
+ def read_private_keyblob(type)
252
+ case type
253
+ when /^ssh-rsa$/
254
+ n = read_bignum
255
+ e = read_bignum
256
+ d = read_bignum
257
+ iqmp = read_bignum
258
+ p = read_bignum
259
+ q = read_bignum
260
+ _unkown1 = read_bignum
261
+ _unkown2 = read_bignum
262
+ dmp1 = d % (p - 1)
263
+ dmq1 = d % (q - 1)
264
+ # Public key
265
+ data_sequence = OpenSSL::ASN1::Sequence([
266
+ OpenSSL::ASN1::Integer(n),
267
+ OpenSSL::ASN1::Integer(e)
268
+ ])
269
+
270
+ if d && p && q && dmp1 && dmq1 && iqmp
271
+ data_sequence = OpenSSL::ASN1::Sequence([
272
+ OpenSSL::ASN1::Integer(0),
273
+ OpenSSL::ASN1::Integer(n),
274
+ OpenSSL::ASN1::Integer(e),
275
+ OpenSSL::ASN1::Integer(d),
276
+ OpenSSL::ASN1::Integer(p),
277
+ OpenSSL::ASN1::Integer(q),
278
+ OpenSSL::ASN1::Integer(dmp1),
279
+ OpenSSL::ASN1::Integer(dmq1),
280
+ OpenSSL::ASN1::Integer(iqmp)
281
+ ])
282
+ end
283
+
284
+ asn1 = OpenSSL::ASN1::Sequence(data_sequence)
285
+ OpenSSL::PKey::RSA.new(asn1.to_der)
286
+ when /^ecdsa\-sha2\-(\w*)$/
287
+ OpenSSL::PKey::EC.read_keyblob($1, self)
288
+ else
289
+ raise Exception, "Cannot decode private key of type #{type}"
290
+ end
291
+ end
292
+
293
+ # Read a keyblob of the given type from the buffer, and return it as
294
+ # a key. Only RSA, DSA, and ECDSA keys are supported.
295
+ def read_keyblob(type)
296
+ case type
297
+ when /^(.*)-cert-v01@openssh\.com$/
298
+ key = Net::SSH::Authentication::Certificate.read_certblob(self, $1)
299
+ when /^ssh-dss$/
300
+ p = read_bignum
301
+ q = read_bignum
302
+ g = read_bignum
303
+ pub_key = read_bignum
304
+
305
+ asn1 = OpenSSL::ASN1::Sequence.new(
306
+ [
307
+ OpenSSL::ASN1::Sequence.new(
308
+ [
309
+ OpenSSL::ASN1::ObjectId.new('DSA'),
310
+ OpenSSL::ASN1::Sequence.new(
311
+ [
312
+ OpenSSL::ASN1::Integer.new(p),
313
+ OpenSSL::ASN1::Integer.new(q),
314
+ OpenSSL::ASN1::Integer.new(g)
315
+ ]
316
+ )
317
+ ]
318
+ ),
319
+ OpenSSL::ASN1::BitString.new(OpenSSL::ASN1::Integer.new(pub_key).to_der)
320
+ ]
321
+ )
322
+
323
+ key = OpenSSL::PKey::DSA.new(asn1.to_der)
324
+ when /^ssh-rsa$/
325
+ e = read_bignum
326
+ n = read_bignum
327
+
328
+ asn1 = OpenSSL::ASN1::Sequence(
329
+ [
330
+ OpenSSL::ASN1::Integer(n),
331
+ OpenSSL::ASN1::Integer(e)
332
+ ]
333
+ )
334
+
335
+ key = OpenSSL::PKey::RSA.new(asn1.to_der)
336
+ when /^ssh-ed25519$/
337
+ Net::SSH::Authentication::ED25519Loader.raiseUnlessLoaded("unsupported key type `#{type}'")
338
+ key = Net::SSH::Authentication::ED25519::PubKey.read_keyblob(self)
339
+ when /^ecdsa\-sha2\-(\w*)$/
340
+ key = OpenSSL::PKey::EC.read_keyblob($1, self)
341
+ else
342
+ raise NotImplementedError, "unsupported key type `#{type}'"
343
+ end
344
+
345
+ return key
346
+ end
347
+
348
+ # Reads the next string from the buffer, and returns a new Buffer
349
+ # object that wraps it.
350
+ def read_buffer
351
+ Buffer.new(read_string)
352
+ end
353
+
354
+ # Writes the given data literally into the string. Does not alter the
355
+ # read position. Returns the buffer object.
356
+ def write(*data)
357
+ data.each { |datum| @content << datum.dup.force_encoding('BINARY') }
358
+ self
359
+ end
360
+
361
+ # Optimized version of write where the caller gives up ownership of string
362
+ # to the method. This way we can mutate the string.
363
+ def write_moved(string)
364
+ @content <<
365
+ if string.frozen?
366
+ string.dup.force_encoding('BINARY')
367
+ else
368
+ string.force_encoding('BINARY')
369
+ end
370
+ self
371
+ end
372
+
373
+ # Writes each argument to the buffer as a network-byte-order-encoded
374
+ # 64-bit integer (8 bytes). Does not alter the read position. Returns the
375
+ # buffer object.
376
+ def write_int64(*n)
377
+ n.each do |i|
378
+ hi = (i >> 32) & 0xFFFFFFFF
379
+ lo = i & 0xFFFFFFFF
380
+ @content << [hi, lo].pack("N2")
381
+ end
382
+ self
383
+ end
384
+
385
+ # Writes each argument to the buffer as a network-byte-order-encoded
386
+ # long (4-byte) integer. Does not alter the read position. Returns the
387
+ # buffer object.
388
+ def write_long(*n)
389
+ @content << n.pack("N*")
390
+ self
391
+ end
392
+
393
+ # Writes each argument to the buffer as a byte. Does not alter the read
394
+ # position. Returns the buffer object.
395
+ def write_byte(*n)
396
+ n.each { |b| @content << b.chr }
397
+ self
398
+ end
399
+
400
+ # Writes each argument to the buffer as an SSH2-encoded string. Each
401
+ # string is prefixed by its length, encoded as a 4-byte long integer.
402
+ # Does not alter the read position. Returns the buffer object.
403
+ def write_string(*text)
404
+ text.each do |string|
405
+ s = string.to_s
406
+ write_long(s.bytesize)
407
+ write(s)
408
+ end
409
+ self
410
+ end
411
+
412
+ # Writes each argument to the buffer as an SSH2-encoded string. Each
413
+ # string is prefixed by its length, encoded as a 4-byte long integer.
414
+ # Does not alter the read position. Returns the buffer object.
415
+ # Might alter arguments see write_moved
416
+ def write_mstring(*text)
417
+ text.each do |string|
418
+ s = string.to_s
419
+ write_long(s.bytesize)
420
+ write_moved(s)
421
+ end
422
+ self
423
+ end
424
+
425
+ # Writes each argument to the buffer as a (C-style) boolean, with 1
426
+ # meaning true, and 0 meaning false. Does not alter the read position.
427
+ # Returns the buffer object.
428
+ def write_bool(*b)
429
+ b.each { |v| @content << (v ? "\1" : "\0") }
430
+ self
431
+ end
432
+
433
+ # Writes each argument to the buffer as a bignum (SSH2-style). No
434
+ # checking is done to ensure that the arguments are, in fact, bignums.
435
+ # Does not alter the read position. Returns the buffer object.
436
+ def write_bignum(*n)
437
+ @content << n.map { |b| b.to_ssh }.join
438
+ self
439
+ end
440
+
441
+ # Writes the given arguments to the buffer as SSH2-encoded keys. Does not
442
+ # alter the read position. Returns the buffer object.
443
+ def write_key(*key)
444
+ key.each { |k| append(k.to_blob) }
445
+ self
446
+ end
447
+ end
448
+ end
449
+ end;