Merge from vendor branch GCC:
[dragonfly.git] / contrib / bind-9.2.4rc7 / lib / dns / rdata / any_255 / tsig_250.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2001, 2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: tsig_250.c,v 1.52.2.3 2004/03/09 06:11:26 marka Exp $ */
19
20 /* Reviewed: Thu Mar 16 13:39:43 PST 2000 by gson */
21
22 #ifndef RDATA_ANY_255_TSIG_250_C
23 #define RDATA_ANY_255_TSIG_250_C
24
25 #define RRTYPE_TSIG_ATTRIBUTES \
26         (DNS_RDATATYPEATTR_META | DNS_RDATATYPEATTR_NOTQUESTION)
27
28 static inline isc_result_t
29 fromtext_any_tsig(ARGS_FROMTEXT) {
30         isc_token_t token;
31         dns_name_t name;
32         isc_uint64_t sigtime;
33         isc_buffer_t buffer;
34         dns_rcode_t rcode;
35         long i;
36         char *e;
37
38         REQUIRE(type == 250);
39         REQUIRE(rdclass == 255);
40
41         UNUSED(type);
42         UNUSED(rdclass);
43         UNUSED(callbacks);
44
45         /*
46          * Algorithm Name.
47          */
48         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
49                                       ISC_FALSE));
50         dns_name_init(&name, NULL);
51         buffer_fromregion(&buffer, &token.value.as_region);
52         origin = (origin != NULL) ? origin : dns_rootname;
53         RETTOK(dns_name_fromtext(&name, &buffer, origin, downcase, target));
54
55         /*
56          * Time Signed: 48 bits.
57          */
58         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
59                                       ISC_FALSE));
60         sigtime = isc_string_touint64(token.value.as_pointer, &e, 10);
61         if (*e != 0)
62                 RETTOK(DNS_R_SYNTAX);
63         if ((sigtime >> 48) != 0)
64                 RETTOK(ISC_R_RANGE);
65         RETERR(uint16_tobuffer((isc_uint16_t)(sigtime >> 32), target));
66         RETERR(uint32_tobuffer((isc_uint32_t)(sigtime & 0xffffffffU), target));
67
68         /*
69          * Fudge.
70          */
71         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
72                                       ISC_FALSE));
73         if (token.value.as_ulong > 0xffffU)
74                 RETTOK(ISC_R_RANGE);
75         RETERR(uint16_tobuffer(token.value.as_ulong, target));
76
77         /*
78          * Signature Size.
79          */
80         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
81                                       ISC_FALSE));
82         if (token.value.as_ulong > 0xffffU)
83                 RETTOK(ISC_R_RANGE);
84         RETERR(uint16_tobuffer(token.value.as_ulong, target));
85
86         /*
87          * Signature.
88          */
89         RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
90
91         /*
92          * Original ID.
93          */
94         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
95                                       ISC_FALSE));
96         if (token.value.as_ulong > 0xffffU)
97                 RETTOK(ISC_R_RANGE);
98         RETERR(uint16_tobuffer(token.value.as_ulong, target));
99
100         /*
101          * Error.
102          */
103         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
104                                       ISC_FALSE));
105         if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion)
106                                 != ISC_R_SUCCESS)
107         {
108                 i = strtol(token.value.as_pointer, &e, 10);
109                 if (*e != 0)
110                         RETTOK(DNS_R_UNKNOWN);
111                 if (i < 0 || i > 0xffff)
112                         RETTOK(ISC_R_RANGE);
113                 rcode = (dns_rcode_t)i;
114         }
115         RETERR(uint16_tobuffer(rcode, target));
116
117         /*
118          * Other Len.
119          */
120         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
121                                       ISC_FALSE));
122         if (token.value.as_ulong > 0xffffU)
123                 RETTOK(ISC_R_RANGE);
124         RETERR(uint16_tobuffer(token.value.as_ulong, target));
125
126         /*
127          * Other Data.
128          */
129         return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
130 }
131
132 static inline isc_result_t
133 totext_any_tsig(ARGS_TOTEXT) {
134         isc_region_t sr;
135         isc_region_t sigr;
136         char buf[sizeof "281474976710655 "];
137         char *bufp;
138         dns_name_t name;
139         dns_name_t prefix;
140         isc_boolean_t sub;
141         isc_uint64_t sigtime;
142         unsigned short n;
143
144         REQUIRE(rdata->type == 250);
145         REQUIRE(rdata->rdclass == 255);
146         REQUIRE(rdata->length != 0);
147
148         dns_rdata_toregion(rdata, &sr);
149         /*
150          * Algorithm Name.
151          */
152         dns_name_init(&name, NULL);
153         dns_name_init(&prefix, NULL);
154         dns_name_fromregion(&name, &sr);
155         sub = name_prefix(&name, tctx->origin, &prefix);
156         RETERR(dns_name_totext(&prefix, sub, target));
157         RETERR(str_totext(" ", target));
158         isc_region_consume(&sr, name_length(&name));
159
160         /*
161          * Time Signed.
162          */
163         sigtime = ((isc_uint64_t)sr.base[0] << 40) |
164                   ((isc_uint64_t)sr.base[1] << 32) |
165                   (sr.base[2] << 24) | (sr.base[3] << 16) |
166                   (sr.base[4] << 8) | sr.base[5];
167         isc_region_consume(&sr, 6);
168         bufp = &buf[sizeof buf - 1];
169         *bufp-- = 0;
170         *bufp-- = ' ';
171         do {
172                 *bufp-- = decdigits[sigtime % 10];
173                 sigtime /= 10;
174         } while (sigtime != 0);
175         bufp++;
176         RETERR(str_totext(bufp, target));
177
178         /*
179          * Fudge.
180          */
181         n = uint16_fromregion(&sr);
182         isc_region_consume(&sr, 2);
183         sprintf(buf, "%u ", n);
184         RETERR(str_totext(buf, target));
185
186         /*
187          * Signature Size.
188          */
189         n = uint16_fromregion(&sr);
190         isc_region_consume(&sr, 2);
191         sprintf(buf, "%u", n);
192         RETERR(str_totext(buf, target));
193
194         /*
195          * Signature.
196          */
197         REQUIRE(n <= sr.length);
198         sigr = sr;
199         sigr.length = n;
200         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
201                 RETERR(str_totext(" (", target));
202         RETERR(str_totext(tctx->linebreak, target));
203         RETERR(isc_base64_totext(&sigr, tctx->width - 2,
204                                  tctx->linebreak, target));
205         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
206                 RETERR(str_totext(" ) ", target));
207         else
208                 RETERR(str_totext(" ", target));
209         isc_region_consume(&sr, n);
210
211         /*
212          * Original ID.
213          */
214         n = uint16_fromregion(&sr);
215         isc_region_consume(&sr, 2);
216         sprintf(buf, "%u ", n);
217         RETERR(str_totext(buf, target));
218
219         /*
220          * Error.
221          */
222         n = uint16_fromregion(&sr);
223         isc_region_consume(&sr, 2);
224         if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS)
225                 RETERR(str_totext(" ", target));
226         else {
227                 sprintf(buf, "%u ", n);
228                 RETERR(str_totext(buf, target));
229         }
230
231         /*
232          * Other Size.
233          */
234         n = uint16_fromregion(&sr);
235         isc_region_consume(&sr, 2);
236         sprintf(buf, "%u ", n);
237         RETERR(str_totext(buf, target));
238
239         /*
240          * Other.
241          */
242         return (isc_base64_totext(&sr, 60, " ", target));
243 }
244
245 static inline isc_result_t
246 fromwire_any_tsig(ARGS_FROMWIRE) {
247         isc_region_t sr;
248         dns_name_t name;
249         unsigned long n;
250
251         REQUIRE(type == 250);
252         REQUIRE(rdclass == 255);
253
254         UNUSED(type);
255         UNUSED(rdclass);
256
257         dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
258
259         /*
260          * Algorithm Name.
261          */
262         dns_name_init(&name, NULL);
263         RETERR(dns_name_fromwire(&name, source, dctx, downcase, target));
264
265         isc_buffer_activeregion(source, &sr);
266         /*
267          * Time Signed + Fudge.
268          */
269         if (sr.length < 8)
270                 return (ISC_R_UNEXPECTEDEND);
271         RETERR(mem_tobuffer(target, sr.base, 8));
272         isc_region_consume(&sr, 8);
273         isc_buffer_forward(source, 8);
274
275         /*
276          * Signature Length + Signature.
277          */
278         if (sr.length < 2)
279                 return (ISC_R_UNEXPECTEDEND);
280         n = uint16_fromregion(&sr);
281         if (sr.length < n + 2)
282                 return (ISC_R_UNEXPECTEDEND);
283         RETERR(mem_tobuffer(target, sr.base, n + 2));
284         isc_region_consume(&sr, n + 2);
285         isc_buffer_forward(source, n + 2);
286
287         /*
288          * Original ID + Error.
289          */
290         if (sr.length < 4)
291                 return (ISC_R_UNEXPECTEDEND);
292         RETERR(mem_tobuffer(target, sr.base,  4));
293         isc_region_consume(&sr, 4);
294         isc_buffer_forward(source, 4);
295
296         /*
297          * Other Length + Other.
298          */
299         if (sr.length < 2)
300                 return (ISC_R_UNEXPECTEDEND);
301         n = uint16_fromregion(&sr);
302         if (sr.length < n + 2)
303                 return (ISC_R_UNEXPECTEDEND);
304         isc_buffer_forward(source, n + 2);
305         return (mem_tobuffer(target, sr.base, n + 2));
306 }
307
308 static inline isc_result_t
309 towire_any_tsig(ARGS_TOWIRE) {
310         isc_region_t sr;
311         dns_name_t name;
312         dns_offsets_t offsets;
313
314         REQUIRE(rdata->type == 250);
315         REQUIRE(rdata->rdclass == 255);
316         REQUIRE(rdata->length != 0);
317
318         dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
319         dns_rdata_toregion(rdata, &sr);
320         dns_name_init(&name, offsets);
321         dns_name_fromregion(&name, &sr);
322         RETERR(dns_name_towire(&name, cctx, target));
323         isc_region_consume(&sr, name_length(&name));
324         return (mem_tobuffer(target, sr.base, sr.length));
325 }
326
327 static inline int
328 compare_any_tsig(ARGS_COMPARE) {
329         isc_region_t r1;
330         isc_region_t r2;
331         dns_name_t name1;
332         dns_name_t name2;
333         int order;
334
335         REQUIRE(rdata1->type == rdata2->type);
336         REQUIRE(rdata1->rdclass == rdata2->rdclass);
337         REQUIRE(rdata1->type == 250);
338         REQUIRE(rdata1->rdclass == 255);
339         REQUIRE(rdata1->length != 0);
340         REQUIRE(rdata2->length != 0);
341
342         dns_rdata_toregion(rdata1, &r1);
343         dns_rdata_toregion(rdata2, &r2);
344         dns_name_init(&name1, NULL);
345         dns_name_init(&name2, NULL);
346         dns_name_fromregion(&name1, &r1);
347         dns_name_fromregion(&name2, &r2);
348         order = dns_name_rdatacompare(&name1, &name2);
349         if (order != 0)
350                 return (order);
351         isc_region_consume(&r1, name_length(&name1));
352         isc_region_consume(&r2, name_length(&name2));
353         return (compare_region(&r1, &r2));
354 }
355
356 static inline isc_result_t
357 fromstruct_any_tsig(ARGS_FROMSTRUCT) {
358         dns_rdata_any_tsig_t *tsig = source;
359         isc_region_t tr;
360
361         REQUIRE(type == 250);
362         REQUIRE(rdclass == 255);
363         REQUIRE(source != NULL);
364         REQUIRE(tsig->common.rdclass == rdclass);
365         REQUIRE(tsig->common.rdtype == type);
366
367         UNUSED(type);
368         UNUSED(rdclass);
369
370         /*
371          * Algorithm Name.
372          */
373         RETERR(name_tobuffer(&tsig->algorithm, target));
374
375         isc_buffer_availableregion(target, &tr);
376         if (tr.length < 6 + 2 + 2)
377                 return (ISC_R_NOSPACE);
378
379         /*
380          * Time Signed: 48 bits.
381          */
382         RETERR(uint16_tobuffer((isc_uint16_t)(tsig->timesigned >> 32),
383                                target));
384         RETERR(uint32_tobuffer((isc_uint32_t)(tsig->timesigned & 0xffffffffU),
385                                target));
386
387         /*
388          * Fudge.
389          */
390         RETERR(uint16_tobuffer(tsig->fudge, target));
391
392         /*
393          * Signature Size.
394          */
395         RETERR(uint16_tobuffer(tsig->siglen, target));
396
397         /*
398          * Signature.
399          */
400         RETERR(mem_tobuffer(target, tsig->signature, tsig->siglen));
401
402         isc_buffer_availableregion(target, &tr);
403         if (tr.length < 2 + 2 + 2)
404                 return (ISC_R_NOSPACE);
405
406         /*
407          * Original ID.
408          */
409         RETERR(uint16_tobuffer(tsig->originalid, target));
410
411         /*
412          * Error.
413          */
414         RETERR(uint16_tobuffer(tsig->error, target));
415
416         /*
417          * Other Len.
418          */
419         RETERR(uint16_tobuffer(tsig->otherlen, target));
420
421         /*
422          * Other Data.
423          */
424         return (mem_tobuffer(target, tsig->other, tsig->otherlen));
425 }
426
427 static inline isc_result_t
428 tostruct_any_tsig(ARGS_TOSTRUCT) {
429         dns_rdata_any_tsig_t *tsig;
430         dns_name_t alg;
431         isc_region_t sr;
432
433         REQUIRE(rdata->type == 250);
434         REQUIRE(rdata->rdclass == 255);
435         REQUIRE(rdata->length != 0);
436
437         tsig = (dns_rdata_any_tsig_t *) target;
438         tsig->common.rdclass = rdata->rdclass;
439         tsig->common.rdtype = rdata->type;
440         ISC_LINK_INIT(&tsig->common, link);
441
442         dns_rdata_toregion(rdata, &sr);
443
444         /*
445          * Algorithm Name.
446          */
447         dns_name_init(&alg, NULL);
448         dns_name_fromregion(&alg, &sr);
449         dns_name_init(&tsig->algorithm, NULL);
450         RETERR(name_duporclone(&alg, mctx, &tsig->algorithm));
451
452         isc_region_consume(&sr, name_length(&tsig->algorithm));
453
454         /*
455          * Time Signed.
456          */
457         INSIST(sr.length >= 6);
458         tsig->timesigned = ((isc_uint64_t)sr.base[0] << 40) |
459                            ((isc_uint64_t)sr.base[1] << 32) |
460                            (sr.base[2] << 24) | (sr.base[3] << 16) |
461                            (sr.base[4] << 8) | sr.base[5];
462         isc_region_consume(&sr, 6);
463
464         /*
465          * Fudge.
466          */
467         tsig->fudge = uint16_fromregion(&sr);
468         isc_region_consume(&sr, 2);
469
470         /*
471          * Signature Size.
472          */
473         tsig->siglen = uint16_fromregion(&sr);
474         isc_region_consume(&sr, 2);
475
476         /*
477          * Signature.
478          */
479         INSIST(sr.length >= tsig->siglen);
480         tsig->signature = mem_maybedup(mctx, sr.base, tsig->siglen);
481         if (tsig->signature == NULL)
482                 goto cleanup;
483         isc_region_consume(&sr, tsig->siglen);
484
485         /*
486          * Original ID.
487          */
488         tsig->originalid = uint16_fromregion(&sr);
489         isc_region_consume(&sr, 2);
490
491         /*
492          * Error.
493          */
494         tsig->error = uint16_fromregion(&sr);
495         isc_region_consume(&sr, 2);
496
497         /*
498          * Other Size.
499          */
500         tsig->otherlen = uint16_fromregion(&sr);
501         isc_region_consume(&sr, 2);
502
503         /*
504          * Other.
505          */
506         INSIST(sr.length == tsig->otherlen);
507         tsig->other = mem_maybedup(mctx, sr.base, tsig->otherlen);
508         if (tsig->other == NULL)
509                 goto cleanup;
510
511         tsig->mctx = mctx;
512         return (ISC_R_SUCCESS);
513
514  cleanup:
515         if (mctx != NULL)
516                 dns_name_free(&tsig->algorithm, tsig->mctx);
517         if (mctx != NULL && tsig->signature != NULL)
518                 isc_mem_free(mctx, tsig->signature);
519         return (ISC_R_NOMEMORY);
520 }
521
522 static inline void
523 freestruct_any_tsig(ARGS_FREESTRUCT) {
524         dns_rdata_any_tsig_t *tsig = (dns_rdata_any_tsig_t *) source;
525
526         REQUIRE(source != NULL);
527         REQUIRE(tsig->common.rdclass == 255);
528         REQUIRE(tsig->common.rdtype == 250);
529
530         if (tsig->mctx == NULL)
531                 return;
532
533         dns_name_free(&tsig->algorithm, tsig->mctx);
534         if (tsig->signature != NULL)
535                 isc_mem_free(tsig->mctx, tsig->signature);
536         if (tsig->other != NULL)
537                 isc_mem_free(tsig->mctx, tsig->other);
538         tsig->mctx = NULL;
539 }
540
541 static inline isc_result_t
542 additionaldata_any_tsig(ARGS_ADDLDATA) {
543         REQUIRE(rdata->type == 250);
544         REQUIRE(rdata->rdclass == 255);
545
546         UNUSED(rdata);
547         UNUSED(add);
548         UNUSED(arg);
549
550         return (ISC_R_SUCCESS);
551 }
552
553 static inline isc_result_t
554 digest_any_tsig(ARGS_DIGEST) {
555
556         REQUIRE(rdata->type == 250);
557         REQUIRE(rdata->rdclass == 255);
558
559         UNUSED(rdata);
560         UNUSED(digest);
561         UNUSED(arg);
562
563         return (ISC_R_NOTIMPLEMENTED);
564 }
565
566 #endif  /* RDATA_ANY_255_TSIG_250_C */