]> git.ipfire.org Git - people/ms/strongswan.git/blob - src/libfreeswan/liblwres/lwres_grbn.c
- started to rebuild source layout
[people/ms/strongswan.git] / src / libfreeswan / liblwres / lwres_grbn.c
1 /*
2 * Copyright (C) 2000, 2001 Internet Software Consortium.
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
9 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
10 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
11 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
13 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
14 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 /* $Id: lwres_grbn.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
19
20 #include <config.h>
21
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <lwres/lwbuffer.h>
27 #include <lwres/lwpacket.h>
28 #include <lwres/lwres.h>
29 #include <lwres/result.h>
30
31 #include "context_p.h"
32 #include "assert_p.h"
33
34 lwres_result_t
35 lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req,
36 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
37 {
38 unsigned char *buf;
39 size_t buflen;
40 int ret;
41 size_t payload_length;
42 lwres_uint16_t datalen;
43
44 REQUIRE(ctx != NULL);
45 REQUIRE(req != NULL);
46 REQUIRE(req->name != NULL);
47 REQUIRE(pkt != NULL);
48 REQUIRE(b != NULL);
49
50 datalen = strlen(req->name);
51
52 payload_length = 4 + 2 + 2 + 2 + req->namelen + 1;
53
54 buflen = LWRES_LWPACKET_LENGTH + payload_length;
55 buf = CTXMALLOC(buflen);
56 if (buf == NULL)
57 return (LWRES_R_NOMEMORY);
58
59 lwres_buffer_init(b, buf, buflen);
60
61 pkt->length = buflen;
62 pkt->version = LWRES_LWPACKETVERSION_0;
63 pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
64 pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
65 pkt->result = 0;
66 pkt->authtype = 0;
67 pkt->authlength = 0;
68
69 ret = lwres_lwpacket_renderheader(b, pkt);
70 if (ret != LWRES_R_SUCCESS) {
71 lwres_buffer_invalidate(b);
72 CTXFREE(buf, buflen);
73 return (ret);
74 }
75
76 INSIST(SPACE_OK(b, payload_length));
77
78 /*
79 * Flags.
80 */
81 lwres_buffer_putuint32(b, req->flags);
82
83 /*
84 * Class.
85 */
86 lwres_buffer_putuint16(b, req->rdclass);
87
88 /*
89 * Type.
90 */
91 lwres_buffer_putuint16(b, req->rdtype);
92
93 /*
94 * Put the length and the data. We know this will fit because we
95 * just checked for it.
96 */
97 lwres_buffer_putuint16(b, datalen);
98 lwres_buffer_putmem(b, (unsigned char *)req->name, datalen);
99 lwres_buffer_putuint8(b, 0); /* trailing NUL */
100
101 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
102
103 return (LWRES_R_SUCCESS);
104 }
105
106 lwres_result_t
107 lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
108 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
109 {
110 unsigned char *buf;
111 size_t buflen;
112 int ret;
113 size_t payload_length;
114 lwres_uint16_t datalen;
115 int x;
116
117 REQUIRE(ctx != NULL);
118 REQUIRE(req != NULL);
119 REQUIRE(pkt != NULL);
120 REQUIRE(b != NULL);
121
122 /* flags, class, type, ttl, nrdatas, nsigs */
123 payload_length = 4 + 2 + 2 + 4 + 2 + 2;
124 /* real name encoding */
125 payload_length += 2 + req->realnamelen + 1;
126 /* each rr */
127 for (x = 0 ; x < req->nrdatas ; x++)
128 payload_length += 2 + req->rdatalen[x];
129 for (x = 0 ; x < req->nsigs ; x++)
130 payload_length += 2 + req->siglen[x];
131
132 buflen = LWRES_LWPACKET_LENGTH + payload_length;
133 buf = CTXMALLOC(buflen);
134 if (buf == NULL)
135 return (LWRES_R_NOMEMORY);
136 lwres_buffer_init(b, buf, buflen);
137
138 pkt->length = buflen;
139 pkt->version = LWRES_LWPACKETVERSION_0;
140 pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
141 pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
142 pkt->authtype = 0;
143 pkt->authlength = 0;
144
145 ret = lwres_lwpacket_renderheader(b, pkt);
146 if (ret != LWRES_R_SUCCESS) {
147 lwres_buffer_invalidate(b);
148 CTXFREE(buf, buflen);
149 return (ret);
150 }
151
152 /*
153 * Check space needed here.
154 */
155 INSIST(SPACE_OK(b, payload_length));
156
157 /* Flags. */
158 lwres_buffer_putuint32(b, req->flags);
159
160 /* encode class, type, ttl, and nrdatas */
161 lwres_buffer_putuint16(b, req->rdclass);
162 lwres_buffer_putuint16(b, req->rdtype);
163 lwres_buffer_putuint32(b, req->ttl);
164 lwres_buffer_putuint16(b, req->nrdatas);
165 lwres_buffer_putuint16(b, req->nsigs);
166
167 /* encode the real name */
168 datalen = req->realnamelen;
169 lwres_buffer_putuint16(b, datalen);
170 lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
171 lwres_buffer_putuint8(b, 0);
172
173 /* encode the rdatas */
174 for (x = 0 ; x < req->nrdatas ; x++) {
175 datalen = req->rdatalen[x];
176 lwres_buffer_putuint16(b, datalen);
177 lwres_buffer_putmem(b, req->rdatas[x], datalen);
178 }
179
180 /* encode the signatures */
181 for (x = 0 ; x < req->nsigs ; x++) {
182 datalen = req->siglen[x];
183 lwres_buffer_putuint16(b, datalen);
184 lwres_buffer_putmem(b, req->sigs[x], datalen);
185 }
186
187 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
188 INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length);
189
190 return (LWRES_R_SUCCESS);
191 }
192
193 lwres_result_t
194 lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
195 lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp)
196 {
197 int ret;
198 char *name;
199 lwres_grbnrequest_t *grbn;
200 lwres_uint32_t flags;
201 lwres_uint16_t rdclass, rdtype;
202 lwres_uint16_t namelen;
203
204 REQUIRE(ctx != NULL);
205 REQUIRE(pkt != NULL);
206 REQUIRE(b != NULL);
207 REQUIRE(structp != NULL && *structp == NULL);
208
209 if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
210 return (LWRES_R_FAILURE);
211
212 if (!SPACE_REMAINING(b, 4 + 2 + 2))
213 return (LWRES_R_UNEXPECTEDEND);
214
215 /*
216 * Pull off the flags, class, and type.
217 */
218 flags = lwres_buffer_getuint32(b);
219 rdclass = lwres_buffer_getuint16(b);
220 rdtype = lwres_buffer_getuint16(b);
221
222 /*
223 * Pull off the name itself
224 */
225 ret = lwres_string_parse(b, &name, &namelen);
226 if (ret != LWRES_R_SUCCESS)
227 return (ret);
228
229 if (LWRES_BUFFER_REMAINING(b) != 0)
230 return (LWRES_R_TRAILINGDATA);
231
232 grbn = CTXMALLOC(sizeof(lwres_grbnrequest_t));
233 if (grbn == NULL)
234 return (LWRES_R_NOMEMORY);
235
236 grbn->flags = flags;
237 grbn->rdclass = rdclass;
238 grbn->rdtype = rdtype;
239 grbn->name = name;
240 grbn->namelen = namelen;
241
242 *structp = grbn;
243 return (LWRES_R_SUCCESS);
244 }
245
246 lwres_result_t
247 lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
248 lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp)
249 {
250 lwres_result_t ret;
251 unsigned int x;
252 lwres_uint32_t flags;
253 lwres_uint16_t rdclass, rdtype;
254 lwres_uint32_t ttl;
255 lwres_uint16_t nrdatas, nsigs;
256 lwres_grbnresponse_t *grbn;
257
258 REQUIRE(ctx != NULL);
259 REQUIRE(pkt != NULL);
260 REQUIRE(b != NULL);
261 REQUIRE(structp != NULL && *structp == NULL);
262
263 grbn = NULL;
264
265 if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
266 return (LWRES_R_FAILURE);
267
268 /*
269 * Pull off the flags, class, type, ttl, nrdatas, and nsigs
270 */
271 if (!SPACE_REMAINING(b, 4 + 2 + 2 + 4 + 2 + 2))
272 return (LWRES_R_UNEXPECTEDEND);
273 flags = lwres_buffer_getuint32(b);
274 rdclass = lwres_buffer_getuint16(b);
275 rdtype = lwres_buffer_getuint16(b);
276 ttl = lwres_buffer_getuint32(b);
277 nrdatas = lwres_buffer_getuint16(b);
278 nsigs = lwres_buffer_getuint16(b);
279
280 /*
281 * Pull off the name itself
282 */
283
284 grbn = CTXMALLOC(sizeof(lwres_grbnresponse_t));
285 if (grbn == NULL)
286 return (LWRES_R_NOMEMORY);
287 grbn->rdatas = NULL;
288 grbn->rdatalen = NULL;
289 grbn->sigs = NULL;
290 grbn->siglen = NULL;
291 grbn->base = NULL;
292
293 grbn->flags = flags;
294 grbn->rdclass = rdclass;
295 grbn->rdtype = rdtype;
296 grbn->ttl = ttl;
297 grbn->nrdatas = nrdatas;
298 grbn->nsigs = nsigs;
299
300 if (nrdatas > 0) {
301 grbn->rdatas = CTXMALLOC(sizeof(char *) * nrdatas);
302 if (grbn->rdatas == NULL) {
303 ret = LWRES_R_NOMEMORY;
304 goto out;
305 }
306
307 grbn->rdatalen = CTXMALLOC(sizeof(lwres_uint16_t) * nrdatas);
308 if (grbn->rdatalen == NULL) {
309 ret = LWRES_R_NOMEMORY;
310 goto out;
311 }
312 }
313
314 if (nsigs > 0) {
315 grbn->sigs = CTXMALLOC(sizeof(char *) * nsigs);
316 if (grbn->sigs == NULL) {
317 ret = LWRES_R_NOMEMORY;
318 goto out;
319 }
320
321 grbn->siglen = CTXMALLOC(sizeof(lwres_uint16_t) * nsigs);
322 if (grbn->siglen == NULL) {
323 ret = LWRES_R_NOMEMORY;
324 goto out;
325 }
326 }
327
328 /*
329 * Now, pull off the real name.
330 */
331 ret = lwres_string_parse(b, &grbn->realname, &grbn->realnamelen);
332 if (ret != LWRES_R_SUCCESS)
333 goto out;
334
335 /*
336 * Parse off the rdatas.
337 */
338 for (x = 0 ; x < grbn->nrdatas ; x++) {
339 ret = lwres_data_parse(b, &grbn->rdatas[x],
340 &grbn->rdatalen[x]);
341 if (ret != LWRES_R_SUCCESS)
342 goto out;
343 }
344
345 /*
346 * Parse off the signatures.
347 */
348 for (x = 0 ; x < grbn->nsigs ; x++) {
349 ret = lwres_data_parse(b, &grbn->sigs[x], &grbn->siglen[x]);
350 if (ret != LWRES_R_SUCCESS)
351 goto out;
352 }
353
354 if (LWRES_BUFFER_REMAINING(b) != 0) {
355 ret = LWRES_R_TRAILINGDATA;
356 goto out;
357 }
358
359 *structp = grbn;
360 return (LWRES_R_SUCCESS);
361
362 out:
363 if (grbn != NULL) {
364 if (grbn->rdatas != NULL)
365 CTXFREE(grbn->rdatas, sizeof(char *) * nrdatas);
366 if (grbn->rdatalen != NULL)
367 CTXFREE(grbn->rdatalen,
368 sizeof(lwres_uint16_t) * nrdatas);
369 if (grbn->sigs != NULL)
370 CTXFREE(grbn->sigs, sizeof(char *) * nsigs);
371 if (grbn->siglen != NULL)
372 CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * nsigs);
373 CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
374 }
375
376 return (ret);
377 }
378
379 void
380 lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp)
381 {
382 lwres_grbnrequest_t *grbn;
383
384 REQUIRE(ctx != NULL);
385 REQUIRE(structp != NULL && *structp != NULL);
386
387 grbn = *structp;
388 *structp = NULL;
389
390 CTXFREE(grbn, sizeof(lwres_grbnrequest_t));
391 }
392
393 void
394 lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp)
395 {
396 lwres_grbnresponse_t *grbn;
397
398 REQUIRE(ctx != NULL);
399 REQUIRE(structp != NULL && *structp != NULL);
400
401 grbn = *structp;
402 *structp = NULL;
403
404 if (grbn->nrdatas > 0) {
405 CTXFREE(grbn->rdatas, sizeof(char *) * grbn->nrdatas);
406 CTXFREE(grbn->rdatalen,
407 sizeof(lwres_uint16_t) * grbn->nrdatas);
408 }
409 if (grbn->nsigs > 0) {
410 CTXFREE(grbn->sigs, sizeof(char *) * grbn->nsigs);
411 CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * grbn->nsigs);
412 }
413 if (grbn->base != NULL)
414 CTXFREE(grbn->base, grbn->baselen);
415 CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
416 }