net-ssh 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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