net-ssh 0.5.0
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.
- data/doc/LICENSE-BSD +27 -0
- data/doc/LICENSE-GPL +280 -0
- data/doc/LICENSE-RUBY +56 -0
- data/doc/README +13 -0
- data/doc/manual-html/chapter-1.html +333 -0
- data/doc/manual-html/chapter-2.html +455 -0
- data/doc/manual-html/chapter-3.html +413 -0
- data/doc/manual-html/chapter-4.html +353 -0
- data/doc/manual-html/chapter-5.html +393 -0
- data/doc/manual-html/chapter-6.html +296 -0
- data/doc/manual-html/index.html +217 -0
- data/doc/manual-html/manual.css +192 -0
- data/doc/manual/chapter.erb +18 -0
- data/doc/manual/example.erb +18 -0
- data/doc/manual/index.erb +29 -0
- data/doc/manual/manual.css +192 -0
- data/doc/manual/manual.rb +240 -0
- data/doc/manual/manual.yml +67 -0
- data/doc/manual/page.erb +87 -0
- data/doc/manual/parts/channels_callbacks.txt +32 -0
- data/doc/manual/parts/channels_loop.txt +14 -0
- data/doc/manual/parts/channels_open.txt +20 -0
- data/doc/manual/parts/channels_operations.txt +15 -0
- data/doc/manual/parts/channels_types.txt +3 -0
- data/doc/manual/parts/channels_what_are.txt +7 -0
- data/doc/manual/parts/exec_channels.txt +28 -0
- data/doc/manual/parts/exec_open.txt +51 -0
- data/doc/manual/parts/exec_popen3.txt +35 -0
- data/doc/manual/parts/forward_direct.txt +37 -0
- data/doc/manual/parts/forward_handlers.txt +16 -0
- data/doc/manual/parts/forward_intro.txt +18 -0
- data/doc/manual/parts/forward_local.txt +18 -0
- data/doc/manual/parts/forward_remote.txt +14 -0
- data/doc/manual/parts/intro_author.txt +1 -0
- data/doc/manual/parts/intro_getting.txt +39 -0
- data/doc/manual/parts/intro_license.txt +6 -0
- data/doc/manual/parts/intro_support.txt +7 -0
- data/doc/manual/parts/intro_what_is.txt +7 -0
- data/doc/manual/parts/intro_what_is_not.txt +3 -0
- data/doc/manual/parts/proxy_http.txt +52 -0
- data/doc/manual/parts/proxy_intro.txt +1 -0
- data/doc/manual/parts/proxy_socks.txt +23 -0
- data/doc/manual/parts/session_key.txt +66 -0
- data/doc/manual/parts/session_options.txt +42 -0
- data/doc/manual/parts/session_session.txt +14 -0
- data/doc/manual/parts/session_start.txt +49 -0
- data/doc/manual/tutorial.erb +30 -0
- data/examples/channel-demo.rb +81 -0
- data/examples/port-forward.rb +51 -0
- data/examples/process-demo.rb +91 -0
- data/examples/remote-net-port-forward.rb +45 -0
- data/examples/remote-port-forward.rb +80 -0
- data/examples/tail-demo.rb +49 -0
- data/lib/net/ssh.rb +52 -0
- data/lib/net/ssh/connection/channel.rb +411 -0
- data/lib/net/ssh/connection/constants.rb +47 -0
- data/lib/net/ssh/connection/driver.rb +343 -0
- data/lib/net/ssh/connection/services.rb +72 -0
- data/lib/net/ssh/connection/term.rb +90 -0
- data/lib/net/ssh/errors.rb +27 -0
- data/lib/net/ssh/proxy/errors.rb +34 -0
- data/lib/net/ssh/proxy/http.rb +126 -0
- data/lib/net/ssh/proxy/socks4.rb +83 -0
- data/lib/net/ssh/proxy/socks5.rb +160 -0
- data/lib/net/ssh/service/forward/driver.rb +319 -0
- data/lib/net/ssh/service/forward/local-network-handler.rb +74 -0
- data/lib/net/ssh/service/forward/remote-network-handler.rb +81 -0
- data/lib/net/ssh/service/forward/services.rb +76 -0
- data/lib/net/ssh/service/process/driver.rb +153 -0
- data/lib/net/ssh/service/process/open.rb +193 -0
- data/lib/net/ssh/service/process/popen3.rb +160 -0
- data/lib/net/ssh/service/process/services.rb +66 -0
- data/lib/net/ssh/service/services.rb +44 -0
- data/lib/net/ssh/session.rb +242 -0
- data/lib/net/ssh/transport/algorithm-negotiator.rb +267 -0
- data/lib/net/ssh/transport/compress/compressor.rb +53 -0
- data/lib/net/ssh/transport/compress/decompressor.rb +53 -0
- data/lib/net/ssh/transport/compress/none-compressor.rb +39 -0
- data/lib/net/ssh/transport/compress/none-decompressor.rb +39 -0
- data/lib/net/ssh/transport/compress/services.rb +68 -0
- data/lib/net/ssh/transport/compress/zlib-compressor.rb +60 -0
- data/lib/net/ssh/transport/compress/zlib-decompressor.rb +52 -0
- data/lib/net/ssh/transport/constants.rb +66 -0
- data/lib/net/ssh/transport/errors.rb +47 -0
- data/lib/net/ssh/transport/identity-cipher.rb +61 -0
- data/lib/net/ssh/transport/kex/dh-gex.rb +106 -0
- data/lib/net/ssh/transport/kex/dh.rb +231 -0
- data/lib/net/ssh/transport/kex/services.rb +60 -0
- data/lib/net/ssh/transport/ossl/buffer-factory.rb +52 -0
- data/lib/net/ssh/transport/ossl/buffer.rb +87 -0
- data/lib/net/ssh/transport/ossl/cipher-factory.rb +98 -0
- data/lib/net/ssh/transport/ossl/digest-factory.rb +51 -0
- data/lib/net/ssh/transport/ossl/hmac-factory.rb +71 -0
- data/lib/net/ssh/transport/ossl/hmac/hmac.rb +62 -0
- data/lib/net/ssh/transport/ossl/hmac/md5-96.rb +44 -0
- data/lib/net/ssh/transport/ossl/hmac/md5.rb +46 -0
- data/lib/net/ssh/transport/ossl/hmac/none.rb +46 -0
- data/lib/net/ssh/transport/ossl/hmac/services.rb +68 -0
- data/lib/net/ssh/transport/ossl/hmac/sha1-96.rb +44 -0
- data/lib/net/ssh/transport/ossl/hmac/sha1.rb +45 -0
- data/lib/net/ssh/transport/ossl/key-factory.rb +113 -0
- data/lib/net/ssh/transport/ossl/services.rb +149 -0
- data/lib/net/ssh/transport/packet-stream.rb +210 -0
- data/lib/net/ssh/transport/services.rb +146 -0
- data/lib/net/ssh/transport/session.rb +296 -0
- data/lib/net/ssh/transport/version-negotiator.rb +73 -0
- data/lib/net/ssh/userauth/agent.rb +218 -0
- data/lib/net/ssh/userauth/constants.rb +35 -0
- data/lib/net/ssh/userauth/driver.rb +176 -0
- data/lib/net/ssh/userauth/methods/hostbased.rb +119 -0
- data/lib/net/ssh/userauth/methods/password.rb +70 -0
- data/lib/net/ssh/userauth/methods/publickey.rb +137 -0
- data/lib/net/ssh/userauth/methods/services.rb +63 -0
- data/lib/net/ssh/userauth/services.rb +126 -0
- data/lib/net/ssh/userauth/userkeys.rb +258 -0
- data/lib/net/ssh/util/buffer.rb +274 -0
- data/lib/net/ssh/util/openssl.rb +146 -0
- data/lib/net/ssh/util/prompter.rb +73 -0
- data/lib/net/ssh/version.rb +29 -0
- data/test/ALL-TESTS.rb +21 -0
- data/test/connection/tc_channel.rb +136 -0
- data/test/connection/tc_driver.rb +287 -0
- data/test/connection/tc_integration.rb +85 -0
- data/test/proxy/tc_http.rb +209 -0
- data/test/proxy/tc_socks4.rb +148 -0
- data/test/proxy/tc_socks5.rb +214 -0
- data/test/service/forward/tc_driver.rb +289 -0
- data/test/service/forward/tc_local_network_handler.rb +123 -0
- data/test/service/forward/tc_remote_network_handler.rb +108 -0
- data/test/service/process/tc_driver.rb +79 -0
- data/test/service/process/tc_integration.rb +117 -0
- data/test/service/process/tc_open.rb +179 -0
- data/test/service/process/tc_popen3.rb +164 -0
- data/test/tc_integration.rb +79 -0
- data/test/transport/compress/tc_none_compress.rb +41 -0
- data/test/transport/compress/tc_none_decompress.rb +45 -0
- data/test/transport/compress/tc_zlib_compress.rb +61 -0
- data/test/transport/compress/tc_zlib_decompress.rb +48 -0
- data/test/transport/kex/tc_dh.rb +304 -0
- data/test/transport/kex/tc_dh_gex.rb +70 -0
- data/test/transport/ossl/fixtures/dsa-encrypted +15 -0
- data/test/transport/ossl/fixtures/dsa-encrypted-bad +15 -0
- data/test/transport/ossl/fixtures/dsa-unencrypted +12 -0
- data/test/transport/ossl/fixtures/dsa-unencrypted-bad +12 -0
- data/test/transport/ossl/fixtures/dsa-unencrypted.pub +1 -0
- data/test/transport/ossl/fixtures/not-a-private-key +4 -0
- data/test/transport/ossl/fixtures/not-supported +2 -0
- data/test/transport/ossl/fixtures/rsa-encrypted +18 -0
- data/test/transport/ossl/fixtures/rsa-encrypted-bad +18 -0
- data/test/transport/ossl/fixtures/rsa-unencrypted +15 -0
- data/test/transport/ossl/fixtures/rsa-unencrypted-bad +15 -0
- data/test/transport/ossl/fixtures/rsa-unencrypted.pub +1 -0
- data/test/transport/ossl/hmac/tc_hmac.rb +58 -0
- data/test/transport/ossl/hmac/tc_md5.rb +50 -0
- data/test/transport/ossl/hmac/tc_md5_96.rb +50 -0
- data/test/transport/ossl/hmac/tc_none.rb +50 -0
- data/test/transport/ossl/hmac/tc_sha1.rb +50 -0
- data/test/transport/ossl/hmac/tc_sha1_96.rb +50 -0
- data/test/transport/ossl/tc_buffer.rb +97 -0
- data/test/transport/ossl/tc_buffer_factory.rb +67 -0
- data/test/transport/ossl/tc_cipher_factory.rb +84 -0
- data/test/transport/ossl/tc_digest_factory.rb +39 -0
- data/test/transport/ossl/tc_hmac_factory.rb +72 -0
- data/test/transport/ossl/tc_key_factory.rb +199 -0
- data/test/transport/tc_algorithm_negotiator.rb +169 -0
- data/test/transport/tc_identity_cipher.rb +52 -0
- data/test/transport/tc_integration.rb +110 -0
- data/test/transport/tc_packet_stream.rb +183 -0
- data/test/transport/tc_session.rb +283 -0
- data/test/transport/tc_version_negotiator.rb +86 -0
- data/test/userauth/methods/tc_hostbased.rb +136 -0
- data/test/userauth/methods/tc_password.rb +89 -0
- data/test/userauth/methods/tc_publickey.rb +167 -0
- data/test/userauth/tc_agent.rb +223 -0
- data/test/userauth/tc_driver.rb +190 -0
- data/test/userauth/tc_integration.rb +81 -0
- data/test/userauth/tc_userkeys.rb +265 -0
- data/test/util/tc_buffer.rb +217 -0
- metadata +256 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# This source file is distributed as part of the Net::SSH Secure Shell Client
|
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
|
|
10
|
+
# distribution for the texts of these licenses.
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
# net-ssh website : http://net-ssh.rubyforge.org
|
|
13
|
+
# project website: http://rubyforge.org/projects/net-ssh
|
|
14
|
+
# =============================================================================
|
|
15
|
+
#++
|
|
16
|
+
|
|
17
|
+
require 'base64'
|
|
18
|
+
require 'openssl'
|
|
19
|
+
require 'net/ssh/util/buffer'
|
|
20
|
+
|
|
21
|
+
module OpenSSL
|
|
22
|
+
|
|
23
|
+
# This class is originally defined in the OpenSSL module. As needed, methods
|
|
24
|
+
# have been added to it by the Net::SSH module for convenience in dealing with
|
|
25
|
+
# SSH functionality.
|
|
26
|
+
class BN
|
|
27
|
+
|
|
28
|
+
# Converts a BN object to a string. The format used is that which is
|
|
29
|
+
# required by the SSH2 protocol.
|
|
30
|
+
def to_ssh
|
|
31
|
+
if zero?
|
|
32
|
+
return [ 0 ].pack( "N" )
|
|
33
|
+
else
|
|
34
|
+
buf = to_s( 2 )
|
|
35
|
+
if buf[0][7] == 1
|
|
36
|
+
return [ buf.length+1, 0, buf ].pack( "NCA*" )
|
|
37
|
+
else
|
|
38
|
+
return [ buf.length, buf ].pack( "NA*" )
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
module PKey
|
|
46
|
+
|
|
47
|
+
# This class is originally defined in the OpenSSL module. As needed, methods
|
|
48
|
+
# have been added to it by the Net::SSH module for convenience in dealing
|
|
49
|
+
# with SSH functionality.
|
|
50
|
+
class DH
|
|
51
|
+
|
|
52
|
+
# Determines whether the pub_key for this key is valid. (This algorithm
|
|
53
|
+
# lifted more-or-less directly from OpenSSH, dh.c, dh_pub_is_valid.)
|
|
54
|
+
def valid?
|
|
55
|
+
return false if pub_key < 0
|
|
56
|
+
bits_set = 0
|
|
57
|
+
pub_key.num_bits.times { |i| bits_set += 1 if pub_key.bit_set? i }
|
|
58
|
+
return ( bits_set > 1 && pub_key < p )
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# This class is originally defined in the OpenSSL module. As needed, methods
|
|
64
|
+
# have been added to it by the Net::SSH module for convenience in dealing
|
|
65
|
+
# with SSH functionality.
|
|
66
|
+
class RSA
|
|
67
|
+
|
|
68
|
+
# Returns "ssh-rsa", which is the description of this key type used by the
|
|
69
|
+
# SSH2 protocol.
|
|
70
|
+
def ssh_type
|
|
71
|
+
"ssh-rsa"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Converts the key to a blob, according to the SSH2 protocol.
|
|
75
|
+
def to_blob
|
|
76
|
+
buffer = Net::SSH::Util::WriterBuffer.new
|
|
77
|
+
buffer.write_bignum( e )
|
|
78
|
+
buffer.write_bignum( n )
|
|
79
|
+
return buffer.to_s
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Verifies the given signature matches the given data.
|
|
83
|
+
def ssh_do_verify( sig, data )
|
|
84
|
+
verify( OpenSSL::Digest::SHA1.new, sig, data )
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Returns the signature for the given data.
|
|
88
|
+
def ssh_do_sign( data )
|
|
89
|
+
sign( OpenSSL::Digest::SHA1.new, data )
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# This class is originally defined in the OpenSSL module. As needed, methods
|
|
94
|
+
# have been added to it by the Net::SSH module for convenience in dealing
|
|
95
|
+
# with SSH functionality.
|
|
96
|
+
class DSA
|
|
97
|
+
|
|
98
|
+
# Returns "ssh-dss", which is the description of this key type used by the
|
|
99
|
+
# SSH2 protocol.
|
|
100
|
+
def ssh_type
|
|
101
|
+
"ssh-dss"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Converts the key to a blob, according to the SSH2 protocol.
|
|
105
|
+
def to_blob
|
|
106
|
+
buffer = Net::SSH::Util::WriterBuffer.new
|
|
107
|
+
buffer.write_bignum( p )
|
|
108
|
+
buffer.write_bignum( q )
|
|
109
|
+
buffer.write_bignum( g )
|
|
110
|
+
buffer.write_bignum( pub_key )
|
|
111
|
+
return buffer.to_s
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Verifies the given signature matches the given data.
|
|
115
|
+
def ssh_do_verify( sig, data )
|
|
116
|
+
sig_r = sig[0,20].unpack("H*")[0].to_i(16)
|
|
117
|
+
sig_s = sig[20,20].unpack("H*")[0].to_i(16)
|
|
118
|
+
a1sig = OpenSSL::ASN1::Sequence([
|
|
119
|
+
OpenSSL::ASN1::Integer(sig_r),
|
|
120
|
+
OpenSSL::ASN1::Integer(sig_s)
|
|
121
|
+
])
|
|
122
|
+
return verify(OpenSSL::Digest::DSS1.new, a1sig.to_der, data)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Sigs the given data.
|
|
126
|
+
def ssh_do_sign( data )
|
|
127
|
+
sig = sign( OpenSSL::Digest::DSS1.new, data)
|
|
128
|
+
a1sig = OpenSSL::ASN1.decode( sig )
|
|
129
|
+
|
|
130
|
+
sig_r = a1sig.value[0].value.to_s(2)
|
|
131
|
+
sig_s = a1sig.value[1].value.to_s(2)
|
|
132
|
+
|
|
133
|
+
if sig_r.length > 20 || sig_s.length > 20
|
|
134
|
+
raise OpenSSL::PKey::DSAError, "bad sig size"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
sig_r = "\0" * ( 20 - sig_r.length ) + sig_r if sig_r.length < 20
|
|
138
|
+
sig_s = "\0" * ( 20 - sig_s.length ) + sig_s if sig_s.length < 20
|
|
139
|
+
|
|
140
|
+
return sig_r + sig_s
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# This source file is distributed as part of the Net::SSH Secure Shell Client
|
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
|
|
10
|
+
# distribution for the texts of these licenses.
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
# net-ssh website : http://net-ssh.rubyforge.org
|
|
13
|
+
# project website: http://rubyforge.org/projects/net-ssh
|
|
14
|
+
# =============================================================================
|
|
15
|
+
#++
|
|
16
|
+
|
|
17
|
+
unless defined?( HAS_TERMIOS )
|
|
18
|
+
begin
|
|
19
|
+
require 'termios'
|
|
20
|
+
HAS_TERMIOS = true
|
|
21
|
+
rescue LoadError
|
|
22
|
+
HAS_TERMIOS = false
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module Net
|
|
27
|
+
module SSH
|
|
28
|
+
module Util
|
|
29
|
+
|
|
30
|
+
# A simple class for prompting a user for input.
|
|
31
|
+
class Prompter
|
|
32
|
+
|
|
33
|
+
# Displays the prompt and then waits for the user to enter a response.
|
|
34
|
+
# If the 'termios' library is available, the user's input will not be
|
|
35
|
+
# echoed to the terminal. The user's response will be returned, with
|
|
36
|
+
# any trailing newline chomped.
|
|
37
|
+
def password( prompt=nil )
|
|
38
|
+
if $stdin.tty?
|
|
39
|
+
echo false
|
|
40
|
+
print prompt if prompt
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
$stdin.gets.chomp
|
|
44
|
+
ensure
|
|
45
|
+
if $stdin.tty?
|
|
46
|
+
echo true
|
|
47
|
+
puts
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
if HAS_TERMIOS
|
|
52
|
+
def echo( enable )
|
|
53
|
+
term = Termios::getattr( $stdin )
|
|
54
|
+
|
|
55
|
+
if enable
|
|
56
|
+
term.c_lflag |= ( Termios::ECHO | Termios::ICANON )
|
|
57
|
+
else
|
|
58
|
+
term.c_lflag &= ~Termios::ECHO
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
Termios::setattr( $stdin, Termios::TCSANOW, term )
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
def echo( enable )
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
private :echo
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# This source file is distributed as part of the Net::SSH Secure Shell Client
|
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
|
|
10
|
+
# distribution for the texts of these licenses.
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
# net-ssh website : http://net-ssh.rubyforge.org
|
|
13
|
+
# project website: http://rubyforge.org/projects/net-ssh
|
|
14
|
+
# =============================================================================
|
|
15
|
+
#++
|
|
16
|
+
|
|
17
|
+
module Net
|
|
18
|
+
module SSH
|
|
19
|
+
module Version
|
|
20
|
+
|
|
21
|
+
MAJOR = 0
|
|
22
|
+
MINOR = 5
|
|
23
|
+
TINY = 0
|
|
24
|
+
|
|
25
|
+
STRING = [ MAJOR, MINOR, TINY ].join( "." )
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/test/ALL-TESTS.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# This source file is distributed as part of the Net::SSH Secure Shell Client
|
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
|
|
10
|
+
# distribution for the texts of these licenses.
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
# net-ssh website : http://net-ssh.rubyforge.org
|
|
13
|
+
# project website: http://rubyforge.org/projects/net-ssh
|
|
14
|
+
# =============================================================================
|
|
15
|
+
#++
|
|
16
|
+
|
|
17
|
+
$:.unshift "../lib"
|
|
18
|
+
|
|
19
|
+
$run_integration_tests = ARGV.include?( "-i" )
|
|
20
|
+
|
|
21
|
+
Dir["**/tc_*.rb"].each { |f| load f }
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# This source file is distributed as part of the Net::SSH Secure Shell Client
|
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
|
|
10
|
+
# distribution for the texts of these licenses.
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
# net-ssh website : http://net-ssh.rubyforge.org
|
|
13
|
+
# project website: http://rubyforge.org/projects/net-ssh
|
|
14
|
+
# =============================================================================
|
|
15
|
+
#++
|
|
16
|
+
|
|
17
|
+
$:.unshift "../../lib"
|
|
18
|
+
|
|
19
|
+
require 'test/unit'
|
|
20
|
+
require 'net/ssh/connection/channel'
|
|
21
|
+
require 'net/ssh/util/buffer'
|
|
22
|
+
|
|
23
|
+
class TC_Channel < Test::Unit::TestCase
|
|
24
|
+
|
|
25
|
+
class Buffers
|
|
26
|
+
def writer
|
|
27
|
+
Net::SSH::Util::WriterBuffer.new
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class Log
|
|
32
|
+
def debug?
|
|
33
|
+
false
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Connection
|
|
38
|
+
attr_reader :buffers
|
|
39
|
+
attr_reader :events
|
|
40
|
+
|
|
41
|
+
def initialize( buffers )
|
|
42
|
+
@events = []
|
|
43
|
+
@buffers = buffers
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def send_message( msg )
|
|
47
|
+
@events << msg.to_s
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def allocate_channel_id
|
|
51
|
+
events << :allocate_channel_id
|
|
52
|
+
1234
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def remove_channel( channel )
|
|
56
|
+
events << :remove_channel
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def setup
|
|
61
|
+
@connection = Connection.new( Buffers.new )
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_open_no_data
|
|
65
|
+
channel = Net::SSH::Connection::Channel.open( @connection, Log.new,
|
|
66
|
+
Buffers.new, "test" )
|
|
67
|
+
assert_equal [ :allocate_channel_id,
|
|
68
|
+
"\132\0\0\0\4test\0\0\4\xd2\x7f\xff\xff\xff\x7f\xff\xff\xff" ],
|
|
69
|
+
@connection.events
|
|
70
|
+
assert_equal "test", channel.type
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def test_open_with_data
|
|
74
|
+
channel = Net::SSH::Connection::Channel.open( @connection, Log.new,
|
|
75
|
+
Buffers.new, "test", "some data" )
|
|
76
|
+
assert_equal [ :allocate_channel_id,
|
|
77
|
+
"\132\0\0\0\4test\0\0\4\xd2\x7f\xff\xff\xff\x7f\xff\xff\xffsome data" ],
|
|
78
|
+
@connection.events
|
|
79
|
+
assert_equal "test", channel.type
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_do_confirm_open
|
|
83
|
+
confirmed = nil
|
|
84
|
+
channel = Net::SSH::Connection::Channel.open( @connection, Log.new,
|
|
85
|
+
Buffers.new, "test" )
|
|
86
|
+
channel.on_confirm_open { |a| confirmed = a }
|
|
87
|
+
channel.do_confirm_open 1, 2, 3
|
|
88
|
+
assert_same channel, confirmed
|
|
89
|
+
assert_equal 1, channel.remote_id
|
|
90
|
+
assert_equal 2, channel.window_size
|
|
91
|
+
assert_equal 3, channel.maximum_packet_size
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def create_channel
|
|
95
|
+
Net::SSH::Connection::Channel.create( @connection, Log.new, Buffers.new,
|
|
96
|
+
"test", 1, 2, 3 )
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def test_create
|
|
100
|
+
channel = create_channel
|
|
101
|
+
assert_equal "test", channel.type
|
|
102
|
+
assert_equal [ :allocate_channel_id ], @connection.events
|
|
103
|
+
assert_equal 1234, channel.local_id
|
|
104
|
+
assert_equal 1, channel.remote_id
|
|
105
|
+
assert_equal 2, channel.window_size
|
|
106
|
+
assert_equal 3, channel.maximum_packet_size
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_new
|
|
110
|
+
assert_raise( NoMethodError ) do
|
|
111
|
+
Net::SSH::Connection::Channel.new( @connection, "test" )
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def self.test_callback( name, do_args=[], expect=do_args )
|
|
116
|
+
define_method( "test_#{name}".to_sym ) do
|
|
117
|
+
channel = create_channel
|
|
118
|
+
|
|
119
|
+
result = nil
|
|
120
|
+
channel.send( "on_#{name}".to_sym ) { |*a| result = a }
|
|
121
|
+
channel.send( "do_#{name}".to_sym, *do_args )
|
|
122
|
+
|
|
123
|
+
assert_equal [ channel, *expect ], result
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
test_callback :confirm_open, [ 1, 2, 3 ], []
|
|
128
|
+
test_callback :confirm_failed, [ 100, "b", "c" ]
|
|
129
|
+
test_callback :window_adjust, [ 14 ]
|
|
130
|
+
test_callback :data, [ "blah" ]
|
|
131
|
+
test_callback :extended_data, [ 1, "blah" ]
|
|
132
|
+
test_callback :eof
|
|
133
|
+
test_callback :request, [ true, "blah" ]
|
|
134
|
+
test_callback :success
|
|
135
|
+
test_callback :failure
|
|
136
|
+
end
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# This source file is distributed as part of the Net::SSH Secure Shell Client
|
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
|
|
10
|
+
# distribution for the texts of these licenses.
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
# net-ssh website : http://net-ssh.rubyforge.org
|
|
13
|
+
# project website: http://rubyforge.org/projects/net-ssh
|
|
14
|
+
# =============================================================================
|
|
15
|
+
#++
|
|
16
|
+
|
|
17
|
+
$:.unshift "../../lib"
|
|
18
|
+
|
|
19
|
+
require 'test/unit'
|
|
20
|
+
require 'net/ssh/connection/driver'
|
|
21
|
+
require 'net/ssh/errors'
|
|
22
|
+
require 'net/ssh/util/buffer'
|
|
23
|
+
|
|
24
|
+
class TC_Driver < Test::Unit::TestCase
|
|
25
|
+
|
|
26
|
+
class Buffers
|
|
27
|
+
def writer
|
|
28
|
+
Net::SSH::Util::WriterBuffer.new
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Log
|
|
33
|
+
attr_reader :messages
|
|
34
|
+
|
|
35
|
+
def initialize
|
|
36
|
+
@messages = []
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def debug?
|
|
40
|
+
true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def debug( msg )
|
|
44
|
+
@messages << msg
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class Session
|
|
49
|
+
attr_reader :events
|
|
50
|
+
attr_reader :script
|
|
51
|
+
|
|
52
|
+
def initialize
|
|
53
|
+
@events = []
|
|
54
|
+
@script = []
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def send_message( msg )
|
|
58
|
+
@events << msg.to_s
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def wait_for_message
|
|
62
|
+
@script.shift
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class Channel
|
|
67
|
+
attr_reader :local_id
|
|
68
|
+
attr_reader :remote_id
|
|
69
|
+
attr_reader :data
|
|
70
|
+
attr_reader :window_size
|
|
71
|
+
attr_reader :packet_size
|
|
72
|
+
attr_reader :type
|
|
73
|
+
attr_reader :block
|
|
74
|
+
attr_reader :events
|
|
75
|
+
|
|
76
|
+
def self.open( type, data )
|
|
77
|
+
new( type, data, nil, nil, nil )
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def self.create( type, remote_id, window_size, packet_size )
|
|
81
|
+
new( type, nil, remote_id, window_size, packet_size )
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def initialize( type, data, remote_id, winsize, packsize )
|
|
85
|
+
@type = type
|
|
86
|
+
@data = data
|
|
87
|
+
@remote_id = remote_id
|
|
88
|
+
@window_size = winsize
|
|
89
|
+
@packet_size = packsize
|
|
90
|
+
@local_id = 1
|
|
91
|
+
@events = []
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def close( value )
|
|
95
|
+
@events << [ :close, value ]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def on_confirm_open( &block )
|
|
99
|
+
@block = block
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def self.event( name )
|
|
103
|
+
define_method( "do_#{name}".to_sym ) do |*args|
|
|
104
|
+
@events << [ name, *args ]
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
event :confirm_failed
|
|
109
|
+
event :confirm_open
|
|
110
|
+
event :window_adjust
|
|
111
|
+
event :data
|
|
112
|
+
event :extended_data
|
|
113
|
+
event :eof
|
|
114
|
+
event :request
|
|
115
|
+
event :success
|
|
116
|
+
event :failure
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def reader( text )
|
|
120
|
+
Net::SSH::Util::ReaderBuffer.new( text )
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def setup
|
|
124
|
+
@session = Session.new
|
|
125
|
+
@log = Log.new
|
|
126
|
+
@driver = Net::SSH::Connection::Driver.new( @session, @log,
|
|
127
|
+
Buffers.new,
|
|
128
|
+
:open => proc { |t,d| Channel.open(t,d) },
|
|
129
|
+
:create => proc { |t,r,w,p| Channel.create(t,r,w,p) } )
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def test_open_channel
|
|
133
|
+
channel = @driver.open_channel( "test", "data" ) { |a| a }
|
|
134
|
+
assert_equal "hello", channel.block.call( "hello" )
|
|
135
|
+
assert_equal "test", channel.type
|
|
136
|
+
assert_equal "data", channel.data
|
|
137
|
+
assert_equal [ channel ], @driver.channels
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def test_remove_channel
|
|
141
|
+
channel = @driver.open_channel( "test", "data" ) { |a| a }
|
|
142
|
+
assert_equal [channel], @driver.channels
|
|
143
|
+
@driver.remove_channel( channel )
|
|
144
|
+
assert_equal [], @driver.channels
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_allocate_channel_id
|
|
148
|
+
assert_equal 1, @driver.allocate_channel_id
|
|
149
|
+
10.times { @driver.allocate_channel_id }
|
|
150
|
+
assert_equal 12, @driver.allocate_channel_id
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def test_global_request
|
|
154
|
+
@driver.global_request "test", "foobar"
|
|
155
|
+
assert_equal [ "\120\0\0\0\4test\1foobar" ], @session.events
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def test_request_success
|
|
159
|
+
@driver.global_request( "test", "foobar" ) do |a,b|
|
|
160
|
+
assert a
|
|
161
|
+
assert_equal "response", b
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
@driver.do_request_success "response"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def test_request_failure
|
|
168
|
+
@driver.global_request( "test", "foobar" ) do |a,b|
|
|
169
|
+
assert !a
|
|
170
|
+
assert_equal "response", b
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
@driver.do_request_failure "response"
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def test_channel_open_no_handler
|
|
177
|
+
assert_raise( Net::SSH::Exception ) do
|
|
178
|
+
@driver.do_channel_open(
|
|
179
|
+
reader( "\0\0\0\4test\0\0\0\4\0\0\0\0\0\0\0\1" ) )
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def test_channel_open_with_handler
|
|
184
|
+
@driver.add_channel_open_handler( "test" ) do |conn,chan,resp|
|
|
185
|
+
assert_equal @driver, conn
|
|
186
|
+
assert_equal "test", chan.type
|
|
187
|
+
assert_equal 4, chan.remote_id
|
|
188
|
+
assert_equal 0, chan.window_size
|
|
189
|
+
assert_equal 1, chan.packet_size
|
|
190
|
+
assert_equal "hello world", resp.read
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
@driver.do_channel_open(
|
|
194
|
+
reader( "\0\0\0\4test\0\0\0\4\0\0\0\0\0\0\0\1hello world" ) )
|
|
195
|
+
|
|
196
|
+
assert_equal 1, @driver.channels.length
|
|
197
|
+
assert_equal [ "\133\0\0\0\4\0\0\0\1\x7f\xff\xff\xff\x7f\xff\xff\xff" ],
|
|
198
|
+
@session.events
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def test_channel_open_failure
|
|
202
|
+
channel = @driver.open_channel( "test", "data" )
|
|
203
|
+
assert_equal 1, @driver.channels.length
|
|
204
|
+
@driver.do_channel_open_failure(
|
|
205
|
+
reader( "\0\0\0\1\0\0\0\2\0\0\0\4test\0\0\0\2en" ) )
|
|
206
|
+
assert_equal 0, @driver.channels.length
|
|
207
|
+
assert_equal [ [ :confirm_failed, 2, "test", "en" ] ], channel.events
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def test_channel_open_confirmation
|
|
211
|
+
channel = @driver.open_channel( "test", "data" )
|
|
212
|
+
@driver.do_channel_open_confirmation(
|
|
213
|
+
reader( "\0\0\0\1\0\0\0\2\0\0\0\3\0\0\0\4" ) )
|
|
214
|
+
assert_equal 1, @driver.channels.length
|
|
215
|
+
assert_equal [ [ :confirm_open, 2, 3, 4 ] ], channel.events
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def test_channel_window_adjust
|
|
219
|
+
channel = @driver.open_channel( "test", "data" )
|
|
220
|
+
@driver.do_channel_window_adjust( reader( "\0\0\0\1\0\0\0\12" ) )
|
|
221
|
+
assert_equal 1, @driver.channels.length
|
|
222
|
+
assert_equal [ [ :window_adjust, 10 ] ], channel.events
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def test_channel_data
|
|
226
|
+
channel = @driver.open_channel( "test", "data" )
|
|
227
|
+
@driver.do_channel_data( reader( "\0\0\0\1\0\0\0\4test" ) )
|
|
228
|
+
assert_equal 1, @driver.channels.length
|
|
229
|
+
assert_equal [ [ :data, "test" ] ], channel.events
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def test_channel_extended_data
|
|
233
|
+
channel = @driver.open_channel( "test", "data" )
|
|
234
|
+
@driver.do_channel_extended_data( reader( "\0\0\0\1\0\0\0\2\0\0\0\4test" ) )
|
|
235
|
+
assert_equal 1, @driver.channels.length
|
|
236
|
+
assert_equal [ [ :extended_data, 2, "test" ] ], channel.events
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def test_channel_eof
|
|
240
|
+
channel = @driver.open_channel( "test", "data" )
|
|
241
|
+
@driver.do_channel_eof( reader( "\0\0\0\1" ) )
|
|
242
|
+
assert_equal 1, @driver.channels.length
|
|
243
|
+
assert_equal [ [ :eof ] ], channel.events
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def test_channel_close
|
|
247
|
+
channel = @driver.open_channel( "test", "data" )
|
|
248
|
+
@driver.do_channel_close( reader( "\0\0\0\1" ) )
|
|
249
|
+
assert_equal 1, @driver.channels.length
|
|
250
|
+
assert_equal [ [ :close, false ] ], channel.events
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def test_channel_request
|
|
254
|
+
channel = @driver.open_channel( "test", "data" )
|
|
255
|
+
@driver.do_channel_request( reader( "\0\0\0\1\0\0\0\4test\1foobarbaz" ) )
|
|
256
|
+
assert_equal 1, @driver.channels.length
|
|
257
|
+
assert_equal [ [ :request, "test", true, reader("foobarbaz") ] ],
|
|
258
|
+
channel.events
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def test_channel_success
|
|
262
|
+
channel = @driver.open_channel( "test", "data" )
|
|
263
|
+
@driver.do_channel_success( reader( "\0\0\0\1" ) )
|
|
264
|
+
assert_equal 1, @driver.channels.length
|
|
265
|
+
assert_equal [ [ :success ] ], channel.events
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def test_channel_failure
|
|
269
|
+
channel = @driver.open_channel( "test", "data" )
|
|
270
|
+
@driver.do_channel_failure( reader( "\0\0\0\1" ) )
|
|
271
|
+
assert_equal 1, @driver.channels.length
|
|
272
|
+
assert_equal [ [ :failure ] ], channel.events
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
ProcessItem = Struct.new( :name, :script, :events )
|
|
276
|
+
def self.i( name, script, events )
|
|
277
|
+
ProcessItem.new( name, script, events )
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def test_process_bad
|
|
281
|
+
@session.script << [ 0, reader("") ]
|
|
282
|
+
assert_raise( Net::SSH::Exception ) do
|
|
283
|
+
@driver.process
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
end
|