Module: Rex::Proto::Quake::Message

Included in:
Rex::Proto::Quake
Defined in:
lib/rex/proto/quake/message.rb

Constant Summary collapse

HEADER =
0xFFFFFFFF

Instance Method Summary collapse

Instance Method Details

#decode_info(message) ⇒ Object



68
69
70
# File 'lib/rex/proto/quake/message.rb', line 68

def decode_info(message)
  decode_response(message, 'info')
end

#decode_infostring(infostring) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rex/proto/quake/message.rb', line 33

def decode_infostring(infostring)
  # decode an "infostring", which is just a (supposedly) quoted string of tokens separated
  # by backslashes, generally terminated with a newline
  token_re = /([^\\]+)\\([^\\]+)/
  return nil unless infostring =~ token_re
  # remove possibly present leading/trailing double quote
  infostring.gsub!(/(?:^"|"$)/, '')
  # remove the trailing \n, if present
  infostring.gsub!(/\n$/, '')
  # split on backslashes and group into key value pairs
  infohash = {}
  infostring.scan(token_re).each do |kv|
    infohash[kv.first] = kv.last
  end
  infohash
end

#decode_message(message) ⇒ Object



13
14
15
16
17
18
19
# File 'lib/rex/proto/quake/message.rb', line 13

def decode_message(message)
  # minimum size is header (4) + <command> + <stuff>
  return if message.length < 7
  header = message.unpack('N')[0]
  return if header != HEADER
  message[4, message.length]
end

#decode_response(message, type) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/rex/proto/quake/message.rb', line 50

def decode_response(message, type)
  resp = decode_message(message)
  if /^print\n(?<error>.*)\n?/m =~ resp
    # XXX: is there a better exception to throw here?
    fail ::ArgumentError, "#{type} error: #{error}"
  # why doesn't this work?
  # elsif /^#{type}Response\n(?<infostring>.*)/m =~ resp
  elsif resp =~ /^#{type}Response\n(.*)/m
    decode_infostring(Regexp.last_match(1))
  else
    nil
  end
end

#decode_status(message) ⇒ Object



64
65
66
# File 'lib/rex/proto/quake/message.rb', line 64

def decode_status(message)
  decode_response(message, 'status')
end

#encode_message(payload) ⇒ Object



21
22
23
# File 'lib/rex/proto/quake/message.rb', line 21

def encode_message(payload)
  [HEADER].pack('N') + payload
end

#getinfoObject



29
30
31
# File 'lib/rex/proto/quake/message.rb', line 29

def getinfo
  encode_message('getinfo')
end

#getstatusObject



25
26
27
# File 'lib/rex/proto/quake/message.rb', line 25

def getstatus
  encode_message('getstatus')
end