CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/proto/quake/message.rb
Views: 11704
1
# -*- coding: binary -*-
2
3
module Rex
4
module Proto
5
##
6
#
7
# Quake 3 protocol, taken from ftp://ftp.idsoftware.com/idstuff/quake3/docs/server.txt
8
#
9
##
10
module Quake::Message
11
HEADER = 0xFFFFFFFF
12
13
def decode_message(message)
14
# minimum size is header (4) + <command> + <stuff>
15
return if message.length < 7
16
header = message.unpack('N')[0]
17
return if header != HEADER
18
message[4, message.length]
19
end
20
21
def encode_message(payload)
22
[HEADER].pack('N') + payload
23
end
24
25
def getstatus
26
encode_message('getstatus')
27
end
28
29
def getinfo
30
encode_message('getinfo')
31
end
32
33
def decode_infostring(infostring)
34
# decode an "infostring", which is just a (supposedly) quoted string of tokens separated
35
# by backslashes, generally terminated with a newline
36
token_re = /([^\\]+)\\([^\\]+)/
37
return nil unless infostring =~ token_re
38
# remove possibly present leading/trailing double quote
39
infostring.gsub!(/(?:^"|"$)/, '')
40
# remove the trailing \n, if present
41
infostring.gsub!(/\n$/, '')
42
# split on backslashes and group into key value pairs
43
infohash = {}
44
infostring.scan(token_re).each do |kv|
45
infohash[kv.first] = kv.last
46
end
47
infohash
48
end
49
50
def decode_response(message, type)
51
resp = decode_message(message)
52
if /^print\n(?<error>.*)\n?/m =~ resp
53
# XXX: is there a better exception to throw here?
54
fail ::ArgumentError, "#{type} error: #{error}"
55
# why doesn't this work?
56
# elsif /^#{type}Response\n(?<infostring>.*)/m =~ resp
57
elsif resp =~ /^#{type}Response\n(.*)/m
58
decode_infostring(Regexp.last_match(1))
59
else
60
nil
61
end
62
end
63
64
def decode_status(message)
65
decode_response(message, 'status')
66
end
67
68
def decode_info(message)
69
decode_response(message, 'info')
70
end
71
end
72
end
73
end
74
75