1 /*
2 * Copyright (c) 2003, 2004 Niels Provos <provos@citi.umich.edu>
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 */
32
33 #include <sys/types.h>
34 #include <sys/param.h>
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include <sys/ioctl.h>
41 #include <sys/tree.h>
42 #include <sys/queue.h>
43 #ifdef HAVE_SYS_TIME_H
44 #include <sys/time.h>
45 #endif
46
47 #include <err.h>
48 #include <errno.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <syslog.h>
53 #include <unistd.h>
54
55 #include <event.h>
56 #include <pcap.h>
57 #include <dnet.h>
58
59 #include "tagging.h"
60 #include "untagging.h"
61
62 extern struct evbuffer *_buf;
63
64 static int __inline
decode_int_internal(uint32_t * pnumber,struct evbuffer * evbuf,int dodrain)65 decode_int_internal(uint32_t *pnumber, struct evbuffer *evbuf, int dodrain)
66 {
67 uint32_t number = 0;
68 uint8_t *data = EVBUFFER_DATA(evbuf);
69 int len = EVBUFFER_LENGTH(evbuf);
70 int nibbles = 0, off;
71
72 if (!len)
73 return (-1);
74
75 nibbles = ((data[0] & 0xf0) >> 4) + 1;
76 if (nibbles > 8 || (nibbles >> 1) > len - 1)
77 return (-1);
78
79 off = nibbles;
80 while (off > 0) {
81 number <<= 4;
82 if (off & 0x1)
83 number |= data[off >> 1] & 0x0f;
84 else
85 number |= (data[off >> 1] & 0xf0) >> 4;
86 off--;
87 }
88
89 len = (nibbles >> 1) + 1;
90 if (dodrain)
91 evbuffer_drain(evbuf, len);
92
93 *pnumber = number;
94
95 return (len);
96 }
97
98 int
decode_int(uint32_t * pnumber,struct evbuffer * evbuf)99 decode_int(uint32_t *pnumber, struct evbuffer *evbuf)
100 {
101 return (decode_int_internal(pnumber, evbuf, 1) == -1 ? -1 : 0);
102 }
103
104 int
tag_peek(struct evbuffer * evbuf,uint8_t * ptag)105 tag_peek(struct evbuffer *evbuf, uint8_t *ptag)
106 {
107 if (EVBUFFER_LENGTH(evbuf) < 2)
108 return (-1);
109 *ptag = EVBUFFER_DATA(evbuf)[0];
110
111 return (0);
112 }
113
114 int
tag_peek_length(struct evbuffer * evbuf,uint32_t * plength)115 tag_peek_length(struct evbuffer *evbuf, uint32_t *plength)
116 {
117 struct evbuffer *tmp;
118 int res;
119
120 if (EVBUFFER_LENGTH(evbuf) < 2)
121 return (-1);
122
123 tmp = evbuffer_new ();
124 evbuffer_add_reference (tmp, evbuffer_pullup(evbuf, -1),
125 evbuffer_get_length(evbuf), NULL, NULL);
126 if (evbuffer_drain(tmp, 1) == -1) {
127 evbuffer_free (tmp);
128 return (-1);
129 }
130
131 res = decode_int_internal(plength, tmp, 0);
132 if (res == -1) {
133 evbuffer_free (tmp);
134 return (-1);
135 }
136
137 *plength += res + 1;
138
139 evbuffer_free (tmp);
140 return (0);
141 }
142
143 int
tag_consume(struct evbuffer * evbuf)144 tag_consume(struct evbuffer *evbuf)
145 {
146 uint32_t len;
147 evbuffer_drain(evbuf, 1);
148 if (decode_int(&len, evbuf) == -1)
149 return (-1);
150 evbuffer_drain(evbuf, len);
151
152 return (0);
153 }
154
155 /* Reads the data type from an event buffer */
156
157 int
tag_unmarshal(struct evbuffer * src,uint8_t * ptag,struct evbuffer * dst)158 tag_unmarshal(struct evbuffer *src, uint8_t *ptag, struct evbuffer *dst)
159 {
160 uint8_t tag;
161 uint16_t len;
162 uint32_t integer;
163
164 if (evbuffer_remove(src, &tag, sizeof(tag)) != sizeof(tag))
165 return (-1);
166 if (decode_int(&integer, src) == -1)
167 return (-1);
168 len = integer;
169
170 if (EVBUFFER_LENGTH(src) < len)
171 return (-1);
172
173 if (evbuffer_add(dst, EVBUFFER_DATA(src), len) == -1)
174 return (-1);
175
176 evbuffer_drain(src, len);
177
178 *ptag = tag;
179 return (len);
180 }
181
182 /* Marshaling for integers */
183
184 int
tag_unmarshal_int(struct evbuffer * evbuf,uint8_t need_tag,uint32_t * pinteger)185 tag_unmarshal_int(struct evbuffer *evbuf, uint8_t need_tag, uint32_t *pinteger)
186 {
187 uint8_t tag;
188 uint16_t len;
189 uint32_t integer;
190
191 if (evbuffer_remove(evbuf, &tag, sizeof(tag)) != sizeof(tag) ||
192 tag != need_tag)
193 return (-1);
194 if (decode_int(&integer, evbuf) == -1)
195 return (-1);
196 len = integer;
197
198 if (EVBUFFER_LENGTH(evbuf) < len)
199 return (-1);
200
201 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
202 if (evbuffer_add(_buf, EVBUFFER_DATA(evbuf), len) == -1)
203 return (-1);
204
205 evbuffer_drain(evbuf, len);
206
207 return (decode_int(pinteger, _buf));
208 }
209
210 /* Unmarshal a fixed length tag */
211
212 int
tag_unmarshal_fixed(struct evbuffer * src,uint8_t need_tag,void * data,size_t len)213 tag_unmarshal_fixed(struct evbuffer *src, uint8_t need_tag, void *data,
214 size_t len)
215 {
216 uint8_t tag;
217
218 /* Initialize this event buffer so that we can read into it */
219 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
220
221 /* Now unmarshal a tag and check that it matches the tag we want */
222 if (tag_unmarshal(src, &tag, _buf) == -1 || tag != need_tag)
223 return (-1);
224
225 if (EVBUFFER_LENGTH(_buf) != len)
226 return (-1);
227
228 memcpy(data, EVBUFFER_DATA(_buf), len);
229 return (0);
230 }
231
232 int
tag_unmarshal_string(struct evbuffer * evbuf,uint8_t need_tag,char ** pstring)233 tag_unmarshal_string(struct evbuffer *evbuf, uint8_t need_tag, char **pstring)
234 {
235 uint8_t tag;
236
237 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
238
239 if (tag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag)
240 return (-1);
241
242 *pstring = calloc(EVBUFFER_LENGTH(_buf) + 1, 1);
243 if (*pstring == NULL)
244 err(1, "%s: calloc", __func__);
245 evbuffer_remove(_buf, *pstring, EVBUFFER_LENGTH(_buf));
246
247 return (0);
248 }
249
250 int
tag_unmarshal_timeval(struct evbuffer * evbuf,uint8_t need_tag,struct timeval * ptv)251 tag_unmarshal_timeval(struct evbuffer *evbuf, uint8_t need_tag,
252 struct timeval *ptv)
253 {
254 uint8_t tag;
255 uint32_t integer;
256
257 evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
258 if (tag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag)
259 return (-1);
260
261 if (decode_int(&integer, _buf) == -1)
262 return (-1);
263 ptv->tv_sec = integer;
264 if (decode_int(&integer, _buf) == -1)
265 return (-1);
266 ptv->tv_usec = integer;
267
268 return (0);
269 }
270
271 int
tag_unmarshal_record(struct evbuffer * evbuf,uint8_t need_tag,struct record * record)272 tag_unmarshal_record(struct evbuffer *evbuf, uint8_t need_tag,
273 struct record *record)
274 {
275 uint8_t tag;
276
277 struct evbuffer *tmp = evbuffer_new();
278
279 if (tag_unmarshal(evbuf, &tag, tmp) == -1 || tag != need_tag)
280 goto error;
281
282 if (record_unmarshal(record, tmp) == -1)
283 goto error;
284
285 evbuffer_free(tmp);
286 return (0);
287
288 error:
289 evbuffer_free(tmp);
290 return (-1);
291 }
292
293 /*
294 * Functions for un/marshaling dnet's struct addr; we create a tagged
295 * stream to save space. Otherwise, we would have pay the overhead of
296 * IPv6 address sizes for every kind of address.
297 */
298
299 #define UNMARSHAL(tag, what) \
300 tag_unmarshal_fixed(evbuf, tag, &(what), sizeof(what))
301
302 int
addr_unmarshal(struct addr * addr,struct evbuffer * evbuf)303 addr_unmarshal(struct addr* addr, struct evbuffer *evbuf)
304 {
305 uint32_t tmp_int;
306
307 memset(addr, 0, sizeof(struct addr));
308
309 if (tag_unmarshal_int(evbuf, ADDR_TYPE, &tmp_int) == -1)
310 return (-1);
311 addr->addr_type = tmp_int;
312
313 if (tag_unmarshal_int(evbuf, ADDR_BITS, &tmp_int) == -1)
314 return (-1);
315 addr->addr_bits = tmp_int;
316
317 switch (addr->addr_type) {
318 case ADDR_TYPE_ETH:
319 tag_unmarshal_fixed(evbuf, ADDR_ADDR,
320 &addr->addr_eth, sizeof(addr->addr_eth));
321 break;
322 case ADDR_TYPE_IP:
323 tag_unmarshal_fixed(evbuf, ADDR_ADDR,
324 &addr->addr_ip, sizeof(addr->addr_ip));
325 break;
326 case ADDR_TYPE_IP6:
327 tag_unmarshal_fixed(evbuf, ADDR_ADDR,
328 &addr->addr_ip6, sizeof(addr->addr_ip6));
329 break;
330 default:
331 return (-1);
332 }
333
334 return (0);
335 }
336
337 /*
338 * Functions to un/marshal records.
339 */
340
341 int
record_unmarshal(struct record * record,struct evbuffer * evbuf)342 record_unmarshal(struct record *record, struct evbuffer *evbuf)
343 {
344 struct evbuffer *tmp = evbuffer_new();
345 uint32_t integer;
346 uint8_t tag;
347
348 memset(record, 0, sizeof(struct record));
349 TAILQ_INIT(&record->hashes);
350
351 /* The timevals are optional, so we need to check their presence */
352 if (tag_peek(evbuf, &tag) != -1 && tag == REC_TV_START) {
353 if (tag_unmarshal_timeval(evbuf, REC_TV_START,
354 &record->tv_start) == -1)
355 goto error;
356 }
357 if (tag_peek(evbuf, &tag) != -1 && tag == REC_TV_END) {
358 if (tag_unmarshal_timeval(evbuf, REC_TV_END,
359 &record->tv_end) == -1)
360 goto error;
361 }
362
363 evbuffer_drain(tmp, EVBUFFER_LENGTH(tmp));
364 if (tag_unmarshal(evbuf, &tag, tmp) == -1 || tag != REC_SRC)
365 goto error;
366 if (addr_unmarshal(&record->src, tmp) == -1)
367 goto error;
368
369 evbuffer_drain(tmp, EVBUFFER_LENGTH(tmp));
370 if (tag_unmarshal(evbuf, &tag, tmp) == -1 || tag != REC_DST)
371 goto error;
372 if (addr_unmarshal(&record->dst, tmp) == -1)
373 goto error;
374
375 if (tag_unmarshal_int(evbuf, REC_SRC_PORT, &integer) == -1)
376 goto error;
377 record->src_port = integer;
378 if (tag_unmarshal_int(evbuf, REC_DST_PORT, &integer) == -1)
379 goto error;
380 record->dst_port = integer;
381 if (tag_unmarshal_int(evbuf, REC_PROTO, &integer) == -1)
382 goto error;
383 record->proto = integer;
384 if (tag_unmarshal_int(evbuf, REC_STATE, &integer) == -1)
385 goto error;
386 record->state = integer;
387
388 while (tag_peek(evbuf, &tag) != -1) {
389 switch(tag) {
390 case REC_OS_FP:
391 if (tag_unmarshal_string(evbuf, tag,
392 &record->os_fp) == -1)
393 goto error;
394 break;
395
396 case REC_HASH: {
397 struct hash *tmp;
398
399 if ((tmp = calloc(1, sizeof(struct hash))) == NULL)
400 err(1, "%s: calloc", __func__);
401 if (tag_unmarshal_fixed(evbuf, REC_HASH, tmp->digest,
402 sizeof(tmp->digest)) == -1) {
403 free(tmp);
404 goto error;
405 }
406 TAILQ_INSERT_TAIL(&record->hashes, tmp, next);
407 }
408 break;
409 case REC_BYTES:
410 if (tag_unmarshal_int(evbuf, tag,&record->bytes) == -1)
411 goto error;
412 break;
413 case REC_FLAGS:
414 if (tag_unmarshal_int(evbuf, tag,&record->flags) == -1)
415 goto error;
416 break;
417 default:
418 syslog(LOG_DEBUG, "Ignoring unknown record tag %d",
419 tag);
420 tag_consume(evbuf);
421 break;
422 }
423 }
424
425 evbuffer_free(tmp);
426 return (0);
427
428 error:
429 evbuffer_free(tmp);
430 return (-1);
431 }
432
433 #define TEST_MAX_INT 6
434
435 void
tagging_int_test(void)436 tagging_int_test(void)
437 {
438 struct evbuffer *tmp = evbuffer_new();
439 uint32_t integers[TEST_MAX_INT] = {
440 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000
441 };
442 uint32_t integer;
443 int i;
444
445 for (i = 0; i < TEST_MAX_INT; i++) {
446 int oldlen, newlen;
447 oldlen = EVBUFFER_LENGTH(tmp);
448 encode__int(tmp, integers[i]);
449 newlen = EVBUFFER_LENGTH(tmp);
450 fprintf(stderr, "\t\tencoded 0x%08x with %d bytes\n",
451 integers[i], newlen - oldlen);
452 }
453
454 for (i = 0; i < TEST_MAX_INT; i++) {
455 if (decode_int(&integer, tmp) == -1)
456 errx(1, "decode %d failed", i);
457 if (integer != integers[i])
458 errx(1, "got %x, wanted %x", integer, integers[i]);
459 }
460
461 if (EVBUFFER_LENGTH(tmp) != 0)
462 errx(1, "trailing data");
463 evbuffer_free(tmp);
464
465 fprintf(stderr, "\t%s: OK\n", __func__);
466 }
467
468 void
tagging_addr_test(void)469 tagging_addr_test(void)
470 {
471 struct evbuffer *tmp = evbuffer_new();
472 struct addr one, two;
473
474 addr_pton("192.168.1.16/28", &one);
475 addr_marshal(tmp, &one);
476 if (addr_unmarshal(&two, tmp) == -1)
477 errx(1, "addr unmarshal failed.");
478 if (addr_cmp(&one, &two) != 0)
479 errx(1, "addr %s != %s", addr_ntoa(&one), addr_ntoa(&two));
480
481 evbuffer_free(tmp);
482
483 fprintf(stderr, "\t%s: OK\n", __func__);
484 }
485
486 void
tagging_record_test(void)487 tagging_record_test(void)
488 {
489 struct evbuffer *tmp = evbuffer_new();
490 struct record one, two;
491 uint32_t length = 0;
492
493 memset(&one, 0, sizeof(one));
494 memset(&two, 0, sizeof(two));
495
496 TAILQ_INIT(&one.hashes);
497 addr_pton("127.0.0.1", &one.src);
498 addr_pton("192.168.0.1", &one.dst);
499 gettimeofday(&one.tv_start, NULL);
500 one.proto = IP_PROTO_TCP;
501 one.os_fp = "Honeyd Machine";
502 one.bytes = 100;
503
504 record_marshal(tmp, &one);
505 if (tag_peek_length(tmp, &length) == -1 || length == 0)
506 errx(1, "tag_peek_length failed.");
507
508 if (record_unmarshal(&two, tmp) == -1)
509 errx(1, "record unmarshal failed.");
510 if (strcmp(one.os_fp, two.os_fp) != 0)
511 errx(1, "fingerprints not the same");
512
513 /* Equal out the variable fields */
514 free(two.os_fp); two.os_fp = one.os_fp;
515 two.hashes = one.hashes;
516
517 if (memcmp(&one, &two, sizeof(one)) != 0)
518 errx(1, "records not the same");
519
520 evbuffer_free(tmp);
521
522 fprintf(stderr, "\t%s: OK\n", __func__);
523 }
524
525 void
tagging_fuzz()526 tagging_fuzz()
527 {
528 u_char buffer[4096];
529 struct evbuffer *tmp = evbuffer_new();
530 rand_t *rand = rand_open();
531 struct record record;
532 struct addr addr;
533 int i, j;
534
535 for (j = 0; j < 100; j++) {
536 for (i = 0; i < sizeof(buffer); i++)
537 buffer[i] = rand_uint8(rand);
538 evbuffer_drain(tmp, -1);
539 evbuffer_add(tmp, buffer, sizeof(buffer));
540
541 if (tag_unmarshal_record(tmp, 1, &record) != -1)
542 errx(1, "tag_unmarshal_record should have failed");
543 if (addr_unmarshal(&addr, tmp) != -1)
544 errx(1, "addr_unmarshal should have failed");
545 if (record_unmarshal(&record, tmp) != -1)
546 errx(1, "record_unmarshal should have failed");
547 }
548
549 /* Now insert some corruption into the tag length field */
550 evbuffer_drain(tmp, -1);
551 addr_pton("127.0.0.0/20", &addr);
552 addr_marshal(tmp, &addr);
553 evbuffer_add(tmp, buffer, sizeof(buffer));
554
555 EVBUFFER_DATA(tmp)[1] = 0xff;
556 if (addr_unmarshal(&addr, tmp) != -1)
557 errx(1, "addr_unmarshal should have failed");
558
559 evbuffer_free(tmp);
560
561 rand_close(rand);
562 fprintf(stderr, "\t%s: OK\n", __func__);
563 }
564
565 void
tagging_test(void)566 tagging_test(void)
567 {
568 tagging_init();
569 tagging_int_test();
570 tagging_addr_test();
571 tagging_record_test();
572 tagging_fuzz();
573 }
574