pNet-DNS 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. data/README +68 -0
  2. data/lib/Net/DNS.rb +879 -0
  3. data/lib/Net/DNS/Header.rb +303 -0
  4. data/lib/Net/DNS/Nameserver.rb +601 -0
  5. data/lib/Net/DNS/Packet.rb +851 -0
  6. data/lib/Net/DNS/Question.rb +117 -0
  7. data/lib/Net/DNS/RR.rb +630 -0
  8. data/lib/Net/DNS/RR/A.rb +103 -0
  9. data/lib/Net/DNS/RR/AAAA.rb +147 -0
  10. data/lib/Net/DNS/RR/AFSDB.rb +114 -0
  11. data/lib/Net/DNS/RR/CERT.rb +191 -0
  12. data/lib/Net/DNS/RR/CNAME.rb +89 -0
  13. data/lib/Net/DNS/RR/DNAME.rb +84 -0
  14. data/lib/Net/DNS/RR/EID.rb +70 -0
  15. data/lib/Net/DNS/RR/HINFO.rb +108 -0
  16. data/lib/Net/DNS/RR/ISDN.rb +118 -0
  17. data/lib/Net/DNS/RR/LOC.rb +341 -0
  18. data/lib/Net/DNS/RR/MB.rb +92 -0
  19. data/lib/Net/DNS/RR/MG.rb +96 -0
  20. data/lib/Net/DNS/RR/MINFO.rb +109 -0
  21. data/lib/Net/DNS/RR/MR.rb +92 -0
  22. data/lib/Net/DNS/RR/MX.rb +124 -0
  23. data/lib/Net/DNS/RR/NAPTR.rb +182 -0
  24. data/lib/Net/DNS/RR/NIMLOC.rb +70 -0
  25. data/lib/Net/DNS/RR/NS.rb +100 -0
  26. data/lib/Net/DNS/RR/NSAP.rb +273 -0
  27. data/lib/Net/DNS/RR/NULL.rb +68 -0
  28. data/lib/Net/DNS/RR/OPT.rb +251 -0
  29. data/lib/Net/DNS/RR/PTR.rb +93 -0
  30. data/lib/Net/DNS/RR/PX.rb +131 -0
  31. data/lib/Net/DNS/RR/RP.rb +108 -0
  32. data/lib/Net/DNS/RR/RT.rb +115 -0
  33. data/lib/Net/DNS/RR/SOA.rb +195 -0
  34. data/lib/Net/DNS/RR/SPF.rb +46 -0
  35. data/lib/Net/DNS/RR/SRV.rb +153 -0
  36. data/lib/Net/DNS/RR/SSHFP.rb +190 -0
  37. data/lib/Net/DNS/RR/TKEY.rb +219 -0
  38. data/lib/Net/DNS/RR/TSIG.rb +358 -0
  39. data/lib/Net/DNS/RR/TXT.rb +162 -0
  40. data/lib/Net/DNS/RR/UNKNOWN.rb +76 -0
  41. data/lib/Net/DNS/RR/X25.rb +90 -0
  42. data/lib/Net/DNS/Resolver.rb +2090 -0
  43. data/lib/Net/DNS/Resolver/Recurse.rb +478 -0
  44. data/lib/Net/DNS/Update.rb +189 -0
  45. data/test/custom.txt +4 -0
  46. data/test/resolv.conf +4 -0
  47. data/test/tc_escapedchars.rb +498 -0
  48. data/test/tc_header.rb +91 -0
  49. data/test/tc_inet6.rb +169 -0
  50. data/test/tc_misc.rb +137 -0
  51. data/test/tc_online.rb +236 -0
  52. data/test/tc_packet.rb +174 -0
  53. data/test/tc_packet_unique_push.rb +126 -0
  54. data/test/tc_question.rb +49 -0
  55. data/test/tc_recurse.rb +69 -0
  56. data/test/tc_res_env.rb +59 -0
  57. data/test/tc_res_file.rb +55 -0
  58. data/test/tc_res_opt.rb +135 -0
  59. data/test/tc_resolver.rb +102 -0
  60. data/test/tc_rr-opt.rb +40 -0
  61. data/test/tc_rr-rrsort.rb +116 -0
  62. data/test/tc_rr-txt.rb +138 -0
  63. data/test/tc_rr-unknown.rb +95 -0
  64. data/test/tc_rr.rb +246 -0
  65. data/test/tc_tcp.rb +34 -0
  66. data/test/tc_tkey.rb +115 -0
  67. data/test/tc_update.rb +226 -0
  68. data/test/ts_netdns.rb +17 -0
  69. data/test/ts_offline.rb +32 -0
  70. data/test/ts_online.rb +33 -0
  71. metadata +119 -0
@@ -0,0 +1,358 @@
1
+ # The contents of this file are subject to the Mozilla
2
+ # Public Licence Version 1.1 (the "Licence"); you may
3
+ # not use this file except in compliance with the
4
+ # Licence. You may obtain a copy of the Licence at
5
+ # http://www.mozilla.org/MPL
6
+ # Software distributed under the Licence is distributed
7
+ # on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
8
+ # either express or implied. See the Licence of the
9
+ # specific language governing rights and limitations
10
+ # under the Licence.
11
+ # The Original Code is pNet::DNS.
12
+ # The Initial Developer of the Original Code is
13
+ # Nominet UK (www.nominet.org.uk). Portions created by
14
+ # Nominet UK are Copyright (c) Nominet UK 2006.
15
+ # All rights reserved.
16
+ require 'base64'
17
+ require "digest/md5"
18
+ module Net
19
+ module DNS
20
+ class RR
21
+ #= NAME
22
+ #
23
+ #Net::DNS::RR::TSIG - DNS TSIG resource record
24
+ #
25
+ #= DESCRIPTION
26
+ #
27
+ #Class for DNS Transaction Signature (TSIG) resource records.
28
+ #
29
+ #= BUGS
30
+ #
31
+ #This code is still under development. Use with caution on production
32
+ #systems.
33
+ #
34
+ #The time_signed and other_data fields should be 48-bit unsigned
35
+ #integers (RFC 2845, Sections 2.3 and 4.5.2). The current implementation
36
+ #ignores the upper 16 bits; this will cause problems for times later
37
+ #than 19 Jan 2038 03:14:07 UTC.
38
+ #
39
+ #The only builtin algorithm currently supported is
40
+ #HMAC-MD5.SIG-ALG.REG.INT. You can use other algorithms by supplying an
41
+ #appropriate sign_func.
42
+ #
43
+ #= COPYRIGHT
44
+ #
45
+ #Copyright (c) 2002 Michael Fuhr.
46
+ #
47
+ #Portions Copyright (c) 2002-2004 Chris Reinhardt.
48
+ #
49
+ #All rights reserved. This program is free software; you may redistribute
50
+ #it and/or modify it under the same terms as Perl itself.
51
+ #
52
+ #= ACKNOWLEDGMENT
53
+ #
54
+ #Most of the code in the Net::DNS::RR::TSIG module was contributed
55
+ #by Chris Turbeville.
56
+ #
57
+ #Support for external signing functions was added by Andrew Tridgell.
58
+ #
59
+ #= SEE ALSO
60
+ #
61
+ #Net::DNS, Net::DNS::Resolver, Net::DNS::Packet,
62
+ #Net::DNS::Header, Net::DNS::Question, Net::DNS::RR,
63
+ #RFC 2845
64
+ class TSIG < RR
65
+ DEFAULT_ALGORITHM = "HMAC-MD5.SIG-ALG.REG.INT"
66
+ DEFAULT_FUDGE = 300
67
+
68
+ #Gets or sets the domain name that specifies the name of the algorithm.
69
+ #The only algorithm currently supported is HMAC-MD5.SIG-ALG.REG.INT.
70
+ #
71
+ # rr.algorithm=(algorithm_name)
72
+ # print "algorithm = ", rr.algorithm, "\n"
73
+ #
74
+ attr_accessor :algorithm
75
+
76
+ #Gets or sets the signing time as the number of seconds since 1 Jan 1970
77
+ #00:00:00 UTC.
78
+ #
79
+ #The default signing time is the current time.
80
+ #
81
+ # rr.time_signed=(time)
82
+ # print "time signed = ", rr.time_signed, "\n"
83
+ #
84
+ attr_accessor :time_signed
85
+
86
+ #Gets or sets the "fudge", i.e., the seconds of error permitted in the
87
+ #signing time.
88
+ #
89
+ #The default fudge is 300 seconds.
90
+ #
91
+ # rr.fudge=(60)
92
+ # print "fudge = ", rr.fudge, "\n"
93
+ #
94
+ attr_accessor :fudge
95
+
96
+ #Returns the number of octets in the message authentication code (MAC).
97
+ #The programmer must call a Net::DNS::Packet object's data method
98
+ #before this will return anything meaningful.
99
+ #
100
+ # print "MAC size = ", rr.mac_size, "\n"
101
+ #
102
+ attr_writer :mac_size
103
+
104
+ #Returns the message authentication code (MAC) as a string of hex
105
+ #characters. The programmer must call a Net::DNS::Packet object's
106
+ #data method before this will return anything meaningful.
107
+ #
108
+ # print "MAC = ", rr.mac, "\n"
109
+ #
110
+ attr_writer :mac
111
+
112
+ #Gets or sets the original message ID.
113
+ #
114
+ # rr.original_id(12345)
115
+ # print "original ID = ", rr.original_id, "\n"
116
+ #
117
+ attr_accessor :fudge, :original_id
118
+
119
+ #Returns the RCODE covering TSIG processing. Common values are
120
+ #NOERROR, BADSIG, BADKEY, and BADTIME. See RFC 2845 for details.
121
+ #
122
+ # print "error = ", rr.error, "\n"
123
+ #
124
+ attr_writer :error
125
+
126
+ #Returns the length of the Other Data. Should be zero unless the
127
+ #error is BADTIME.
128
+ #
129
+ # print "other len = ", rr.other_len, "\n"
130
+ #
131
+ attr_accessor :other_len
132
+
133
+ #Returns the Other Data. This field should be empty unless the
134
+ #error is BADTIME, in which case it will contain the server's
135
+ #time as the number of seconds since 1 Jan 1970 00:00:00 UTC.
136
+ #
137
+ # print "other data = ", rr.other_data, "\n"
138
+ #
139
+ attr_accessor :other_data
140
+
141
+ #This sets the signing function to be used for this TSIG record.
142
+ #
143
+ #The default signing function is HMAC-MD5.
144
+ #
145
+ # tsig.sign_func=(Proc.new {|key, data| return some_digest_algorithm(key, data)})
146
+ #
147
+ attr_accessor :sign_func
148
+ attr_accessor :key
149
+
150
+ def new_from_hash(values)
151
+ init_defaults
152
+ if (values.has_key?:key)
153
+ @key = values[:key]
154
+ end
155
+ if (values.has_key?:fudge)
156
+ @fudge = values[:fudge]
157
+ end
158
+ if (values.has_key?:algorithm)
159
+ @algorithm = values[:algorithm]
160
+ end
161
+ if (values.has_key?:mac_size)
162
+ @mac_size = values[:mac_size]
163
+ end
164
+ if (values.has_key?:mac)
165
+ @mac = values[:mac]
166
+ end
167
+ if (values.has_key?:other_len)
168
+ @other_len = values[:other_len]
169
+ end
170
+ if (values.has_key?:other_data)
171
+ @other_data = values[:other_data]
172
+ end
173
+ if (values.has_key?:original_id)
174
+ @original_id = values[:original_id]
175
+ end
176
+ if (values.has_key?:error)
177
+ @error = values[:error]
178
+ end
179
+ if (values.has_key?:sign_func)
180
+ @sign_func = values[:sign_func]
181
+ end
182
+ if (values.has_key?:time_signed)
183
+ @time_signed = values[:time_signed]
184
+ end
185
+ end
186
+
187
+ def new_from_data(data, offset)
188
+ if (@rdlength > 0)
189
+ @algorithm, offset = Net::DNS::Packet.dn_expand(data, offset)
190
+
191
+ time_high, time_low = data.unpack("\@#{offset} nN")
192
+ self.time_signed = time_low # bug
193
+ offset += Net::DNS::INT16SZ + Net::DNS::INT32SZ
194
+
195
+ @fudge, @mac_size = data.unpack("\@$offset nn")
196
+ offset += Net::DNS::INT16SZ + Net::DNS::INT16SZ
197
+
198
+ @mac = data[offset, @mac_size]
199
+ offset += @mac_size
200
+
201
+ @original_id, @error, @other_len = data.unpack("\@#{offset} nnn")
202
+ offset += Net::DNS::INT16SZ * 3
203
+
204
+ odata = data[offset, @other_len]
205
+ odata_high, odata_low = odata.unpack("nN")
206
+ @other_data = odata_low
207
+ end
208
+ end
209
+
210
+ def new_from_string(string)
211
+
212
+ if (string!=nil && (string =~ /^(.*)$/))
213
+ @key = $1
214
+ end
215
+
216
+ init_defaults
217
+ end
218
+
219
+ def init_defaults
220
+ @algorithm = DEFAULT_ALGORITHM
221
+ @time_signed = Time.now
222
+ @fudge = DEFAULT_FUDGE
223
+ @mac_size = 0
224
+ @mac = ""
225
+ @original_id = 0
226
+ @error = 0
227
+ @other_len = 0
228
+ @other_data = nil
229
+ @sign_func = lambda { |key, data|
230
+ # a signing function for the HMAC-MD5 algorithm. This can be overridden using
231
+ # the sign_func element
232
+ key.gsub!(/ /,"")
233
+ key = Base64::decode64(key)
234
+
235
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new("md5"), key, data)
236
+
237
+ # hmac = Digest::HMAC_MD5.new(key)
238
+ # hmac.add(data)
239
+
240
+ # hmac.digest
241
+ }
242
+
243
+ # RFC 2845 Section 2.3
244
+ rrclass = "ANY"
245
+ end
246
+
247
+ def error
248
+ rcode=0
249
+ error = @error
250
+
251
+ if (error!=nil)
252
+ rcode = Net::DNS::Rcodesbyval[error] || error
253
+ end
254
+
255
+ return rcode
256
+ end
257
+
258
+ def mac_size
259
+ return (@mac!=nil ? @mac : "").length
260
+ end
261
+
262
+ def mac
263
+ mac = @mac.unpack("H*") if @mac!=nil;
264
+ return mac;
265
+ end
266
+
267
+ def rdatastr
268
+ error = @error
269
+ error = "UNDEFINED" unless error!=nil
270
+
271
+ rdatastr=""
272
+
273
+ if (@algorithm!=nil)
274
+ rdatastr = "#{@algorithm}. #{error}";
275
+ if (@other_len > 0 && @other_data!=nil)
276
+ rdatastr += " #{@other_data}"
277
+ end
278
+ else
279
+ rdatastr = ""
280
+ end
281
+
282
+ return rdatastr
283
+ end
284
+
285
+ #Returns the packet packed according to RFC2845 in a form for signing. This
286
+ #is only needed if you want to supply an external signing function, such as is
287
+ #needed for TSIG-GSS.
288
+ #
289
+ # sigdata = tsig.sig_data(packet)
290
+ #
291
+ def sig_data(packet)
292
+ # return the data that needs to be signed/verified. This is useful for
293
+ # external TSIG verification routines
294
+ newpacket = Packet.new
295
+ sigdata = ""
296
+
297
+ newpacket.additional = []
298
+ newpacket.header = packet.header.clone
299
+ newpacket.additional = packet.additional.map {|i| i}
300
+ newpacket.additional.shift
301
+ newpacket.header.arcount-=1
302
+ newpacket.compnames = Hash.new
303
+
304
+ # Add the request MAC if present (used to validate responses).
305
+ sigdata += [@request_mac].pack("H*") if @request_mac
306
+
307
+ sigdata += newpacket.data
308
+
309
+ # Don't compress the record (key) name.
310
+ tmppacket = Net::DNS::Packet.new
311
+ sigdata += tmppacket.dn_comp(@name.downcase, 0)
312
+
313
+ sigdata += [Net::DNS.classesbyname(@rrclass.upcase())].pack("n")
314
+ sigdata += [@ttl].pack("N")
315
+
316
+ # Don't compress the algorithm name.
317
+ tmppacket.compnames = Hash.new
318
+ sigdata += tmppacket.dn_comp(@algorithm.downcase, 0)
319
+
320
+ sigdata += [0, @time_signed].pack("nN") # bug
321
+ sigdata += [@fudge].pack("n")
322
+ sigdata += [@error, @other_len].pack("nn")
323
+
324
+ sigdata += [0, @other_data].pack("nN") if @other_data!=nil
325
+
326
+ return sigdata
327
+ end
328
+
329
+ def rr_rdata(packet, offset)
330
+ rdata = ""
331
+
332
+ if (@key != nil)
333
+ # form the data to be signed
334
+ sigdata = sig_data(packet)
335
+
336
+ # and call the signing function
337
+ @mac = @sign_func.call(@key, sigdata)
338
+ @mac_size = @mac.length
339
+
340
+ # construct the signed TSIG record
341
+ packet.compnames = Hash.new
342
+ rdata += packet.dn_comp(@algorithm, 0)
343
+
344
+ rdata += [0, @time_signed].pack("nN") # bug
345
+ rdata += [@fudge, @mac_size].pack("nn")
346
+ rdata += @mac
347
+
348
+ rdata += [packet.header.id,@error,@other_len].pack("nnn")
349
+
350
+ rdata += [0, @other_data].pack("nN") if @other_data!=nil
351
+ end
352
+
353
+ return rdata
354
+ end
355
+ end
356
+ end
357
+ end
358
+ end
@@ -0,0 +1,162 @@
1
+ # The contents of this file are subject to the Mozilla
2
+ # Public Licence Version 1.1 (the "Licence"); you may
3
+ # not use this file except in compliance with the
4
+ # Licence. You may obtain a copy of the Licence at
5
+ # http://www.mozilla.org/MPL
6
+ # Software distributed under the Licence is distributed
7
+ # on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
8
+ # either express or implied. See the Licence of the
9
+ # specific language governing rights and limitations
10
+ # under the Licence.
11
+ # The Original Code is pNet::DNS.
12
+ # The Initial Developer of the Original Code is
13
+ # Nominet UK (www.nominet.org.uk). Portions created by
14
+ # Nominet UK are Copyright (c) Nominet UK 2006.
15
+ # All rights reserved.
16
+ require 'shellwords'
17
+ module Net
18
+ module DNS
19
+ class RR
20
+ #= NAME
21
+ #
22
+ #Net::DNS::RR::TXT - DNS TXT resource record
23
+ #
24
+ #= DESCRIPTION
25
+ #
26
+ #Class for DNS Text (TXT) resource records.
27
+ #
28
+ #= FEATURES
29
+ #
30
+ #The RR class accepts semi-colons as a start of a comment. This is
31
+ #to allow the RR.pm to deal with RFC1035 specified zonefile format.
32
+ #
33
+ #For some applications of the TXT RR the semicolon is relevant, you
34
+ #will need to escape it on input.
35
+ #
36
+ #Also note that you should specify the several character strings
37
+ #separately. The easiest way to do so is to include the whole argument
38
+ #in single quotes and the several character strings in double
39
+ #quotes. Double quotes inside the character strings will need to be
40
+ #escaped.
41
+ #
42
+ # TXTrr=Net::DNS::RR.create('txt2.t.net-dns.org. 60 IN
43
+ # TXT "Test1 \" \; more stuff" "Test2"')
44
+ #
45
+ #would result in
46
+ # TXTrr.char_str_list())[0] containing 'Test1 " ; more stuff'
47
+ #and
48
+ # TXTrr.char_str_list())[1] containing 'Test2'
49
+ #
50
+ #
51
+ #= COPYRIGHT
52
+ #
53
+ #Copyright (c) 1997-2002 Michael Fuhr.
54
+ #
55
+ #Portions Copyright (c) 2002-2004 Chris Reinhardt.
56
+ #Portions Copyright (c) 2005 Olaf Kolkman (NLnet Labs)
57
+ #
58
+ #All rights reserved. This program is free software; you may redistribute
59
+ #it and/or modify it under the same terms as Perl itself.
60
+ #
61
+ #= SEE ALSO
62
+ #
63
+ #Net::DNS, Net::DNS::Resolver, Net::DNS::Packet,
64
+ #<Net::DNS::Header, Net::DNS::Question, Net::DNS::RR,
65
+ #RFC 1035 Section 3.3.14
66
+ class TXT < RR
67
+ # attr_accessor :char_str_list
68
+ def new_from_data(data, offset)
69
+ init_char_str_list()
70
+ if (@rdlength == nil || @rdlength == 0)
71
+ return
72
+ end
73
+ endpos = offset + @rdlength
74
+
75
+ while (offset < endpos)
76
+ strlen = data.unpack("\@#{offset} C")[0]
77
+ offset += 1
78
+
79
+ char_str = data[offset,strlen]
80
+ offset += strlen
81
+
82
+ @char_str_list.push(char_str)
83
+ end
84
+ end
85
+
86
+ def new_from_hash(values)
87
+ if (values.has_key?:txtdata)
88
+ _build_char_str_list(values[:txtdata])
89
+ end
90
+ end
91
+
92
+ def new_from_string (rdata_string)
93
+ _build_char_str_list(rdata_string)
94
+ end
95
+
96
+ #Returns the descriptive text as a single string, regardless of actual
97
+ #number of <character-string> elements. Of questionable value. Should
98
+ #be deprecated.
99
+ #
100
+ #Use txt.rdatastr() or txt.char_str_list() instead.
101
+ #
102
+ def txtdata
103
+ return @char_str_list.join(' ')
104
+ end
105
+
106
+ def rdatastr
107
+ if (defined?@char_str_list)
108
+ temp = @char_str_list.map {|str|
109
+ str.gsub(/"/, '\\"')
110
+ %<"#{str}">
111
+ }
112
+ return temp.join(' ')
113
+ end
114
+ return ''
115
+ end
116
+
117
+ def init_char_str_list
118
+ @char_str_list = []
119
+ end
120
+
121
+ def _build_char_str_list(rdata_string)
122
+ words = Shellwords.shellwords(rdata_string)
123
+
124
+ init_char_str_list()
125
+
126
+ if (words != nil)
127
+ words.each { |string|
128
+ string .gsub!(/\\"/, '"')
129
+ @char_str_list.push(string)
130
+ }
131
+ end
132
+ end
133
+
134
+ #Returns a list of the individual <character-string> elements,
135
+ #as unquoted strings. Used by TXT->rdatastr and TXT->rr_rdata.
136
+ #
137
+ # print "Individual <character-string> list: \n\t",
138
+ # rr.char_str_list().join("\n\t")
139
+ #
140
+ def char_str_list
141
+ if (!defined?(@char_str_list))
142
+ _build_char_str_list( @txtdata )
143
+ end
144
+
145
+ return @char_str_list # unquoted strings
146
+ end
147
+
148
+ def rr_rdata(*args)
149
+ rdata = ''
150
+
151
+ if (@char_str_list!=nil)
152
+ @char_str_list.each { |string|
153
+ rdata += [string.length].pack("C")
154
+ rdata += string
155
+ }
156
+ end
157
+ return rdata
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end