pNet-DNS 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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