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.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/exe/harbr +225 -150
- data/lib/examples/container.toml +13 -0
- data/lib/harbr/container.rb +14 -10
- data/lib/harbr/host.rb +21 -0
- data/lib/harbr/version.rb +1 -1
- data/lib/harbr.rb +21 -6
- data/vendor/bundle/ruby/3.2.0/cache/dddr-1.0.8.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/dddr-1.1.0.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/dddr-1.1.1.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/net-ssh-7.2.1.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/.DS_Store +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/.rspec +3 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/.standard.yml +3 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/CHANGELOG.md +5 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/CODE_OF_CONDUCT.md +84 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/LICENSE.txt +21 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/README.md +96 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/Rakefile +10 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/hero.png +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/lib/dddr/version.rb +5 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/lib/dddr.rb +205 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.0.8/sig/dddr.rbs +4 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/.DS_Store +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/.rspec +3 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/.standard.yml +3 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/CHANGELOG.md +5 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/CODE_OF_CONDUCT.md +84 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/LICENSE.txt +21 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/README.md +96 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/Rakefile +10 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/hero.png +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/lib/dddr/version.rb +5 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/lib/dddr.rb +182 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.0/sig/dddr.rbs +4 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/.DS_Store +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/.rspec +3 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/.standard.yml +3 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/CHANGELOG.md +5 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/CODE_OF_CONDUCT.md +84 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/LICENSE.txt +21 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/README.md +96 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/Rakefile +10 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/hero.png +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/lib/dddr/version.rb +5 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/lib/dddr.rb +184 -0
- data/vendor/bundle/ruby/3.2.0/gems/dddr-1.1.1/sig/dddr.rbs +4 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.dockerignore +6 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.github/FUNDING.yml +1 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.github/config/rubocop_linter_action.yml +4 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.github/workflows/ci-with-docker.yml +44 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.github/workflows/ci.yml +94 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.github/workflows/rubocop.yml +16 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.gitignore +15 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.rubocop.yml +22 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/.rubocop_todo.yml +1081 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/CHANGES.txt +738 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/DEVELOPMENT.md +23 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Dockerfile +29 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Dockerfile.openssl3 +17 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Gemfile +13 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Gemfile.noed25519 +12 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Gemfile.norbnacl +12 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/ISSUE_TEMPLATE.md +30 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/LICENSE.txt +19 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Manifest +132 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/README.md +298 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/Rakefile +192 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/SECURITY.md +4 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/THANKS.txt +110 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/appveyor.yml +58 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/docker-compose.yml +25 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/agent.rb +284 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/certificate.rb +183 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/constants.rb +20 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/ed25519.rb +186 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/key_manager.rb +327 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/abstract.rb +79 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/hostbased.rb +72 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/keyboard_interactive.rb +77 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/none.rb +34 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/password.rb +80 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/methods/publickey.rb +137 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/pageant.rb +497 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/authentication/session.rb +172 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/buffer.rb +449 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/buffered_io.rb +202 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/config.rb +406 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/channel.rb +694 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/constants.rb +33 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/event_loop.rb +123 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/keepalive.rb +59 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/session.rb +712 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/connection/term.rb +180 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/errors.rb +106 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/key_factory.rb +218 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/known_hosts.rb +265 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/loggable.rb +62 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/packet.rb +106 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/prompt.rb +62 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/command.rb +123 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/errors.rb +16 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/http.rb +98 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/https.rb +50 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/jump.rb +54 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/socks4.rb +67 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/proxy/socks5.rb +140 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/service/forward.rb +426 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/channel.rb +147 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/extensions.rb +173 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/kex.rb +46 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/local_packet.rb +53 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/packet.rb +101 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/remote_packet.rb +40 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/script.rb +180 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test/socket.rb +65 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/test.rb +94 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/algorithms.rb +524 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/cipher_factory.rb +128 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/constants.rb +40 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/ctr.rb +115 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/abstract.rb +97 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/md5.rb +10 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/md5_96.rb +9 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/none.rb +13 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/ripemd160.rb +11 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha1.rb +11 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha1_96.rb +9 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_256.rb +11 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_256_96.rb +9 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_512.rb +11 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_512_96.rb +9 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/hmac.rb +47 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/identity_cipher.rb +65 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/abstract.rb +130 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
- 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
- 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
- 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
- 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
- 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
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +39 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +21 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +21 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/kex.rb +31 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/key_expander.rb +30 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/openssl.rb +274 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/packet_stream.rb +301 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/server_version.rb +77 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/session.rb +354 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/transport/state.rb +208 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/verifiers/accept_new.rb +33 -0
- 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
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/verifiers/always.rb +58 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/verifiers/never.rb +19 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh/version.rb +68 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/lib/net/ssh.rb +338 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/net-ssh-public_cert.pem +20 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/net-ssh.gemspec +46 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-ssh-7.2.1/support/ssh_tunnel_bug.rb +65 -0
- data/vendor/bundle/ruby/3.2.0/specifications/dddr-1.0.8.gemspec +27 -0
- data/vendor/bundle/ruby/3.2.0/specifications/dddr-1.1.0.gemspec +27 -0
- data/vendor/bundle/ruby/3.2.0/specifications/dddr-1.1.1.gemspec +27 -0
- data/vendor/bundle/ruby/3.2.0/specifications/net-ssh-7.2.1.gemspec +38 -0
- metadata +174 -9
- data/config/manifest.yml +0 -5
- data/lib/harbr/job.rb +0 -252
- data/lib/harbr/lxd/job.rb +0 -119
- 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
|