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/net/dns/names/names.rb
Views: 11655
1
# -*- coding: binary -*-
2
module Net # :nodoc:
3
module DNS
4
5
module Names # :nodoc: all
6
7
INT16SZ = 2
8
9
# Expand a compressed name in a DNS Packet object. Please
10
# see RFC1025 for an explanation of how the compression
11
# in DNS packets works, how may it be useful and how should
12
# be handled.
13
#
14
# This method accept two parameters: a raw packet data and an
15
# offset, which indicates the point in the packet in which the
16
# parsing has arrived.
17
#
18
def dn_expand(packet,offset)
19
name = ""
20
packetlen = packet.size
21
while true
22
raise ExpandError, "offset is greater than packet length!" if packetlen < (offset+1)
23
len = packet.unpack("@#{offset} C")[0]
24
25
if len == 0
26
offset += 1
27
break
28
elsif (len & 0xC0) == 0xC0
29
raise ExpandError, "Packet ended before offset expand" if packetlen < (offset+INT16SZ)
30
ptr = packet.unpack("@#{offset} n")[0]
31
ptr &= 0x3FFF
32
name2 = dn_expand(packet,ptr)[0]
33
raise ExpandError, "Packet is malformed!" if name2 == nil
34
name += name2
35
offset += INT16SZ
36
break
37
else
38
offset += 1
39
raise ExpandError, "No expansion found" if packetlen < (offset+len)
40
elem = packet[offset..offset+len-1]
41
name += "#{elem}."
42
offset += len
43
end
44
end
45
return [name,offset] # name.chomp(".") if trailing dot has to be omitted
46
end
47
48
def pack_name(name)
49
if name.size > 255
50
raise ArgumentError, "Name data cannot exceed 255 chars"
51
end
52
arr = name.split(".")
53
str = ""
54
arr.each do |elem|
55
if elem.size > 63
56
raise ArgumentError, "Label data cannot exceed 63 chars"
57
end
58
str += [elem.size,elem].pack("Ca*")
59
end
60
str += [0].pack("C")
61
str
62
end
63
64
def names_array(name)
65
arr = name.split(".")
66
ar = []
67
string = ""
68
arr.size.times do |i|
69
x = i+1
70
elem = arr[-x]
71
len = elem.size
72
string = ((string.reverse)+([len,elem].pack("Ca*")).reverse).reverse
73
ar.unshift(string)
74
end
75
return ar
76
end
77
78
def dn_comp(name,offset,compnames)
79
names = {}
80
ptr = 0
81
str = ""
82
arr = names_array(name)
83
arr.each do |entry|
84
if compnames.has_key?(entry)
85
ptr = 0xC000 | compnames[entry]
86
str += [ptr].pack("n")
87
offset += INT16SZ
88
break
89
else
90
len = entry.unpack("C")[0]
91
elem = entry[1..len]
92
str += [len,elem].pack("Ca*")
93
names.update({"#{entry}" => offset})
94
offset += len
95
end
96
end
97
return str,offset,names
98
end
99
100
def valid?(name)
101
if name =~ /^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/i
102
return name
103
else
104
raise ArgumentError, "Invalid FQDN: #{name}"
105
end
106
end
107
108
end # module Names
109
end # module DNS
110
end # module Net
111
112
class ExpandError < StandardError # :nodoc:
113
end
114
115