| 1 |
begin |
|---|
| 2 |
require 'rubygems' |
|---|
| 3 |
gem 'net-ssh', "< 1.99.0" |
|---|
| 4 |
rescue LoadError, NameError |
|---|
| 5 |
end |
|---|
| 6 |
|
|---|
| 7 |
require 'net/ssh' |
|---|
| 8 |
|
|---|
| 9 |
module Capistrano |
|---|
| 10 |
unless ENV['SKIP_VERSION_CHECK'] |
|---|
| 11 |
require 'capistrano/version' |
|---|
| 12 |
require 'net/ssh/version' |
|---|
| 13 |
ssh_version = [Net::SSH::Version::MAJOR, Net::SSH::Version::MINOR, Net::SSH::Version::TINY] |
|---|
| 14 |
if !Version.check(Version::SSH_REQUIRED, ssh_version) |
|---|
| 15 |
raise "You have Net::SSH #{ssh_version.join(".")}, but you need at least #{Version::SSH_REQUIRED.join(".")}" |
|---|
| 16 |
end |
|---|
| 17 |
end |
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
net_ssh_dependencies = %w(connection/services connection/channel connection/driver |
|---|
| 25 |
service/agentforward/services service/agentforward/driver |
|---|
| 26 |
service/process/driver util/prompter |
|---|
| 27 |
service/forward/services service/forward/driver service/forward/local-network-handler service/forward/remote-network-handler |
|---|
| 28 |
service/shell/services service/shell/driver |
|---|
| 29 |
lenient-host-key-verifier |
|---|
| 30 |
transport/compress/services transport/compress/zlib-compressor transport/compress/none-compressor transport/compress/zlib-decompressor transport/compress/none-decompressor |
|---|
| 31 |
transport/kex/services transport/kex/dh transport/kex/dh-gex |
|---|
| 32 |
transport/ossl/services |
|---|
| 33 |
transport/ossl/hmac/services transport/ossl/hmac/sha1 transport/ossl/hmac/sha1-96 transport/ossl/hmac/md5 transport/ossl/hmac/md5-96 transport/ossl/hmac/none |
|---|
| 34 |
transport/ossl/cipher-factory transport/ossl/hmac-factory transport/ossl/buffer-factory transport/ossl/key-factory transport/ossl/digest-factory |
|---|
| 35 |
transport/identity-cipher transport/packet-stream transport/version-negotiator transport/algorithm-negotiator transport/session |
|---|
| 36 |
userauth/methods/services userauth/methods/password userauth/methods/keyboard-interactive userauth/methods/publickey userauth/methods/hostbased |
|---|
| 37 |
userauth/services userauth/agent userauth/userkeys userauth/driver |
|---|
| 38 |
transport/services service/services |
|---|
| 39 |
) |
|---|
| 40 |
|
|---|
| 41 |
net_ssh_dependencies << "userauth/pageant" if File::ALT_SEPARATOR |
|---|
| 42 |
net_ssh_dependencies.each do |path| |
|---|
| 43 |
begin |
|---|
| 44 |
require "net/ssh/#{path}" |
|---|
| 45 |
rescue LoadError |
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
|
|---|
| 49 |
|
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 |
|
|---|
| 53 |
|
|---|
| 54 |
|
|---|
| 55 |
|
|---|
| 56 |
end |
|---|
| 57 |
end |
|---|
| 58 |
|
|---|
| 59 |
|
|---|
| 60 |
class SSH |
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 |
|
|---|
| 64 |
|
|---|
| 65 |
module Server |
|---|
| 66 |
def self.apply_to(connection, server) |
|---|
| 67 |
connection.extend(Server) |
|---|
| 68 |
connection.xserver = server |
|---|
| 69 |
connection |
|---|
| 70 |
end |
|---|
| 71 |
|
|---|
| 72 |
attr_accessor :xserver |
|---|
| 73 |
end |
|---|
| 74 |
|
|---|
| 75 |
|
|---|
| 76 |
DEFAULT_PORT = 22 |
|---|
| 77 |
|
|---|
| 78 |
|
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 |
|
|---|
| 84 |
|
|---|
| 85 |
|
|---|
| 86 |
|
|---|
| 87 |
|
|---|
| 88 |
|
|---|
| 89 |
|
|---|
| 90 |
|
|---|
| 91 |
def self.connect(server, options={}, &block) |
|---|
| 92 |
methods = [ %w(publickey hostbased), %w(password keyboard-interactive) ] |
|---|
| 93 |
password_value = nil |
|---|
| 94 |
|
|---|
| 95 |
ssh_options = (options[:ssh_options] || {}).dup |
|---|
| 96 |
ssh_options[:username] = server.user || options[:user] || ssh_options[:username] |
|---|
| 97 |
ssh_options[:port] = server.port || options[:port] || ssh_options[:port] || DEFAULT_PORT |
|---|
| 98 |
|
|---|
| 99 |
begin |
|---|
| 100 |
connection_options = ssh_options.merge( |
|---|
| 101 |
:password => password_value, |
|---|
| 102 |
:auth_methods => ssh_options[:auth_methods] || methods.shift |
|---|
| 103 |
) |
|---|
| 104 |
|
|---|
| 105 |
connection = Net::SSH.start(server.host, connection_options, &block) |
|---|
| 106 |
Server.apply_to(connection, server) |
|---|
| 107 |
|
|---|
| 108 |
rescue Net::SSH::AuthenticationFailed |
|---|
| 109 |
raise if methods.empty? || ssh_options[:auth_methods] |
|---|
| 110 |
password_value = options[:password] |
|---|
| 111 |
retry |
|---|
| 112 |
end |
|---|
| 113 |
end |
|---|
| 114 |
end |
|---|
| 115 |
end |
|---|