net-ssh 1.1.1 → 1.1.2

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/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Net::SSH is copyrighted free software by Jamis Buck <jamis@37signals.com>.
2
+ The reader is hereby granted permission to redistribute and/or modify it
3
+ under the terms of the BSD license, the Ruby license, or (by association
4
+ with the Ruby license) the GPL, at the reader's option.
5
+
6
+ Look in the "doc" subdirectory, and see the LICENSE-BSD, LICENSE-RUBY and
7
+ LICENSE-GPL files for the text of these licenses.
data/NEWS ADDED
@@ -0,0 +1,146 @@
1
+ Net:SSH
2
+ http://rubyforge.org/projects/net-ssh
3
+
4
+ [1.1.2] 18 June 2007
5
+ * Fixed bug #6156 (ruby -w warnings)
6
+
7
+ * Fixed bug #11532 (Hang after MSG_CHANNEL_OPEN_FAILURE)
8
+
9
+ * Fixed bug #10818 (Exception in split_data_for_packet)
10
+
11
+ * Fixed bug #6667 (wrong SOCKS 5 auth version)
12
+
13
+ * Fixed bug #11270 (error when server uses some aes ciphers)
14
+
15
+ * Fixed bug #11355 (typo in session.rb)
16
+
17
+ * Fixed bug #11250 (host key verification problems when an RSA key appears
18
+ in the known hosts file, but the server has both DSS and RSA keys)
19
+
20
+ [1.1.1] 9 May 2007
21
+ * Fixed broken mkdir in host key verification.
22
+
23
+ * Fixed problems with Windows users getting "address family for hostname
24
+ not supported" errors.
25
+
26
+ [1.1.0] 1 May 2007
27
+ * Added the missing rb-keygen utility
28
+
29
+ * Server key verification (enabled by default, disable with :paranoid => false)
30
+
31
+ * Add support for SSH agent forwwarding
32
+
33
+ [1.0.10] 9 Sep 2006
34
+ * Experiment with using read instead of sysread, to try and alleviate problems
35
+ on Windows.
36
+
37
+ * Use printf instead of echo -n in the shell service, for compatibility with
38
+ more unices.
39
+
40
+ * Give a sane error message when the user name is nil and cannot be derived
41
+ from the environment.
42
+
43
+ * Add a #connection accessor to the session.
44
+
45
+ * Add initial support for server-originated global requests.
46
+
47
+ [1.0.9] 14 Apr 2006
48
+ * Fix a bug when used in tandem with edge Rails, due to monkeypatching in Rails.
49
+
50
+ [1.0.8] 18 Feb 2006
51
+ * Move connect for forwarded connections outside of thread so errors can be
52
+ caught
53
+
54
+ [1.0.7] 27 Jan 2006
55
+ * Fix intermittent "corrupt mac" bug (finally!)
56
+
57
+ [1.0.6] 19 Jan 2006
58
+ * Send NEWKEYS message first, for compatibility with wodSSHServer (which
59
+ won't send NEWKEYS until recieving it)
60
+
61
+ * Do not print the banner message by default on authorization (rarely useful
62
+ for automated processes anyway)
63
+
64
+ [1.0.5] 2 Jan 2006
65
+ * Added connection.ping! and session.ping! for testing the connection
66
+
67
+ [1.0.4] 24 Dec 2005
68
+ * Fixed tests broken by changes in Ruby 1.8.4.
69
+
70
+ * Fixed references to obsolete contact email address.
71
+
72
+ [1.0.3] 9 Nov 2005
73
+ * Fixed for windows so that connections succeed even if pageant process is
74
+ not running.
75
+
76
+ [1.0.2] 26 Jul 2005
77
+ * Fixed channel on_request callback signature.
78
+
79
+ * Better thread-safety in the connection driver (fixes some "Bad packet size"
80
+ errors in multi-threaded apps)
81
+
82
+ * Corrected various minor bugs.
83
+
84
+ [1.0.1] 17 Jun 2005
85
+ * Added a :timeout option on the transport session
86
+
87
+ * Net::SSH works with the Putty Agent now
88
+
89
+ [1.0.0] 6 Feb 2005
90
+ * Password can be programmatically specified for the 'keyboard-authentication'
91
+ method.
92
+
93
+ * All unit tests pass on Windows now.
94
+
95
+ * Channels now respect their own local window and maximum packet sizes, and
96
+ report reasonable values to the server. This fixes a bug that caused
97
+ problems when large quantities of data were requested of the server and
98
+ certain server maximums were being exceeded.
99
+
100
+ * Client name is determined in a more robust manner.
101
+
102
+ * Fixed hostbased bug.
103
+
104
+ * Authentication process is now aware of the authentication methods reported
105
+ by the server as having a chance of succeeded, and no longer attempts
106
+ those methods that cannot possibly succeed.
107
+
108
+ [0.9.0] 11 Jan 2005
109
+ * Added 'shell' and 'sync' services for interacting with users' shells,
110
+ including a demo script that uses these to implement a simple SSH terminal
111
+ client.
112
+
113
+ * The 'keyboard-interactive' authentication method is implemented correctly
114
+ now, which means users will receive a prompt to enter a password if one is
115
+ not given, and is required.
116
+
117
+ * The bug that caused the agent to always be used--even if it was
118
+ unavailable--has been fixed.
119
+
120
+ * The user manual now includes links to previous/next chapters, and uses
121
+ syntax highlighting for the code blocks. Various other style tweaks in the
122
+ manual.
123
+
124
+ * Window sizes and maximum packet sizes are now honored, which should take
125
+ care of various bugs and make Net::SSH play nicer with older SSH servers.
126
+
127
+ * Non-blocking reads are now supported via the
128
+ Transport::Session#reader_ready? method. The Connection::Driver#process
129
+ method has been modified to make better use of this.
130
+
131
+ * Moved to subversion, from CVS. Repository is now at
132
+ http://www.jamisbuck.org/svn/net-ssh
133
+
134
+ [0.6.0] 2 Dec 2004
135
+ * Added pageant support (thanks to Guillaume Mar�ais)
136
+
137
+ * Added support for external services (like SFTP).
138
+
139
+ * Use USERNAME environment variable if USER is not set (like on Windows)
140
+
141
+ [0.5.0] 23 Nov 2004
142
+ * Refactored to use Needle.
143
+
144
+ * Moved SFTP support into its own library.
145
+
146
+ * Moved command-line utilities into their own library.
data/README ADDED
@@ -0,0 +1,14 @@
1
+ = Net::SSH
2
+
3
+ <b><em>A pure Ruby module that emulates an SSH client.</em></b>
4
+
5
+ <em>Author: Jamis Buck (jamis@37signals.com)</em>
6
+
7
+ Net::SSH absolutely WILL NOT work with the version of Ruby's OpenSSL module currently shipped with Ruby versions < 1.8.2 final. If you insist on trying it with a pre-1.8.2 final version, you must get a patched version of the OpenSSL module and install it (and remove the old module) before using Net::SSH.
8
+
9
+ The current release of Net::SSH supports:
10
+
11
+ * the execution of processes on the remote host (interactively, or non-interactively)
12
+ * interacting with a user's shell
13
+ * port forwarding, both from a local port to a remote port, and vice versa
14
+ * HTTP and SOCKS proxy support (and support for creation of additional proxy types)
data/THANKS ADDED
@@ -0,0 +1,19 @@
1
+ Net::SSH was originally written by Jamis Buck <jamis@37signals.com>. In
2
+ addition, the following individuals are gratefully acknowledged for their
3
+ contributions:
4
+
5
+ GOTOU Yuuzou <gotoyuzo@notwork.org>
6
+ * help and code related to OpenSSL
7
+
8
+ Guillaume Mar�ais <guillaume.marcais@free.fr>
9
+ * support for communicating with the the PuTTY "pageant" process
10
+
11
+ Daniel Berger <djberg96@yahoo.com>
12
+ * help getting unit tests to pass in Windows
13
+
14
+ Chris Andrews <chris@nodnol.org> and Lee Jensen <lee@outerim.com>
15
+ * support for ssh agent forwarding
16
+
17
+ If you have contributed to Net::SSH and are not on the above list, please do
18
+ not take offense! Jamis is notoriously forgetful. Instead, just let him know
19
+ what your contribution was, and he'll be only too happy to add you.
@@ -200,7 +200,7 @@ class KeyGenerator
200
200
  # prints the messages to +stderr+.
201
201
  def if_chatty( *args )
202
202
  unless @options[ :quiet ]
203
- $stderr.puts *args
203
+ $stderr.puts(*args)
204
204
  end
205
205
  end
206
206
  private :if_chatty
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.1.1</strong><br />
18
- Manual Last Updated: <strong>2007-05-10 04:06 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.2</strong><br />
18
+ Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.1.1</strong><br />
18
- Manual Last Updated: <strong>2007-05-10 04:06 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.2</strong><br />
18
+ Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.1.1</strong><br />
18
- Manual Last Updated: <strong>2007-05-10 04:06 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.2</strong><br />
18
+ Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.1.1</strong><br />
18
- Manual Last Updated: <strong>2007-05-10 04:06 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.2</strong><br />
18
+ Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.1.1</strong><br />
18
- Manual Last Updated: <strong>2007-05-10 04:06 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.2</strong><br />
18
+ Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.1.1</strong><br />
18
- Manual Last Updated: <strong>2007-05-10 04:06 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.2</strong><br />
18
+ Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.1.1</strong><br />
18
- Manual Last Updated: <strong>2007-05-10 04:06 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.2</strong><br />
18
+ Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.1.1</strong><br />
18
- Manual Last Updated: <strong>2007-05-10 04:06 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.2</strong><br />
18
+ Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -303,10 +303,10 @@ module Net
303
303
  data = data[0,window_size]
304
304
  end
305
305
 
306
- if data.length + overhead > maximum_packet_size
307
- data_to_return = data[maximum_packet_size..-1] +
308
- ( data_to_return || "" )
309
- data = data[0,maximum_packet_size]
306
+ max_size_less_overhead = maximum_packet_size - overhead
307
+ if data.length > max_size_less_overhead
308
+ data_to_return = data[max_size_less_overhead..-1] + ( data_to_return || "" )
309
+ data = data[0,max_size_less_overhead]
310
310
  end
311
311
 
312
312
  [ data, data_to_return ]
@@ -71,7 +71,7 @@ module Net
71
71
  # the confirmation, the +on_confirm+ callback will be invoked.
72
72
  def open_channel( type, extra_data=nil, &on_confirm )
73
73
  channel = @factories[:open].call( type, extra_data )
74
- channel.on_confirm_open &on_confirm
74
+ channel.on_confirm_open(&on_confirm)
75
75
  @channel_map[ channel.local_id ] = channel
76
76
  end
77
77
 
@@ -1,20 +1,13 @@
1
1
  require 'net/ssh/errors'
2
+ require 'net/ssh/known-hosts'
2
3
 
3
4
  module Net
4
5
  module SSH
5
6
 
6
7
  class HostKeyVerifier
7
8
  def verify(arguments)
8
- # first, find any matches on hostname+port
9
- matches = keys.select do |item|
10
- host = item[:host] || arguments[:peer][:host]
11
- ip = item[:ip] || arguments[:peer][:ip]
12
- port = item[:port] || arguments[:peer][:port]
13
-
14
- host == arguments[:peer][:host] &&
15
- ip == arguments[:peer][:ip] &&
16
- port == arguments[:peer][:port]
17
- end
9
+ host = canonize(arguments[:peer])
10
+ matches = Net::SSH::KnownHosts.search_for(host)
18
11
 
19
12
  # we've never seen this host before, so just automatically add the key.
20
13
  # not the most secure option (since the first hit might be the one that
@@ -22,85 +15,36 @@ module Net
22
15
  # fingerprint, this is a reasonable compromise between usability and
23
16
  # security.
24
17
  if matches.empty?
25
- add_key(arguments)
18
+ Net::SSH::KnownHosts.add(host, arguments[:key])
26
19
  return true
27
20
  end
28
21
 
29
22
  # If we found any matches, check to see that the key type and
30
23
  # blob also match.
31
- found = matches.any? do |item|
32
- item[:type] == arguments[:key].ssh_type &&
33
- item[:key] == arguments[:key_blob]
34
- end
24
+ found = matches.any? do |key|
25
+ key.ssh_type == arguments[:key].ssh_type &&
26
+ key.to_blob == arguments[:key].to_blob
27
+ end
35
28
 
36
29
  # If a match was found, return true. Otherwise, raise an exception
37
30
  # indicating that the key was not recognized.
38
- found || process_cache_miss(arguments)
31
+ found || process_cache_miss(host, arguments)
39
32
  end
40
33
 
41
34
  private
42
35
 
43
- def process_cache_miss(args)
44
- exception = HostKeyMismatch.new("fingerprint #{args[:fingerprint]} does not match for #{args[:peer][:host]}")
36
+ def process_cache_miss(host, args)
37
+ exception = HostKeyMismatch.new("fingerprint #{args[:fingerprint]} does not match for #{host.join(',')}")
45
38
  exception.data = args
46
- exception.callback = Proc.new { add_key(args) }
39
+ exception.callback = Proc.new { Net::SSH::KnownHosts.add(host, args[:key]) }
47
40
  raise exception
48
41
  end
49
42
 
50
- def home_directory
51
- ENV['HOME'] ||
52
- (ENV['HOMEPATH'] && "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}") ||
53
- "/"
54
- end
55
-
56
- def user_key_file
57
- @user_key_file ||= "#{home_directory}/.ssh/known_hosts"
58
- end
59
-
60
- def add_key(args)
61
- keys << { :host => args[:peer][:host], :port => args[:peer][:port], :ip => args[:peer][:ip], :type => args[:key].ssh_type, :key => args[:key_blob] }
62
-
63
- key_directory = File.dirname(user_key_file)
64
- Dir.mkdir(key_directory, 0700) if !File.exists?(key_directory)
65
-
66
- File.open(user_key_file, "a") do |f|
67
- host = args[:peer][:host]
68
- host = "[#{host}]:#{args[:peer][:port]}" if host && args[:peer][:port] != 22
69
-
70
- ip = args[:peer][:ip]
71
- ip = nil if ip == "127.0.0.1" || ip == "::1"
72
-
73
- host = [host, ip].compact.join(",")
74
- f.puts "%s %s %s" % [host, args[:key].ssh_type, [args[:key_blob]].pack("m*").gsub(/\s/, "")]
75
- end
76
- end
77
-
78
- def keys
79
- @keys ||= begin
80
- list = []
81
- list.concat(load_keys_from(user_key_file)) if File.exist?(user_key_file)
82
- list
83
- end
84
- end
85
-
86
- def load_keys_from(path)
87
- File.readlines(path).map do |line|
88
- host, type, key = line.chomp.split
89
- host, address = host.split(/,/)
90
-
91
- if address.nil? && host =~ /^\d+\.\d+\.\d+\.\d+$/
92
- host, address = address, host
93
- end
94
-
95
- if host
96
- host, port = host.split(/:/, 2)
97
- host = host.gsub(/[\[\]]/, "")
98
- end
99
-
100
- key = key.unpack("m*").first
101
-
102
- { :host => host, :ip => address, :port => port, :type => type, :key => key }
103
- end
43
+ def canonize(peer)
44
+ hosts = []
45
+ hosts << Net::SSH::KnownHosts.canonize(peer[:host], peer[:port])
46
+ hosts << Net::SSH::KnownHosts.canonize(peer[:ip], peer[:port])
47
+ hosts.compact
104
48
  end
105
49
  end
106
50
 
@@ -0,0 +1,96 @@
1
+ require 'strscan'
2
+ require 'net/ssh/transport/ossl/buffer'
3
+ require 'net/ssh/util/openssl'
4
+
5
+ module Net; module SSH
6
+ class KnownHosts
7
+ class <<self
8
+ def canonize(location, port)
9
+ value = location
10
+ value = "[#{value}]:#{port}" if port && port != 22
11
+ value
12
+ end
13
+
14
+ def search_for(host)
15
+ search_in(hostfile_locations, host)
16
+ end
17
+
18
+ def add(host, key)
19
+ hostfile_locations.each do |file|
20
+ begin
21
+ KnownHosts.new(file).add(host, key)
22
+ return
23
+ rescue SystemCallError
24
+ # try the next hostfile
25
+ end
26
+ end
27
+ end
28
+
29
+ def search_in(files, host)
30
+ files.map { |file| KnownHosts.new(file).keys_for(host) }.flatten
31
+ end
32
+
33
+ def hostfile_locations
34
+ @hostfile_locations ||= [
35
+ "#{home_directory}/.ssh/known_hosts",
36
+ "#{home_directory}/.ssh/known_hosts2",
37
+ "/etc/ssh/ssh_known_hosts",
38
+ "/etc/ssh/ssh_known_hosts2"
39
+ ]
40
+ end
41
+
42
+ def home_directory
43
+ ENV['HOME'] ||
44
+ (ENV['HOMEPATH'] && "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}") ||
45
+ "/"
46
+ end
47
+ end
48
+
49
+
50
+ attr_reader :source
51
+
52
+ def initialize(source)
53
+ @source = source
54
+ end
55
+
56
+ def keys_for(host)
57
+ keys = []
58
+ hosts = Array(host)
59
+
60
+ File.open(source) do |file|
61
+ scanner = StringScanner.new("")
62
+ file.each_line do |line|
63
+ scanner.string = line
64
+
65
+ scanner.skip(/\s*/)
66
+ next if scanner.match?(/$|#/)
67
+
68
+ hostlist = scanner.scan(/\S+/)
69
+ next if (hostlist.split(/,/) & hosts).empty?
70
+
71
+ scanner.skip(/\s*/)
72
+ type = scanner.scan(/\S+/)
73
+ scanner.skip(/\s*/)
74
+ blob = scanner.rest.unpack("m*").first
75
+ keys << Net::SSH::Transport::OSSL::Buffer.new(blob).read_key
76
+ end
77
+ end
78
+
79
+ keys
80
+ rescue SystemCallError
81
+ return []
82
+ end
83
+
84
+ def add(host, key)
85
+ dir = File.dirname(source)
86
+ Dir.mkdir(dir, 0700) if !File.exists?(dir)
87
+
88
+ File.open(source, "a") do |file|
89
+ buffer = Net::SSH::Transport::OSSL::Buffer.new
90
+ buffer.write_key(key)
91
+ blob = [buffer.to_s].pack("m*").gsub(/\s/, "")
92
+ file.puts "#{Array(host).join(',')} #{key.ssh_type} #{blob}"
93
+ end
94
+ end
95
+ end
96
+ end; end