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