Class: HrrRbSsh::Transport::Receiver

Inherits:
Object
  • Object
show all
Includes:
Loggable
Defined in:
lib/hrr_rb_ssh/transport/receiver.rb

Instance Attribute Summary

Attributes included from Loggable

#log_key, #logger

Instance Method Summary collapse

Methods included from Loggable

#log_debug, #log_error, #log_fatal, #log_info, #log_warn

Constructor Details

#initialize(logger: nil) ⇒ Receiver

Returns a new instance of Receiver.



11
12
13
# File 'lib/hrr_rb_ssh/transport/receiver.rb', line 11

def initialize logger: nil
  self.logger = logger
end

Instance Method Details

#depacketize(transport, packet) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/hrr_rb_ssh/transport/receiver.rb', line 15

def depacketize transport, packet
  packet_length_field_length  = 4
  padding_length_field_length = 1

  packet_length           = packet[0,4].unpack("N")[0]
  padding_length          = packet[4,1].unpack("C")[0]
  deflated_payload_length = packet_length - padding_length_field_length - padding_length
  deflated_payload        = packet[packet_length_field_length + padding_length_field_length, deflated_payload_length]
  payload                 = transport.incoming_compression_algorithm.inflate deflated_payload

  payload
end

#receive(transport) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/hrr_rb_ssh/transport/receiver.rb', line 65

def receive transport
  unencrypted_packet = receive_packet transport
  payload            = depacketize transport, unencrypted_packet
  mac                = receive_mac transport

  raise if mac != transport.incoming_mac_algorithm.compute( transport.incoming_sequence_number.sequence_number, unencrypted_packet )

  transport.incoming_sequence_number.increment

  payload
end

#receive_mac(transport) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'lib/hrr_rb_ssh/transport/receiver.rb', line 55

def receive_mac transport
  mac_length = transport.incoming_mac_algorithm.digest_length
  mac = transport.io.read mac_length
  if (mac == nil) || (mac.length != mac_length)
    log_warn { "IO is EOF" }
    raise EOFError
  end
  mac
end

#receive_packet(transport) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/hrr_rb_ssh/transport/receiver.rb', line 28

def receive_packet transport
  packet_length_field_length = 4
  minimum_block_size         = 8

  encrypted_packet   = Array.new
  unencrypted_packet = Array.new

  block_size = [transport.incoming_encryption_algorithm.block_size, minimum_block_size].max
  encrypted_packet.push transport.io.read(block_size)
  if (encrypted_packet.last == nil) || (encrypted_packet.last.length != block_size)
    log_warn { "IO is EOF" }
    raise EOFError
  end
  unencrypted_packet.push transport.incoming_encryption_algorithm.decrypt(encrypted_packet.last)

  packet_length           = unencrypted_packet.last[0,4].unpack("N")[0]
  following_packet_length = packet_length_field_length + packet_length - block_size
  encrypted_packet.push transport.io.read(following_packet_length)
  if (encrypted_packet.last == nil) || (encrypted_packet.last.length != following_packet_length)
    log_warn { "IO is EOF" }
    raise EOFError
  end
  unencrypted_packet.push transport.incoming_encryption_algorithm.decrypt(encrypted_packet.last)

  unencrypted_packet.join
end