Class: Net::SSH::Transport::Algorithms

Inherits:
Object
  • Object
show all
Includes:
Loggable, Constants
Defined in:
lib/net/ssh/transport/algorithms.rb

Overview

Implements the higher-level logic behind an SSH key-exchange. It handles both the initial exchange, as well as subsequent re-exchanges (as needed). It also encapsulates the negotiation of the algorithms, and provides a single point of access to the negotiated algorithms.

You will never instantiate or reference this directly. It is used internally by the transport layer.

Constant Summary collapse

ALGORITHMS =

Define the default algorithms, in order of preference, supported by Net::SSH.

{
  :host_key    => %w(ssh-rsa ssh-dss),
  :kex         => %w(diffie-hellman-group-exchange-sha1
                     diffie-hellman-group1-sha1),
  :encryption  => %w(aes128-cbc 3des-cbc blowfish-cbc cast128-cbc
                     aes192-cbc aes256-cbc [email protected]
                     idea-cbc none arcfour128 arcfour256),
  :hmac        => %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 none),
  :compression => %w(none [email protected] zlib),
  :language    => %w() 
}

Constants included from Constants

Constants::DEBUG, Constants::DISCONNECT, Constants::IGNORE, Constants::KEXDH_INIT, Constants::KEXDH_REPLY, Constants::KEXINIT, Constants::NEWKEYS, Constants::SERVICE_ACCEPT, Constants::SERVICE_REQUEST, Constants::UNIMPLEMENTED

Instance Attribute Summary collapse

Attributes included from Loggable

#logger

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Loggable

#debug, #error, #fatal, #info, #lwarn

Constructor Details

#initialize(session, options = {}) ⇒ Algorithms

Instantiates a new Algorithms object, and prepares the hash of preferred algorithms based on the options parameter and the ALGORITHMS constant.



89
90
91
92
93
94
95
96
97
# File 'lib/net/ssh/transport/algorithms.rb', line 89

def initialize(session, options={})
  @session = session
  @logger = session.logger
  @options = options
  @algorithms = {}
  @pending = @initialized = false
  @client_packet = @server_packet = nil
  prepare_preferred_algorithms!
end

Instance Attribute Details

#algorithms ⇒ Object (readonly)

The hash of algorithms preferred by the client, which will be told to the server during algorithm negotiation.



75
76
77
# File 'lib/net/ssh/transport/algorithms.rb', line 75

def algorithms
  @algorithms
end

#compression_client ⇒ Object (readonly)

The type of compression to use to compress packets being sent by the client.



62
63
64
# File 'lib/net/ssh/transport/algorithms.rb', line 62

def compression_client
  @compression_client
end

#compression_server ⇒ Object (readonly)

The type of compression to use to decompress packets arriving from the server.



65
66
67
# File 'lib/net/ssh/transport/algorithms.rb', line 65

def compression_server
  @compression_server
end

#encryption_client ⇒ Object (readonly)

The type of the cipher to use to encrypt packets sent from the client to the server.



50
51
52
# File 'lib/net/ssh/transport/algorithms.rb', line 50

def encryption_client
  @encryption_client
end

#encryption_server ⇒ Object (readonly)

The type of the cipher to use to decrypt packets arriving from the server.



53
54
55
# File 'lib/net/ssh/transport/algorithms.rb', line 53

def encryption_server
  @encryption_server
end

#hmac_client ⇒ Object (readonly)

The type of HMAC to use to sign packets sent by the client.



56
57
58
# File 'lib/net/ssh/transport/algorithms.rb', line 56

def hmac_client
  @hmac_client
end

#hmac_server ⇒ Object (readonly)

The type of HMAC to use to validate packets arriving from the server.



59
60
61
# File 'lib/net/ssh/transport/algorithms.rb', line 59

def hmac_server
  @hmac_server
end

#host_key ⇒ Object (readonly)

The type of host key that will be used for this session.



46
47
48
# File 'lib/net/ssh/transport/algorithms.rb', line 46

def host_key
  @host_key
end

#kex ⇒ Object (readonly)

The kex algorithm to use settled on between the client and server.



43
44
45
# File 'lib/net/ssh/transport/algorithms.rb', line 43

def kex
  @kex
end

#language_client ⇒ Object (readonly)

The language that will be used in messages sent by the client.



68
69
70
# File 'lib/net/ssh/transport/algorithms.rb', line 68

def language_client
  @language_client
end

#language_server ⇒ Object (readonly)

The language that will be used in messages sent from the server.



71
72
73
# File 'lib/net/ssh/transport/algorithms.rb', line 71

def language_server
  @language_server
end

#options ⇒ Object (readonly)

The hash of options used to initialize this object



40
41
42
# File 'lib/net/ssh/transport/algorithms.rb', line 40

def options
  @options
end

#session ⇒ Object (readonly)

The underlying transport layer session that supports this object



37
38
39
# File 'lib/net/ssh/transport/algorithms.rb', line 37

def session
  @session
end

#session_id ⇒ Object (readonly)

The session-id for this session, as decided during the initial key exchange.



78
79
80
# File 'lib/net/ssh/transport/algorithms.rb', line 78

def session_id
  @session_id
end

Class Method Details

.allowed_packet?(packet) ⇒ Boolean

Returns true if the given packet can be processed during a key-exchange.

Returns:

  • (Boolean)


81
82
83
84
85
# File 'lib/net/ssh/transport/algorithms.rb', line 81

def self.allowed_packet?(packet)
  ( 1.. 4).include?(packet.type) ||
  ( 6..19).include?(packet.type) ||
  (21..49).include?(packet.type)
end

Instance Method Details

#[](key) ⇒ Object

A convenience method for accessing the list of preferred types for a specific algorithm (see #algorithms).



126
127
128
# File 'lib/net/ssh/transport/algorithms.rb', line 126

def [](key)
  algorithms[key]
end

#accept_kexinit(packet) ⇒ Object

Called by the transport layer when a KEXINIT packet is recieved, indicating that the server wants to exchange keys. This can be spontaneous, or it can be in response to a client-initiated rekey request (see #rekey!). Either way, this will block until the key exchange completes.



113
114
115
116
117
118
119
120
121
122
# File 'lib/net/ssh/transport/algorithms.rb', line 113

def accept_kexinit(packet)
  info { "got KEXINIT from server" }
  @server_data = parse_server_algorithm_packet(packet)
  @server_packet = @server_data[:raw]
  if !pending?
    send_kexinit
  else
    proceed!
  end
end

#allow?(packet) ⇒ Boolean

Returns true if no exchange is pending, and otherwise returns true or false depending on whether the given packet is of a type that is allowed during a key exchange.

Returns:

  • (Boolean)


142
143
144
# File 'lib/net/ssh/transport/algorithms.rb', line 142

def allow?(packet)
  !pending? || Algorithms.allowed_packet?(packet)
end

#initialized? ⇒ Boolean

Returns true if the algorithms have been negotiated at all.

Returns:

  • (Boolean)


147
148
149
# File 'lib/net/ssh/transport/algorithms.rb', line 147

def initialized?
  @initialized
end

#pending? ⇒ Boolean

Returns true if a key-exchange is pending. This will be true from the moment either the client or server requests the key exchange, until the exchange completes. While an exchange is pending, only a limited number of packets are allowed, so event processing essentially stops during this period.

Returns:

  • (Boolean)


135
136
137
# File 'lib/net/ssh/transport/algorithms.rb', line 135

def pending?
  @pending
end

#rekey! ⇒ Object

Request a rekey operation. This will return immediately, and does not actually perform the rekey operation. It does cause the session to change state, however--until the key exchange finishes, no new packets will be processed.



103
104
105
106
107
# File 'lib/net/ssh/transport/algorithms.rb', line 103

def rekey!
  @client_packet = @server_packet = nil
  @initialized = false
  send_kexinit
end