net-ssh 4.0.0.beta3 → 4.0.0.beta4
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +2 -1
- data/CHANGES.txt +9 -0
- data/Gemfile +9 -1
- data/Gemfile.norbnacl +6 -1
- data/Gemfile.norbnacl.lock +4 -3
- data/ISSUE_TEMPLATE.md +30 -0
- data/README.rdoc +5 -1
- data/Rakefile +4 -0
- data/appveyor.yml +36 -5
- data/lib/net/ssh.rb +5 -5
- data/lib/net/ssh/authentication/agent.rb +174 -14
- data/lib/net/ssh/authentication/key_manager.rb +1 -1
- data/lib/net/ssh/authentication/pageant.rb +116 -19
- data/lib/net/ssh/buffered_io.rb +17 -12
- data/lib/net/ssh/connection/session.rb +29 -7
- data/lib/net/ssh/key_factory.rb +7 -7
- data/lib/net/ssh/proxy/http.rb +7 -4
- data/lib/net/ssh/proxy/https.rb +49 -0
- data/lib/net/ssh/test.rb +2 -2
- data/lib/net/ssh/test/extensions.rb +17 -0
- data/lib/net/ssh/transport/ctr.rb +7 -9
- data/lib/net/ssh/version.rb +2 -2
- data/net-ssh.gemspec +3 -4
- metadata +8 -21
- metadata.gz.sig +0 -0
- data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
- data/lib/net/ssh/authentication/agent/socket.rb +0 -178
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5651b877a83649b20a9c8643125f5bd30bd982b3
|
4
|
+
data.tar.gz: 46d37efc38505e66f1049894b15cdb214e3016b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b657629b5e8cb5ced31e567d7a6353679683fa4a2024fdb41460fce8314c15b928f7b5b5101b6e4dc1565c1462780cdabc7716a9a2388eceae4ddeaab60cbe3
|
7
|
+
data.tar.gz: 55783d5ebe87f2bb7561f689e4bba5d4fcf22bea6f4661c2aea410fd2d3fcfb2e1f62175db46997f9406182b5e6dc4f8c68ffccd9ed9037ad884b190da6dea74
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.travis.yml
CHANGED
@@ -26,6 +26,7 @@ matrix:
|
|
26
26
|
allow_failures:
|
27
27
|
- rvm: rbx-3.25
|
28
28
|
- rvm: jruby-9.1.2.0
|
29
|
+
- rvm: ruby-head
|
29
30
|
|
30
31
|
install:
|
31
32
|
- export JRUBY_OPTS='--client -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -Xcext.enabled=false -J-Xss2m -Xcompile.invokedynamic=false'
|
@@ -33,7 +34,7 @@ install:
|
|
33
34
|
- gem install bundler -v "= 1.11.2"
|
34
35
|
- bundle _1.11.2_ install
|
35
36
|
- BUNDLE_GEMFILE=./Gemfile.norbnacl bundle _1.11.2_ install
|
36
|
-
- sudo ansible-galaxy install rvm_io.
|
37
|
+
- sudo ansible-galaxy install rvm_io.ruby
|
37
38
|
- sudo chown -R travis:travis /home/travis/.ansible
|
38
39
|
- ansible-playbook ./test/integration/playbook.yml -i "localhost," --become -c local -e 'no_rvm=true' -e 'myuser=travis' -e 'mygroup=travis' -e 'homedir=/home/travis'
|
39
40
|
|
data/CHANGES.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
=== 4.0.0.beta4
|
2
|
+
|
3
|
+
* Added exitstatus method to exec's return [Miklós Fazekas, #452]
|
4
|
+
* Don't raise from exec if server closes transport just after channel close [Miklós Fazekas, #450]
|
5
|
+
* Removed java_pageant, as jruby should be using regular pagent impl [Miklós Fazekas, ]
|
6
|
+
* Use SSH_AUTH_SOCK if possible on windows (cygwin) [Miklós Fazekas, Martin Dürst, #365, #361]
|
7
|
+
* HTTPS proxy support [Marcus Ilgner, #432]
|
8
|
+
* Supports ruby 2.4.0.dev new exception type from OpenSSL::PKey.read
|
9
|
+
|
1
10
|
=== 4.0.0.beta3
|
2
11
|
|
3
12
|
* Fix Net::SSH::Disconnect exceptions when channels are closed cleanly [Miklos Fazekas, #421, #422]
|
data/Gemfile
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in mygem.gemspec
|
4
|
-
gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
unless Gem.win_platform? || RUBY_PLATFORM == "java"
|
7
|
+
gem 'byebug', group: [:development, :test]
|
8
|
+
end
|
9
|
+
|
10
|
+
gem 'simplecov', require: false, group: :test
|
11
|
+
|
12
|
+
gem 'codecov', require: false, group: :test if ENV["CI"]
|
data/Gemfile.norbnacl
CHANGED
@@ -2,4 +2,9 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
ENV['NET_SSH_NO_RBNACL'] = 'true'
|
4
4
|
# Specify your gem's dependencies in mygem.gemspec
|
5
|
-
gemspec
|
5
|
+
gemspec
|
6
|
+
|
7
|
+
unless Gem.win_platform?
|
8
|
+
gem 'simplecov', require: false, group: :test
|
9
|
+
gem 'codecov', require: false, group: :test if ENV["CI"]
|
10
|
+
end
|
data/Gemfile.norbnacl.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
net-ssh (4.0.0.
|
4
|
+
net-ssh (4.0.0.beta3)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -27,9 +27,10 @@ GEM
|
|
27
27
|
|
28
28
|
PLATFORMS
|
29
29
|
ruby
|
30
|
+
x86-mingw32
|
30
31
|
|
31
32
|
DEPENDENCIES
|
32
|
-
bundler (~> 1.11
|
33
|
+
bundler (~> 1.11)
|
33
34
|
minitest (~> 5.0)
|
34
35
|
mocha (>= 1.1.0)
|
35
36
|
net-ssh!
|
@@ -37,4 +38,4 @@ DEPENDENCIES
|
|
37
38
|
rubocop (~> 0.39.0)
|
38
39
|
|
39
40
|
BUNDLED WITH
|
40
|
-
1.
|
41
|
+
1.13.5
|
data/ISSUE_TEMPLATE.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
### Expected behavior
|
2
|
+
|
3
|
+
Tell us what should happen
|
4
|
+
|
5
|
+
### Actual behavior
|
6
|
+
|
7
|
+
Tell us what happens instead.
|
8
|
+
|
9
|
+
### System configuration
|
10
|
+
|
11
|
+
- net-ssh version
|
12
|
+
- Ruby version
|
13
|
+
|
14
|
+
### Example App
|
15
|
+
|
16
|
+
Please provide an example script that reproduces the problem. This will save maintainers time so they can spend it fixing your issues instead of trying to build a reproduction case from sparse instructions.
|
17
|
+
|
18
|
+
You can use this as stating point:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'net-ssh', '= 4.0.0.beta3'
|
22
|
+
require 'net/ssh'
|
23
|
+
puts Net::SSH::Version::CURRENT
|
24
|
+
|
25
|
+
@host = 'localhost'
|
26
|
+
@user = ENV['USER']
|
27
|
+
Net::SSH.start(@host, @user) do |ssh|
|
28
|
+
puts ssh.exec!('echo "hello"')
|
29
|
+
end
|
30
|
+
```
|
data/README.rdoc
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
{<img src="https://badge.fury.io/rb/net-ssh.svg" alt="Gem Version" />}[https://badge.fury.io/rb/net-ssh]
|
2
|
+
{<img src="https://badges.gitter.im/net-ssh/net-ssh.svg" alt="Join the chat at https://gitter.im/net-ssh/net-ssh">}[https://gitter.im/net-ssh/net-ssh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge]
|
3
|
+
{<img src="https://travis-ci.org/net-ssh/net-ssh.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/net-ssh/net-ssh]
|
4
|
+
|
1
5
|
= Net::SSH 4.x
|
2
6
|
|
3
7
|
* Docs: http://net-ssh.github.com/net-ssh
|
@@ -105,7 +109,7 @@ If you don't add the public key, you'll see an error like "Couldn't verify data
|
|
105
109
|
|
106
110
|
* Ruby 1.8.x is supported up until the net-ssh 2.5.1 release.
|
107
111
|
* Ruby 1.9.x is supported up until the net-ssh 2.9.x release.
|
108
|
-
* Current net-ssh releases require Ruby 2.0 or later.
|
112
|
+
* Current net-ssh releases require Ruby 2.0 or later. JRuby 1.7+ (with `compat.version=2.0` set) or JRuby 9k+
|
109
113
|
|
110
114
|
== RUNNING TESTS
|
111
115
|
|
data/Rakefile
CHANGED
@@ -73,8 +73,12 @@ require 'rake/testtask'
|
|
73
73
|
Rake::TestTask.new do |t|
|
74
74
|
t.libs = ["lib", "test"]
|
75
75
|
t.libs << "test/integration" if ENV['NET_SSH_RUN_INTEGRATION_TESTS']
|
76
|
+
t.libs << "test/win_integration" if ENV['NET_SSH_RUN_WIN_INTEGRATION_TESTS']
|
76
77
|
test_files = FileList['test/**/test_*.rb']
|
77
78
|
test_files -= FileList['test/integration/**/test_*.rb'] unless ENV['NET_SSH_RUN_INTEGRATION_TESTS']
|
79
|
+
test_files -= FileList['test/win_integration/**/test_*.rb'] unless ENV['NET_SSH_RUN_WIN_INTEGRATION_TESTS']
|
80
|
+
test_files -= FileList['test/manual/test_*.rb']
|
81
|
+
test_files -= FileList['test/test_pageant.rb']
|
78
82
|
test_files -= FileList['test/test/**/test_*.rb']
|
79
83
|
t.test_files = test_files
|
80
84
|
end
|
data/appveyor.yml
CHANGED
@@ -4,17 +4,48 @@ skip_tags: true
|
|
4
4
|
|
5
5
|
environment:
|
6
6
|
matrix:
|
7
|
-
- ruby_version: "
|
8
|
-
- ruby_version: "
|
7
|
+
- ruby_version: "jruby-9.1.2.0"
|
8
|
+
- ruby_version: "23"
|
9
|
+
- ruby_version: "23-x64"
|
10
|
+
|
11
|
+
#init:
|
12
|
+
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
13
|
+
|
14
|
+
#on_finish:
|
15
|
+
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
16
|
+
|
17
|
+
|
18
|
+
platform:
|
19
|
+
- x86
|
9
20
|
|
10
21
|
install:
|
11
22
|
- SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
|
12
|
-
-
|
23
|
+
- if "%ruby_version%" == "jruby-9.1.2.0" ( cinst javaruntime -i )
|
24
|
+
- if "%ruby_version%" == "jruby-9.1.2.0" ( cinst jruby --version 9.1.2.0 -i )
|
25
|
+
- if "%ruby_version%" == "jruby-9.1.2.0" ( SET "PATH=C:\jruby-9.1.2.0\bin\;%PATH%" )
|
26
|
+
- ruby --version
|
27
|
+
- gem install bundler --no-document -v 1.13.5
|
13
28
|
- SET BUNDLE_GEMFILE=Gemfile.norbnacl
|
14
|
-
- bundle _1.
|
29
|
+
- bundle _1.13.5_ install --retry=3
|
30
|
+
- cinst freesshd
|
31
|
+
- cinst putty
|
32
|
+
- ps: |
|
33
|
+
if ($env:Processor_Architecture -eq "x86")
|
34
|
+
{
|
35
|
+
dir 'C:\Program Files\'
|
36
|
+
dir 'C:\Program Files\freeSSHd'
|
37
|
+
cp 'test\win_integration\FreeSSHDService.ini' 'C:\Program Files\freeSSHd\FreeSSHDService.ini'
|
38
|
+
& 'C:\Program Files\freeSSHd\FreeSSHDService.exe'
|
39
|
+
} else {
|
40
|
+
dir 'C:\Program Files (x86)\'
|
41
|
+
dir 'C:\Program Files (x86)\freeSSHd'
|
42
|
+
cp 'test\win_integration\FreeSSHDService32.ini' 'C:\Program Files (x86)\freeSSHd\FreeSSHDService.ini'
|
43
|
+
& 'C:\Program Files (x86)\freeSSHd\FreeSSHDService.exe'
|
44
|
+
}
|
15
45
|
|
16
46
|
test_script:
|
17
47
|
- SET BUNDLE_GEMFILE=Gemfile.norbnacl
|
18
|
-
-
|
48
|
+
- SET NET_SSH_RUN_WIN_INTEGRATION_TESTS=YES
|
49
|
+
- bundle _1.13.5_ exec rake test
|
19
50
|
|
20
51
|
build: off
|
data/lib/net/ssh.rb
CHANGED
@@ -153,6 +153,10 @@ module Net
|
|
153
153
|
# for better performance if your SSH server supports it (most do).
|
154
154
|
# * :max_win_size => maximum size we tell the other side that is supported for
|
155
155
|
# the window.
|
156
|
+
# * :non_interactive => set to true if your app is non interactive and prefers
|
157
|
+
# authentication failure vs password prompt. Non-interactive applications
|
158
|
+
# should set it to true to prefer failing a password/etc auth methods vs.
|
159
|
+
# asking for password.
|
156
160
|
# * :paranoid => either false, true, :very, or :secure specifying how
|
157
161
|
# strict host-key verification should be (in increasing order here).
|
158
162
|
# You can also provide an own Object which responds to +verify+. The argument
|
@@ -181,8 +185,6 @@ module Net
|
|
181
185
|
# Defaults to %w(~/.ssh/known_hosts ~/.ssh/known_hosts2).
|
182
186
|
# * :use_agent => Set false to disable the use of ssh-agent. Defaults to
|
183
187
|
# true
|
184
|
-
# * :non_interactive => set to true if your app is non interactive and prefers
|
185
|
-
# authentication failure vs password prompt
|
186
188
|
# * :verbose => how verbose to be (Logger verbosity constants, Logger::DEBUG
|
187
189
|
# is very verbose, Logger::FATAL is all but silent). Logger::FATAL is the
|
188
190
|
# default. The symbols :debug, :info, :warn, :error, and :fatal are also
|
@@ -192,8 +194,6 @@ module Net
|
|
192
194
|
# * :number_of_password_prompts => Number of prompts for the password
|
193
195
|
# authentication method defaults to 3 set to 0 to disable prompt for
|
194
196
|
# password auth method
|
195
|
-
# * :non_interactive => non interactive applications should set it to true
|
196
|
-
# to prefer failing a password/etc auth methods vs asking for password
|
197
197
|
# * :password_prompt => a custom prompt object with ask method. See Net::SSH::Prompt
|
198
198
|
#
|
199
199
|
# * :agent_socket_factory => enables the user to pass a lambda/block that will serve as the socket factory
|
@@ -264,7 +264,7 @@ module Net
|
|
264
264
|
# to read.
|
265
265
|
#
|
266
266
|
# See Net::SSH::Config for the full description of all supported options.
|
267
|
-
def self.configuration_for(host, use_ssh_config
|
267
|
+
def self.configuration_for(host, use_ssh_config)
|
268
268
|
files = case use_ssh_config
|
269
269
|
when true then Net::SSH::Config.default_files
|
270
270
|
when false, nil then return {}
|
@@ -2,22 +2,182 @@ require 'net/ssh/buffer'
|
|
2
2
|
require 'net/ssh/errors'
|
3
3
|
require 'net/ssh/loggable'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
: RUBY_PLATFORM =~ /java/ ? :java : :unix
|
5
|
+
require 'net/ssh/transport/server_version'
|
6
|
+
require 'socket'
|
7
|
+
require 'rubygems'
|
9
8
|
|
10
|
-
|
11
|
-
class AgentError < Net::SSH::Exception; end
|
9
|
+
require 'net/ssh/authentication/pageant' if Gem.win_platform? && RUBY_PLATFORM != "java"
|
12
10
|
|
11
|
+
module Net; module SSH; module Authentication
|
12
|
+
# Class for representing agent-specific errors.
|
13
|
+
class AgentError < Net::SSH::Exception; end
|
13
14
|
# An exception for indicating that the SSH agent is not available.
|
14
15
|
class AgentNotAvailable < AgentError; end
|
15
|
-
end; end; end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
# This class implements a simple client for the ssh-agent protocol. It
|
18
|
+
# does not implement any specific protocol, but instead copies the
|
19
|
+
# behavior of the ssh-agent functions in the OpenSSH library (3.8).
|
20
|
+
#
|
21
|
+
# This means that although it behaves like a SSH1 client, it also has
|
22
|
+
# some SSH2 functionality (like signing data).
|
23
|
+
class Agent
|
24
|
+
include Loggable
|
25
|
+
|
26
|
+
# A simple module for extending keys, to allow comments to be specified
|
27
|
+
# for them.
|
28
|
+
module Comment
|
29
|
+
attr_accessor :comment
|
30
|
+
end
|
31
|
+
|
32
|
+
SSH2_AGENT_REQUEST_VERSION = 1
|
33
|
+
SSH2_AGENT_REQUEST_IDENTITIES = 11
|
34
|
+
SSH2_AGENT_IDENTITIES_ANSWER = 12
|
35
|
+
SSH2_AGENT_SIGN_REQUEST = 13
|
36
|
+
SSH2_AGENT_SIGN_RESPONSE = 14
|
37
|
+
SSH2_AGENT_FAILURE = 30
|
38
|
+
SSH2_AGENT_VERSION_RESPONSE = 103
|
39
|
+
|
40
|
+
SSH_COM_AGENT2_FAILURE = 102
|
41
|
+
|
42
|
+
SSH_AGENT_REQUEST_RSA_IDENTITIES = 1
|
43
|
+
SSH_AGENT_RSA_IDENTITIES_ANSWER1 = 2
|
44
|
+
SSH_AGENT_RSA_IDENTITIES_ANSWER2 = 5
|
45
|
+
SSH_AGENT_FAILURE = 5
|
46
|
+
|
47
|
+
# The underlying socket being used to communicate with the SSH agent.
|
48
|
+
attr_reader :socket
|
49
|
+
|
50
|
+
# Instantiates a new agent object, connects to a running SSH agent,
|
51
|
+
# negotiates the agent protocol version, and returns the agent object.
|
52
|
+
def self.connect(logger=nil, agent_socket_factory = nil)
|
53
|
+
agent = new(logger)
|
54
|
+
agent.connect!(agent_socket_factory)
|
55
|
+
agent.negotiate!
|
56
|
+
agent
|
57
|
+
end
|
58
|
+
|
59
|
+
# Creates a new Agent object, using the optional logger instance to
|
60
|
+
# report status.
|
61
|
+
def initialize(logger=nil)
|
62
|
+
self.logger = logger
|
63
|
+
end
|
64
|
+
|
65
|
+
# Connect to the agent process using the socket factory and socket name
|
66
|
+
# given by the attribute writers. If the agent on the other end of the
|
67
|
+
# socket reports that it is an SSH2-compatible agent, this will fail
|
68
|
+
# (it only supports the ssh-agent distributed by OpenSSH).
|
69
|
+
def connect!(agent_socket_factory = nil)
|
70
|
+
debug { "connecting to ssh-agent" }
|
71
|
+
@socket =
|
72
|
+
if agent_socket_factory
|
73
|
+
agent_socket_factory.call
|
74
|
+
elsif ENV['SSH_AUTH_SOCK'] && defined?(unix_socket_class)
|
75
|
+
unix_socket_class.open(ENV['SSH_AUTH_SOCK'])
|
76
|
+
elsif Gem.win_platform? && RUBY_ENGINE != "jruby"
|
77
|
+
Pageant::Socket.open
|
78
|
+
else
|
79
|
+
raise AgentNotAvailable, "Agent not configured"
|
80
|
+
end
|
81
|
+
rescue StandardError => e
|
82
|
+
error { "could not connect to ssh-agent: #{e.message}" }
|
83
|
+
raise AgentNotAvailable, $!.message
|
84
|
+
end
|
85
|
+
|
86
|
+
# Attempts to negotiate the SSH agent protocol version. Raises an error
|
87
|
+
# if the version could not be negotiated successfully.
|
88
|
+
def negotiate!
|
89
|
+
# determine what type of agent we're communicating with
|
90
|
+
type, body = send_and_wait(SSH2_AGENT_REQUEST_VERSION, :string, Transport::ServerVersion::PROTO_VERSION)
|
91
|
+
|
92
|
+
raise AgentNotAvailable, "SSH2 agents are not yet supported" if type == SSH2_AGENT_VERSION_RESPONSE
|
93
|
+
if type == SSH2_AGENT_FAILURE
|
94
|
+
debug { "Unexpected response type==#{type}, this will be ignored" }
|
95
|
+
elsif type != SSH_AGENT_RSA_IDENTITIES_ANSWER1 && type != SSH_AGENT_RSA_IDENTITIES_ANSWER2
|
96
|
+
raise AgentNotAvailable, "unknown response from agent: #{type}, #{body.to_s.inspect}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Return an array of all identities (public keys) known to the agent.
|
101
|
+
# Each key returned is augmented with a +comment+ property which is set
|
102
|
+
# to the comment returned by the agent for that key.
|
103
|
+
def identities
|
104
|
+
type, body = send_and_wait(SSH2_AGENT_REQUEST_IDENTITIES)
|
105
|
+
raise AgentError, "could not get identity count" if agent_failed(type)
|
106
|
+
raise AgentError, "bad authentication reply: #{type}" if type != SSH2_AGENT_IDENTITIES_ANSWER
|
107
|
+
|
108
|
+
identities = []
|
109
|
+
body.read_long.times do
|
110
|
+
key_str = body.read_string
|
111
|
+
comment_str = body.read_string
|
112
|
+
begin
|
113
|
+
key = Buffer.new(key_str).read_key
|
114
|
+
key.extend(Comment)
|
115
|
+
key.comment = comment_str
|
116
|
+
identities.push key
|
117
|
+
rescue NotImplementedError => e
|
118
|
+
error { "ignoring unimplemented key:#{e.message} #{comment_str}" }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
return identities
|
123
|
+
end
|
124
|
+
|
125
|
+
# Closes this socket. This agent reference is no longer able to
|
126
|
+
# query the agent.
|
127
|
+
def close
|
128
|
+
@socket.close
|
129
|
+
end
|
130
|
+
|
131
|
+
# Using the agent and the given public key, sign the given data. The
|
132
|
+
# signature is returned in SSH2 format.
|
133
|
+
def sign(key, data)
|
134
|
+
type, reply = send_and_wait(SSH2_AGENT_SIGN_REQUEST, :string, Buffer.from(:key, key), :string, data, :long, 0)
|
135
|
+
|
136
|
+
raise AgentError, "agent could not sign data with requested identity" if agent_failed(type)
|
137
|
+
raise AgentError, "bad authentication response #{type}" if type != SSH2_AGENT_SIGN_RESPONSE
|
138
|
+
|
139
|
+
return reply.read_string
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def unix_socket_class
|
145
|
+
UNIXSocket
|
146
|
+
end
|
147
|
+
|
148
|
+
# Send a new packet of the given type, with the associated data.
|
149
|
+
def send_packet(type, *args)
|
150
|
+
buffer = Buffer.from(*args)
|
151
|
+
data = [buffer.length + 1, type.to_i, buffer.to_s].pack("NCA*")
|
152
|
+
debug { "sending agent request #{type} len #{buffer.length}" }
|
153
|
+
@socket.send data, 0
|
154
|
+
end
|
155
|
+
|
156
|
+
# Read the next packet from the agent. This will return a two-part
|
157
|
+
# tuple consisting of the packet type, and the packet's body (which
|
158
|
+
# is returned as a Net::SSH::Buffer).
|
159
|
+
def read_packet
|
160
|
+
buffer = Net::SSH::Buffer.new(@socket.read(4))
|
161
|
+
buffer.append(@socket.read(buffer.read_long))
|
162
|
+
type = buffer.read_byte
|
163
|
+
debug { "received agent packet #{type} len #{buffer.length-4}" }
|
164
|
+
return type, buffer
|
165
|
+
end
|
166
|
+
|
167
|
+
# Send the given packet and return the subsequent reply from the agent.
|
168
|
+
# (See #send_packet and #read_packet).
|
169
|
+
def send_and_wait(type, *args)
|
170
|
+
send_packet(type, *args)
|
171
|
+
read_packet
|
172
|
+
end
|
173
|
+
|
174
|
+
# Returns +true+ if the parameter indicates a "failure" response from
|
175
|
+
# the agent, and +false+ otherwise.
|
176
|
+
def agent_failed(type)
|
177
|
+
type == SSH_AGENT_FAILURE ||
|
178
|
+
type == SSH2_AGENT_FAILURE ||
|
179
|
+
type == SSH_COM_AGENT2_FAILURE
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end; end; end
|