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,192 @@
1
+ #
2
+ # Also in your terminal environment run:
3
+ # $ export LANG=en_US.UTF-8
4
+ # $ export LANGUAGE=en_US.UTF-8
5
+ # $ export LC_ALL=en_US.UTF-8
6
+
7
+ require "rubygems"
8
+ require "rake"
9
+ require "rake/clean"
10
+ require "bundler/gem_tasks"
11
+
12
+ require "rdoc/task"
13
+
14
+ desc "When releasing make sure NET_SSH_BUILDGEM_SIGNED is set"
15
+ task :check_NET_SSH_BUILDGEM_SIGNED do
16
+ raise "NET_SSH_BUILDGEM_SIGNED should be set to release" unless ENV['NET_SSH_BUILDGEM_SIGNED']
17
+ end
18
+
19
+ Rake::Task[:release].enhance [:check_NET_SSH_BUILDGEM_SIGNED]
20
+ Rake::Task[:release].prerequisites.unshift(:check_NET_SSH_BUILDGEM_SIGNED)
21
+
22
+ task default: ["build"]
23
+ CLEAN.include ['pkg', 'rdoc']
24
+ name = "net-ssh"
25
+
26
+ require_relative "lib/net/ssh/version"
27
+ version = Net::SSH::Version::CURRENT
28
+
29
+ extra_files = %w[LICENSE.txt THANKS.txt CHANGES.txt]
30
+ RDoc::Task.new do |rdoc|
31
+ rdoc.rdoc_dir = "rdoc"
32
+ rdoc.title = "#{name} #{version}"
33
+ rdoc.generator = 'hanna' # gem install hanna-nouveau
34
+ rdoc.main = 'README.md'
35
+ rdoc.rdoc_files.include("README*")
36
+ rdoc.rdoc_files.include("bin/*.rb")
37
+ rdoc.rdoc_files.include("lib/**/*.rb")
38
+ extra_files.each { |file|
39
+ rdoc.rdoc_files.include(file) if File.exist?(file)
40
+ }
41
+ end
42
+
43
+ namespace :cert do
44
+ desc "Update public cert from private - only run if public is expired"
45
+ task :update_public_when_expired do
46
+ require 'openssl'
47
+ require 'time'
48
+ raw = File.read "net-ssh-public_cert.pem"
49
+ certificate = OpenSSL::X509::Certificate.new raw
50
+ raise Exception, "Not yet expired: #{certificate.not_after}" unless certificate.not_after < Time.now
51
+
52
+ sh "gem cert --build netssh@solutious.com --days 365*5 --private-key /mnt/gem/net-ssh-private_key.pem"
53
+ sh "mv gem-public_cert.pem net-ssh-public_cert.pem"
54
+ sh "gem cert --add net-ssh-public_cert.pem"
55
+ end
56
+ end
57
+
58
+ def change_version(&block)
59
+ version_file = 'lib/net/ssh/version.rb'
60
+ require_relative version_file
61
+ pre = Net::SSH::Version::PRE
62
+ tiny = Net::SSH::Version::TINY
63
+ result = block[pre: pre, tiny: Net::SSH::Version::TINY]
64
+ raise "Version change logic should always return a pre", ArgumentError unless result.key?(:pre)
65
+
66
+ new_pre = result[:pre]
67
+ new_tiny = result[:tiny] || tiny
68
+ found = { pre: false, tiny: false }
69
+ File.open("#{version_file}.new", "w") do |f|
70
+ File.readlines(version_file).each do |line|
71
+ match =
72
+ if pre.nil?
73
+ /^(\s+PRE\s+=\s+)nil(\s*)$/.match(line)
74
+ else
75
+ /^(\s+PRE\s+=\s+")#{pre}("\s*)$/.match(line)
76
+ end
77
+ if match
78
+ prefix = match[1]
79
+ postfix = match[2]
80
+ prefix.delete_suffix!('"')
81
+ postfix.delete_prefix!('"')
82
+ new_line = "#{prefix}#{new_pre.inspect}#{postfix}"
83
+ puts "Changing:\n - #{line} + #{new_line}"
84
+ line = new_line
85
+ found[:pre] = true
86
+ end
87
+
88
+ if new_tiny != tiny
89
+ match = /^(\s+TINY\s+=\s+)#{tiny}(\s*)$/.match(line)
90
+ if match
91
+ prefix = match[1]
92
+ postfix = match[2]
93
+ new_line = "#{prefix}#{new_tiny}#{postfix}"
94
+ puts "Changing:\n - #{line} + #{new_line}"
95
+ line = new_line
96
+ found[:tiny] = true
97
+ end
98
+ end
99
+
100
+ f.write(line)
101
+ end
102
+ raise ArgumentError, "Cound not find line: PRE = \"#{pre}\" in #{version_file}" unless found[:pre]
103
+ raise ArgumentError, "Cound not find line: TINY = \"#{tiny}\" in #{version_file}" unless found[:tiny] || new_tiny == tiny
104
+ end
105
+
106
+ FileUtils.mv version_file, "#{version_file}.old"
107
+ FileUtils.mv "#{version_file}.new", version_file
108
+ end
109
+
110
+ namespace :vbump do
111
+ desc "Final release"
112
+ task :final do
113
+ change_version do |pre:, tiny:|
114
+ _ = tiny
115
+ raise ArgumentError, "Unexpected pre: #{pre}" if pre.nil?
116
+
117
+ { pre: nil }
118
+ end
119
+ end
120
+
121
+ desc "Increment prerelease"
122
+ task :pre, [:type] do |_t, args|
123
+ change_version do |pre:, tiny:|
124
+ puts " PRE => #{pre.inspect}"
125
+ match = /^([a-z]+)(\d+)/.match(pre)
126
+ raise ArgumentError, "Unexpected pre: #{pre}" if match.nil? && args[:type].nil?
127
+
128
+ if match.nil? || (!args[:type].nil? && args[:type] != match[1])
129
+ if pre.nil?
130
+ { pre: "#{args[:type]}1", tiny: tiny + 1 }
131
+ else
132
+ { pre: "#{args[:type]}1" }
133
+ end
134
+ else
135
+ { pre: "#{match[1]}#{match[2].to_i + 1}" }
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ namespace :rdoc do
142
+ desc "Update gh-pages branch"
143
+ task :publish do
144
+ # copy/checkout
145
+ rm_rf "/tmp/net-ssh-rdoc"
146
+ rm_rf "/tmp/net-ssh-gh-pages"
147
+ cp_r "./rdoc", "/tmp/net-ssh-rdoc"
148
+ mkdir "/tmp/net-ssh-gh-pages"
149
+ Dir.chdir "/tmp/net-ssh-gh-pages" do
150
+ sh "git clone --branch gh-pages --single-branch https://github.com/net-ssh/net-ssh"
151
+ rm_rf "/tmp/net-ssh-gh-pages/net-ssh/*"
152
+ end
153
+ # update
154
+ sh "cp -rf ./rdoc/* /tmp/net-ssh-gh-pages/net-ssh/"
155
+ Dir.chdir "/tmp/net-ssh-gh-pages/net-ssh" do
156
+ sh "git add -A ."
157
+ sh "git commit -m \"Update docs\""
158
+ end
159
+ # publish
160
+ Dir.chdir "/tmp/net-ssh-gh-pages/net-ssh" do
161
+ sh "git push origin gh-pages"
162
+ end
163
+ end
164
+ end
165
+
166
+ require 'rake/testtask'
167
+
168
+ Rake::TestTask.new do |t|
169
+ t.libs = ["lib", "test"]
170
+ t.libs << "test/integration" if ENV['NET_SSH_RUN_INTEGRATION_TESTS']
171
+ t.libs << "test/win_integration" if ENV['NET_SSH_RUN_WIN_INTEGRATION_TESTS']
172
+ test_files = FileList['test/**/test_*.rb']
173
+ test_files -= FileList['test/integration/**/test_*.rb'] unless ENV['NET_SSH_RUN_INTEGRATION_TESTS']
174
+ test_files -= FileList['test/win_integration/**/test_*.rb'] unless ENV['NET_SSH_RUN_WIN_INTEGRATION_TESTS']
175
+ test_files -= FileList['test/manual/test_*.rb']
176
+ test_files -= FileList['test/test_pageant.rb']
177
+ test_files -= FileList['test/test/**/test_*.rb']
178
+ t.test_files = test_files
179
+ end
180
+
181
+ # We need to enable the OpenSSL 3.0 legacy providers for our test suite
182
+ require 'openssl'
183
+ ENV['OPENSSL_CONF'] = 'test/openssl3.conf' if OpenSSL::OPENSSL_LIBRARY_VERSION.start_with? "OpenSSL 3"
184
+
185
+ desc "Run tests of Net::SSH:Test"
186
+ Rake::TestTask.new do |t|
187
+ t.name = "test_test"
188
+ # we need to run test/test separatedly as it hacks io + other modules
189
+ t.libs = ["lib", "test"]
190
+ test_files = FileList['test/test/**/test_*.rb']
191
+ t.test_files = test_files
192
+ end
@@ -0,0 +1,4 @@
1
+ ## Security contact information
2
+
3
+ To report a security vulnerability, please use the
4
+ [GitHub private vulnerability reporting feature](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability).
@@ -0,0 +1,110 @@
1
+ Net::SSH was originally written by Jamis Buck <jamis@37signals.com>. It
2
+ is currently maintained by Delano Mandelbaum <delano@solutious.com>. In
3
+ addition, the following individuals are gratefully acknowledged for their
4
+ contributions:
5
+
6
+ GOTOU Yuuzou <gotoyuzo@notwork.org>
7
+ * help and code related to OpenSSL
8
+
9
+ Guillaume Marçais <guillaume.marcais@free.fr>
10
+ * support for communicating with the the PuTTY "pageant" process
11
+
12
+ Daniel Berger <djberg96@yahoo.com>
13
+ * help getting unit tests in earlier Net::SSH versions to pass in Windows
14
+ * initial version of Net::SSH::Config provided inspiration and encouragement
15
+
16
+ Chris Andrews <chris@nodnol.org> and Lee Jensen <lee@outerim.com>
17
+ * support for ssh agent forwarding
18
+
19
+ Hiroshi Nakamura
20
+ * fixed errors with JRuby tests
21
+
22
+ bobveznat
23
+ therealjessesanford
24
+ liggitt
25
+ jarredholman
26
+ yugui
27
+ SFEley
28
+ bobtfish
29
+ carlhoerberg
30
+ deric
31
+ mirakui
32
+ ecki
33
+ Dave Sieh
34
+ metametaclass
35
+ fnordfish
36
+ krishicks
37
+ noric
38
+ GabKlein
39
+ Josh Kalderimis
40
+ voxik
41
+ Olipro
42
+ jansegre
43
+ priteau
44
+ jordimassaguerpla
45
+ Kenichi Kamiya
46
+ Andreas Wolff
47
+ mhuffnagle
48
+ ohrite
49
+ iltempo
50
+ nagachika
51
+ Nobuhiro IMAI
52
+ arturaz
53
+ dubspeed
54
+ Andy Brody
55
+ Marco Sandrini
56
+ Ryosuke Yamazaki
57
+ muffl0n
58
+ pcn
59
+ musybite
60
+ Mark Imbriaco
61
+ Joel Watson
62
+ Woon Jung
63
+ Edmund Haselwanter
64
+ robbebob
65
+ Daniel Pittman
66
+ Markus Roberts
67
+ Gavin Brock
68
+ Rich Lane
69
+ Lee Marlow
70
+ xbaldauf
71
+ Delano Mandelbaum
72
+ Miklós Fazekas
73
+ Andy Lo-A-Foe
74
+ Jason Weathered
75
+ Hans de Graaff
76
+ Travis Reeder
77
+ Akinori MUSHA
78
+ Alex Peuchert
79
+ Daniel Azuma
80
+ Will Bryant
81
+ Gerald Talton
82
+ ckoehler
83
+ Karl Varga
84
+ Denis Bernard
85
+ Steven Hazel
86
+ Alex Holems
87
+ Andrew Babkin
88
+ Bob Cotton
89
+ Yanko Ivanov
90
+ Angel N. Sciortino
91
+ arilerner@mac.com
92
+ David Dollar
93
+ Timo Gatsonides
94
+ Matthew Todd
95
+ Brian Candler
96
+ Francis Sullivan
97
+ James Rosen
98
+ Mike Timm
99
+ guns
100
+ devrandom
101
+ kachick
102
+ Pablo Merino
103
+ thedarkone
104
+ czarneckid
105
+ jbarnette
106
+ watsonian
107
+ Grant Hutchins
108
+ Michael Schubert
109
+ mtrudel
110
+ Aurélien Derouineau
@@ -0,0 +1,58 @@
1
+ version: '{build}'
2
+
3
+ skip_tags: true
4
+
5
+ environment:
6
+ matrix:
7
+ - ruby_version: "jruby-9.1.2.0"
8
+ - ruby_version: "26-x64"
9
+ - ruby_version: "25-x64"
10
+ - ruby_version: "24-x64"
11
+ - ruby_version: "23"
12
+ - ruby_version: "23-x64"
13
+
14
+ matrix:
15
+ allow_failures:
16
+ - ruby_version: "jruby-9.1.2.0"
17
+
18
+ #init:
19
+ # - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
20
+
21
+ #on_finish:
22
+ # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
23
+
24
+
25
+ platform:
26
+ - x86
27
+
28
+ install:
29
+ - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
30
+ - if "%ruby_version%" == "jruby-9.1.2.0" ( cinst javaruntime -i )
31
+ - if "%ruby_version%" == "jruby-9.1.2.0" ( cinst jruby --version 9.1.2.0 -i --allow-empty-checksums )
32
+ - if "%ruby_version%" == "jruby-9.1.2.0" ( SET "PATH=C:\jruby-9.1.2.0\bin\;%PATH%" )
33
+ - ruby --version
34
+ - gem install bundler --no-document --user-install -v 1.17
35
+ - SET BUNDLE_GEMFILE=Gemfile.noed25519
36
+ - bundle install --retry=3
37
+ - cinst freesshd
38
+ - cinst putty --allow-empty-checksums
39
+ - ps: |
40
+ if ($env:Processor_Architecture -eq "x86")
41
+ {
42
+ dir 'C:\Program Files\'
43
+ dir 'C:\Program Files\freeSSHd'
44
+ cp 'test\win_integration\FreeSSHDService.ini' 'C:\Program Files\freeSSHd\FreeSSHDService.ini'
45
+ & 'C:\Program Files\freeSSHd\FreeSSHDService.exe'
46
+ } else {
47
+ dir 'C:\Program Files (x86)\'
48
+ dir 'C:\Program Files (x86)\freeSSHd'
49
+ cp 'test\win_integration\FreeSSHDService32.ini' 'C:\Program Files (x86)\freeSSHd\FreeSSHDService.ini'
50
+ & 'C:\Program Files (x86)\freeSSHd\FreeSSHDService.exe'
51
+ }
52
+
53
+ test_script:
54
+ - SET BUNDLE_GEMFILE=Gemfile.noed25519
55
+ - SET NET_SSH_RUN_WIN_INTEGRATION_TESTS=YES
56
+ - bundle exec rake test
57
+
58
+ build: off
@@ -0,0 +1,25 @@
1
+ version: '3'
2
+
3
+ services:
4
+ ruby-3.1:
5
+ build:
6
+ context: .
7
+ args:
8
+ RUBY_VERSION: 3.1
9
+ ruby-3.0:
10
+ build:
11
+ context: .
12
+ args:
13
+ RUBY_VERSION: 3.0
14
+ ruby-2.7:
15
+ build:
16
+ context: .
17
+ args:
18
+ RUBY_VERSION: 2.7
19
+ BUNDLERV: "-v 2.2.28"
20
+ ruby-2.6:
21
+ build:
22
+ context: .
23
+ args:
24
+ RUBY_VERSION: 2.6
25
+ BUNDLERV: "-v 2.4.22"
@@ -0,0 +1,284 @@
1
+ require 'net/ssh/buffer'
2
+ require 'net/ssh/errors'
3
+ require 'net/ssh/loggable'
4
+
5
+ require 'net/ssh/transport/server_version'
6
+ require 'socket'
7
+ require 'rubygems'
8
+
9
+ require 'net/ssh/authentication/pageant' if Gem.win_platform? && RUBY_PLATFORM != "java"
10
+
11
+ module Net
12
+ module SSH
13
+ module Authentication
14
+ # Class for representing agent-specific errors.
15
+ class AgentError < Net::SSH::Exception; end
16
+
17
+ # An exception for indicating that the SSH agent is not available.
18
+ class AgentNotAvailable < AgentError; end
19
+
20
+ # This class implements a simple client for the ssh-agent protocol. It
21
+ # does not implement any specific protocol, but instead copies the
22
+ # behavior of the ssh-agent functions in the OpenSSH library (3.8).
23
+ #
24
+ # This means that although it behaves like a SSH1 client, it also has
25
+ # some SSH2 functionality (like signing data).
26
+ class Agent
27
+ include Loggable
28
+
29
+ # A simple module for extending keys, to allow comments to be specified
30
+ # for them.
31
+ module Comment
32
+ attr_accessor :comment
33
+ end
34
+
35
+ SSH2_AGENT_REQUEST_VERSION = 1
36
+ SSH2_AGENT_REQUEST_IDENTITIES = 11
37
+ SSH2_AGENT_IDENTITIES_ANSWER = 12
38
+ SSH2_AGENT_SIGN_REQUEST = 13
39
+ SSH2_AGENT_SIGN_RESPONSE = 14
40
+ SSH2_AGENT_ADD_IDENTITY = 17
41
+ SSH2_AGENT_REMOVE_IDENTITY = 18
42
+ SSH2_AGENT_REMOVE_ALL_IDENTITIES = 19
43
+ SSH2_AGENT_LOCK = 22
44
+ SSH2_AGENT_UNLOCK = 23
45
+ SSH2_AGENT_ADD_ID_CONSTRAINED = 25
46
+ SSH2_AGENT_FAILURE = 30
47
+ SSH2_AGENT_VERSION_RESPONSE = 103
48
+
49
+ SSH_COM_AGENT2_FAILURE = 102
50
+
51
+ SSH_AGENT_REQUEST_RSA_IDENTITIES = 1
52
+ SSH_AGENT_RSA_IDENTITIES_ANSWER1 = 2
53
+ SSH_AGENT_RSA_IDENTITIES_ANSWER2 = 5
54
+ SSH_AGENT_FAILURE = 5
55
+ SSH_AGENT_SUCCESS = 6
56
+
57
+ SSH_AGENT_CONSTRAIN_LIFETIME = 1
58
+ SSH_AGENT_CONSTRAIN_CONFIRM = 2
59
+
60
+ SSH_AGENT_RSA_SHA2_256 = 0x02
61
+ SSH_AGENT_RSA_SHA2_512 = 0x04
62
+
63
+ # The underlying socket being used to communicate with the SSH agent.
64
+ attr_reader :socket
65
+
66
+ # Instantiates a new agent object, connects to a running SSH agent,
67
+ # negotiates the agent protocol version, and returns the agent object.
68
+ def self.connect(logger = nil, agent_socket_factory = nil, identity_agent = nil)
69
+ agent = new(logger)
70
+ agent.connect!(agent_socket_factory, identity_agent)
71
+ agent.negotiate!
72
+ agent
73
+ end
74
+
75
+ # Creates a new Agent object, using the optional logger instance to
76
+ # report status.
77
+ def initialize(logger = nil)
78
+ self.logger = logger
79
+ end
80
+
81
+ # Connect to the agent process using the socket factory and socket name
82
+ # given by the attribute writers. If the agent on the other end of the
83
+ # socket reports that it is an SSH2-compatible agent, this will fail
84
+ # (it only supports the ssh-agent distributed by OpenSSH).
85
+ def connect!(agent_socket_factory = nil, identity_agent = nil)
86
+ debug { "connecting to ssh-agent" }
87
+ @socket =
88
+ if agent_socket_factory
89
+ agent_socket_factory.call
90
+ elsif identity_agent
91
+ unix_socket_class.open(File.expand_path(identity_agent))
92
+ elsif ENV['SSH_AUTH_SOCK'] && unix_socket_class
93
+ unix_socket_class.open(File.expand_path(ENV['SSH_AUTH_SOCK']))
94
+ elsif Gem.win_platform? && RUBY_ENGINE != "jruby"
95
+ Pageant::Socket.open
96
+ else
97
+ raise AgentNotAvailable, "Agent not configured"
98
+ end
99
+ rescue StandardError => e
100
+ error { "could not connect to ssh-agent: #{e.message}" }
101
+ raise AgentNotAvailable, $!.message
102
+ end
103
+
104
+ # Attempts to negotiate the SSH agent protocol version. Raises an error
105
+ # if the version could not be negotiated successfully.
106
+ def negotiate!
107
+ # determine what type of agent we're communicating with
108
+ type, body = send_and_wait(SSH2_AGENT_REQUEST_VERSION, :string, Transport::ServerVersion::PROTO_VERSION)
109
+
110
+ raise AgentNotAvailable, "SSH2 agents are not yet supported" if type == SSH2_AGENT_VERSION_RESPONSE
111
+
112
+ if type == SSH2_AGENT_FAILURE
113
+ debug { "Unexpected response type==#{type}, this will be ignored" }
114
+ elsif type != SSH_AGENT_RSA_IDENTITIES_ANSWER1 && type != SSH_AGENT_RSA_IDENTITIES_ANSWER2
115
+ raise AgentNotAvailable, "unknown response from agent: #{type}, #{body.to_s.inspect}"
116
+ end
117
+ end
118
+
119
+ # Return an array of all identities (public keys) known to the agent.
120
+ # Each key returned is augmented with a +comment+ property which is set
121
+ # to the comment returned by the agent for that key.
122
+ def identities
123
+ type, body = send_and_wait(SSH2_AGENT_REQUEST_IDENTITIES)
124
+ raise AgentError, "could not get identity count" if agent_failed(type)
125
+ raise AgentError, "bad authentication reply: #{type}" if type != SSH2_AGENT_IDENTITIES_ANSWER
126
+
127
+ identities = []
128
+ body.read_long.times do
129
+ key_str = body.read_string
130
+ comment_str = body.read_string
131
+ begin
132
+ key = Buffer.new(key_str).read_key
133
+ if key.nil?
134
+ error { "ignoring invalid key: #{comment_str}" }
135
+ next
136
+ end
137
+ key.extend(Comment)
138
+ key.comment = comment_str
139
+ identities.push key
140
+ rescue NotImplementedError => e
141
+ error { "ignoring unimplemented key:#{e.message} #{comment_str}" }
142
+ end
143
+ end
144
+
145
+ return identities
146
+ end
147
+
148
+ # Closes this socket. This agent reference is no longer able to
149
+ # query the agent.
150
+ def close
151
+ @socket.close
152
+ end
153
+
154
+ # Using the agent and the given public key, sign the given data. The
155
+ # signature is returned in SSH2 format.
156
+ def sign(key, data, flags = 0)
157
+ type, reply = send_and_wait(SSH2_AGENT_SIGN_REQUEST, :string, Buffer.from(:key, key), :string, data, :long, flags)
158
+
159
+ raise AgentError, "agent could not sign data with requested identity" if agent_failed(type)
160
+ raise AgentError, "bad authentication response #{type}" if type != SSH2_AGENT_SIGN_RESPONSE
161
+
162
+ return reply.read_string
163
+ end
164
+
165
+ # Adds the private key with comment to the agent.
166
+ # If lifetime is given, the key will automatically be removed after lifetime
167
+ # seconds.
168
+ # If confirm is true, confirmation will be required for each agent signing
169
+ # operation.
170
+ def add_identity(priv_key, comment, lifetime: nil, confirm: false)
171
+ constraints = Buffer.new
172
+ if lifetime
173
+ constraints.write_byte(SSH_AGENT_CONSTRAIN_LIFETIME)
174
+ constraints.write_long(lifetime)
175
+ end
176
+ constraints.write_byte(SSH_AGENT_CONSTRAIN_CONFIRM) if confirm
177
+
178
+ req_type = constraints.empty? ? SSH2_AGENT_ADD_IDENTITY : SSH2_AGENT_ADD_ID_CONSTRAINED
179
+ type, = send_and_wait(req_type, :string, priv_key.ssh_type, :raw, blob_for_add(priv_key),
180
+ :string, comment, :raw, constraints)
181
+ raise AgentError, "could not add identity to agent" if type != SSH_AGENT_SUCCESS
182
+ end
183
+
184
+ # Removes key from the agent.
185
+ def remove_identity(key)
186
+ type, = send_and_wait(SSH2_AGENT_REMOVE_IDENTITY, :string, key.to_blob)
187
+ raise AgentError, "could not remove identity from agent" if type != SSH_AGENT_SUCCESS
188
+ end
189
+
190
+ # Removes all identities from the agent.
191
+ def remove_all_identities
192
+ type, = send_and_wait(SSH2_AGENT_REMOVE_ALL_IDENTITIES)
193
+ raise AgentError, "could not remove all identity from agent" if type != SSH_AGENT_SUCCESS
194
+ end
195
+
196
+ # lock the ssh agent with password
197
+ def lock(password)
198
+ type, = send_and_wait(SSH2_AGENT_LOCK, :string, password)
199
+ raise AgentError, "could not lock agent" if type != SSH_AGENT_SUCCESS
200
+ end
201
+
202
+ # unlock the ssh agent with password
203
+ def unlock(password)
204
+ type, = send_and_wait(SSH2_AGENT_UNLOCK, :string, password)
205
+ raise AgentError, "could not unlock agent" if type != SSH_AGENT_SUCCESS
206
+ end
207
+
208
+ private
209
+
210
+ def unix_socket_class
211
+ defined?(UNIXSocket) && UNIXSocket
212
+ end
213
+
214
+ # Send a new packet of the given type, with the associated data.
215
+ def send_packet(type, *args)
216
+ buffer = Buffer.from(*args)
217
+ data = [buffer.length + 1, type.to_i, buffer.to_s].pack("NCA*")
218
+ debug { "sending agent request #{type} len #{buffer.length}" }
219
+ @socket.send data, 0
220
+ end
221
+
222
+ # Read the next packet from the agent. This will return a two-part
223
+ # tuple consisting of the packet type, and the packet's body (which
224
+ # is returned as a Net::SSH::Buffer).
225
+ def read_packet
226
+ buffer = Net::SSH::Buffer.new(@socket.read(4))
227
+ buffer.append(@socket.read(buffer.read_long))
228
+ type = buffer.read_byte
229
+ debug { "received agent packet #{type} len #{buffer.length - 4}" }
230
+ return type, buffer
231
+ end
232
+
233
+ # Send the given packet and return the subsequent reply from the agent.
234
+ # (See #send_packet and #read_packet).
235
+ def send_and_wait(type, *args)
236
+ send_packet(type, *args)
237
+ read_packet
238
+ end
239
+
240
+ # Returns +true+ if the parameter indicates a "failure" response from
241
+ # the agent, and +false+ otherwise.
242
+ def agent_failed(type)
243
+ type == SSH_AGENT_FAILURE ||
244
+ type == SSH2_AGENT_FAILURE ||
245
+ type == SSH_COM_AGENT2_FAILURE
246
+ end
247
+
248
+ def blob_for_add(priv_key)
249
+ # Ideally we'd have something like `to_private_blob` on the various key types, but the
250
+ # nuances with encoding (e.g. `n` and `e` are reversed for RSA keys) make this impractical.
251
+ case priv_key.ssh_type
252
+ when /^ssh-dss$/
253
+ Net::SSH::Buffer.from(:bignum, priv_key.p, :bignum, priv_key.q, :bignum, priv_key.g,
254
+ :bignum, priv_key.pub_key, :bignum, priv_key.priv_key).to_s
255
+ when /^ssh-dss-cert-v01@openssh\.com$/
256
+ Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.priv_key).to_s
257
+ when /^ecdsa\-sha2\-(\w*)$/
258
+ curve_name = OpenSSL::PKey::EC::CurveNameAliasInv[priv_key.group.curve_name]
259
+ Net::SSH::Buffer.from(:string, curve_name, :mstring, priv_key.public_key.to_bn.to_s(2),
260
+ :bignum, priv_key.private_key).to_s
261
+ when /^ecdsa\-sha2\-(\w*)-cert-v01@openssh\.com$/
262
+ Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.private_key).to_s
263
+ when /^ssh-ed25519$/
264
+ Net::SSH::Buffer.from(:string, priv_key.public_key.verify_key.to_bytes,
265
+ :string, priv_key.sign_key.keypair).to_s
266
+ when /^ssh-ed25519-cert-v01@openssh\.com$/
267
+ # Unlike the other certificate types, the public key is included after the certifiate.
268
+ Net::SSH::Buffer.from(:string, priv_key.to_blob,
269
+ :string, priv_key.key.public_key.verify_key.to_bytes,
270
+ :string, priv_key.key.sign_key.keypair).to_s
271
+ when /^ssh-rsa$/
272
+ # `n` and `e` are reversed compared to the ordering in `OpenSSL::PKey::RSA#to_blob`.
273
+ Net::SSH::Buffer.from(:bignum, priv_key.n, :bignum, priv_key.e, :bignum, priv_key.d,
274
+ :bignum, priv_key.iqmp, :bignum, priv_key.p, :bignum, priv_key.q).to_s
275
+ when /^ssh-rsa-cert-v01@openssh\.com$/
276
+ Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.d,
277
+ :bignum, priv_key.key.iqmp, :bignum, priv_key.key.p,
278
+ :bignum, priv_key.key.q).to_s
279
+ end
280
+ end
281
+ end
282
+ end
283
+ end
284
+ end