Class: StickyElephant::Handler::Handshake

Inherits:
Base
  • Object
show all
Defined in:
lib/sticky_elephant/handler/handshake.rb

Instance Method Summary collapse

Methods inherited from Base

#initialize

Constructor Details

This class inherits a constructor from StickyElephant::Handler::Base

Instance Method Details

#keyObject



70
71
72
# File 'lib/sticky_elephant/handler/handshake.rb', line 70

def key
  0xEFBEADDE
end

#negotiate_authObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/sticky_elephant/handler/handshake.rb', line 39

def negotiate_auth
  socket.write("R")
  socket.write(with_length_bytes("\x00\x00\x00\x03"))
  IO.select([socket], nil, nil, 60)
  begin
    password_response = socket.readpartial(1024)
  rescue EOFError
    sleep 0.01
    retry
  end
  password = password_response.bytes[5..-2].map(&:chr).join
  log(msg: "Password: " + password, level: :info)
  socket.write("R")
  socket.write(with_length_bytes("\x00\x00\x00\x00"))
  password
end

#payload_hashObject



34
35
36
37
# File 'lib/sticky_elephant/handler/handshake.rb', line 34

def payload_hash
  payload_arr = payload.raw.pack('C*')[8..-1].split("\x00")
  Hash[*payload_arr.flatten(1)].map {|pair| [pair.first.to_sym, pair.last] }.to_h
end

#pidObject



66
67
68
# File 'lib/sticky_elephant/handler/handshake.rb', line 66

def pid
  666
end

#processObject



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/sticky_elephant/handler/handshake.rb', line 4

def process
  log(msg: 'shaking hands', level: :debug)
  hash = connection_hash.merge(payload_hash)
  password = begin
               negotiate_auth
             rescue
               report_connection(hash)
               log(level: :error, msg: "#{e}")
               'NONE PROVIDED'
             end
  report_connection(hash.merge(password: password))

  write_parameter_status("application_name", hash[:application_name])
  write_parameter_status("client_encoding", hash[:client_encoding])
  write_parameter_status("DateStyle", "ISO, MDY")
  write_parameter_status("integer_datetimes", "on")
  write_parameter_status("IntervalStyle", "postgres")
  write_parameter_status("is_superuser", "on")
  write_parameter_status("server_encoding", hash[:client_encoding])
  write_parameter_status("server_version", "9.5.5")
  write_parameter_status("session_authorization", hash[:user])
  write_parameter_status("standard_conforming_strings", "on")
  write_parameter_status("TimeZone", "US/Pacific")
  write_key_data
  response_string = [0x4b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x56,
                     0x7b, 0x27, 0x50, 0xb7, 0x0c, 0x5a, 0x00, 0x00,
                     0x00, 0x05, 0x49].map(&:chr).join
  socket.write(response_string)
end

#write_key_dataObject



56
57
58
59
60
61
62
63
64
# File 'lib/sticky_elephant/handler/handshake.rb', line 56

def write_key_data
  socket.write("K")
  socket.write(
    with_length_bytes(
      [pid].pack('N') +
      [key].pack('N')
    )
  )
end

#write_parameter_status(key, value) ⇒ Object



74
75
76
77
# File 'lib/sticky_elephant/handler/handshake.rb', line 74

def write_parameter_status(key, value)
  to_write = "S" + with_length_bytes("#{key}\x00#{value}\x00")
  socket.write(to_write)
end