1 /*
2 * Copyright (c) 2001 Mark Fullmer and The Ohio State University
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: ftxlate.c,v 1.6 2005/05/11 14:03:30 maf Exp $
27 */
28
29 #include "ftconfig.h"
30 #include "ftlib.h"
31
32 #ifdef HAVE_OPENSSL
33 #define free_func ssl_free_func /* hack, zlib uses free_func also */
34 #include <openssl/ssl.h>
35 #include <openssl/evp.h>
36 #undef free_func
37 #endif /* HAVE_OPENSSL */
38
39 #include <sys/time.h>
40 #include <sys/types.h>
41 #include <sys/uio.h>
42 #include <sys/socket.h>
43 #include <sys/resource.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46 #include <sys/stat.h>
47 #include <syslog.h>
48 #include <dirent.h>
49 #include <limits.h>
50 #include <unistd.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <time.h>
54 #include <fcntl.h>
55 #include <zlib.h>
56
57 #if HAVE_STRINGS_H
58 #include <strings.h>
59 #endif
60 #if HAVE_STRING_H
61 #include <string.h>
62 #endif
63
64 #if HAVE_INTTYPES_H
65 # include <inttypes.h> /* C99 uint8_t uint16_t uint32_t uint64_t */
66 #elif HAVE_STDINT_H
67 # include <stdint.h> /* or here */
68 #endif /* else commit suicide. later */
69
70 #if !HAVE_STRSEP
71 char *strsep (char **, const char *);
72 #endif
73
74 struct cryptopan {
75 uint8_t m_key[16]; /* 128 bit secret key */
76 uint8_t m_pad[16]; /* 128 bit secret pad */
77 #ifdef HAVE_OPENSSL
78 EVP_CIPHER_CTX *cipher_ctx; /* openssl cipher context */
79 #endif /* HAVE_OPENSSL */
80 };
81
82 static int cryptopan_anon(struct cryptopan *cp, uint32_t orig_addr,
83 uint32_t *new_addr);
84 static int cryptopan_free(struct cryptopan *cp);
85 static int cryptopan_init(struct cryptopan *cp, unsigned char *key);
86
87 static int load_key_file(char *fname, unsigned char *key);
88
89 struct line_parser {
90 struct ftxlate_action *cur_action;
91 struct ftxlate_def *cur_def;
92 struct ftxlate_def_term *cur_def_term;
93 int state, type;
94 int lineno;
95 char *buf, *word;
96 const char *fname;
97 };
98
99 #define FT_XLATE_TYPE_IP_SRC_ADDR2NET 0x1
100 #define FT_XLATE_TYPE_IP_DST_ADDR2NET 0x2
101 #define FT_XLATE_TYPE_IP_SRC_ADDR2CNET 0x3
102 #define FT_XLATE_TYPE_IP_DST_ADDR2CNET 0x4
103 #define FT_XLATE_TYPE_IP_ADDR_PRIV_MASK 0x5
104 #define FT_XLATE_TYPE_TAG_MASK 0x6
105 #define FT_XLATE_TYPE_SCALE 0x7
106 #define FT_XLATE_TYPE_SRC_AS 0x8
107 #define FT_XLATE_TYPE_DST_AS 0x9
108 #define FT_XLATE_TYPE_IP_PORT_PRIV_MASK 0xA
109 #define FT_XLATE_TYPE_IP_ADDR_ANON 0xB
110 #define FT_XLATE_TYPE_IP_SRC_ADDR_ANON 0xC
111 #define FT_XLATE_TYPE_IP_DST_ADDR_ANON 0xD
112 #define FT_XLATE_FLAG_STOP 0x1
113 #define FT_XLATE_ALG_CRYPTOPAN_AES128 0x1
114
115 struct ftxlate_action {
116 FT_SLIST_ENTRY(ftxlate_action) chain; /* list of all actions */
117 int type; /* FT_XLATE_TYPE_MATCH_* */
118 char *name;
119 void *action;
120 void (*eval)(struct ftxlate_action *ftxa, char *rec,
121 struct fts3rec_offsets *fo);
122 uint64_t xfields;
123 };
124
125 struct ftxlate_def_term {
126 FT_STAILQ_ENTRY(ftxlate_def_term) chain; /* list of terms */
127 FT_STAILQ_HEAD(xactdhead, ftxlate_def_term_actions) actions; /* actions */
128 int type; /* FT_XLATE_TYPE_MATCH_* */
129 struct ftfil_def *ftfd; /* filter definition */
130 int flags;
131 uint64_t xfields;
132 };
133
134 struct ftxlate_def_term_actions {
135 FT_STAILQ_ENTRY(ftxlate_def_term_actions) chain; /* all actions */
136 struct ftxlate_action *action; /* filled in by resolve_actions */
137 char *name; /* temporary, invalid after config file is closed */
138 };
139
140 struct ftxlate_def {
141 FT_SLIST_ENTRY(ftxlate_def) chain;
142 FT_STAILQ_HEAD(xdthead, ftxlate_def_term) terms; /* terms */
143 char *name;
144 uint64_t xfields;
145 };
146
147 struct ftxlate_act_scale {
148 int scale;
149 };
150
151 struct ftxlate_act_asn {
152 uint16_t as;
153 };
154 struct ftxlate_act_tag_mask {
155 uint32_t src_mask;
156 uint32_t dst_mask;
157 };
158
159 struct ftxlate_act_ip_addr_priv_mask {
160 uint32_t src_mask;
161 uint32_t dst_mask;
162 };
163
164 struct ftxlate_act_ip_port_priv_mask {
165 uint16_t src_mask;
166 uint16_t dst_mask;
167 };
168 struct ftxlate_act_ip_addr_anon {
169 int init;
170 int algorithm; /* algorithm - cryptopan only for now */
171 char *key_fname; /* file containing a key, null if not used */
172 unsigned char key[32]; /* key */
173 time_t key_refresh_next; /* next key refresh */
174 time_t key_refresh_interval; /* key refresh check rate */
175 struct cryptopan cp; /* cryptopan context */
176 };
177
178
179 static int parse_action(struct line_parser *lp, struct ftxlate *ftxlate);
180 static int parse_action_type(struct line_parser *lp, struct ftxlate *ftxlate);
181 static int parse_action_mask(struct line_parser *lp, struct ftxlate *ftxlate);
182 static int parse_action_scale(struct line_parser *lp, struct ftxlate *ftxlate);
183 static int parse_action_asn(struct line_parser *lp, struct ftxlate *ftxlate);
184 static int parse_action_algorithm(struct line_parser *lp,
185 struct ftxlate *ftxlate);
186 static int parse_action_key(struct line_parser *lp,
187 struct ftxlate *ftxlate);
188 static int parse_action_key_file(struct line_parser *lp,
189 struct ftxlate *ftxlate);
190 static int parse_action_key_refresh(struct line_parser *lp,
191 struct ftxlate *ftxlate);
192
193 static int decode_hex(char *in, int in_len, unsigned char *out, int out_len);
194
195 static int parse_def(struct line_parser *lp, struct ftxlate *ftxlate);
196 static int parse_def_term(struct line_parser *lp, struct ftxlate *ftxlate);
197 static int parse_def_filter(struct line_parser *lp, struct ftxlate *ftxlate);
198 static int parse_def_action(struct line_parser *lp, struct ftxlate *ftxlate);
199 static int parse_def_stop(struct line_parser *lp, struct ftxlate *ftxlate);
200 static int resolve_actions(struct ftxlate *ftxlate);
201 static int parse_include_filter(struct line_parser *lp,
202 struct ftxlate *ftxlate);
203
204 static int load_filters(struct ftxlate *ftxlate);
205
206 static void eval_ip_src_addr2net(struct ftxlate_action *ftxa,
207 char *rec, struct fts3rec_offsets *fo);
208 static void eval_ip_dst_addr2net(struct ftxlate_action *ftxa,
209 char *rec, struct fts3rec_offsets *fo);
210 static void eval_ip_src_addr2cnet(struct ftxlate_action *ftxa,
211 char *rec, struct fts3rec_offsets *fo);
212 static void eval_ip_dst_addr2cnet(struct ftxlate_action *ftxa,
213 char *rec, struct fts3rec_offsets *fo);
214 static void eval_ip_addr_privacy_mask(struct ftxlate_action *ftxa,
215 char *rec, struct fts3rec_offsets *fo);
216 static void eval_ip_port_privacy_mask(struct ftxlate_action *ftxa,
217 char *rec, struct fts3rec_offsets *fo);
218 static void eval_scale(struct ftxlate_action *ftxa,
219 char *rec, struct fts3rec_offsets *fo);
220 static void eval_tag_mask(struct ftxlate_action *ftxa,
221 char *rec, struct fts3rec_offsets *fo);
222 static void eval_src_asn(struct ftxlate_action *ftxa,
223 char *rec, struct fts3rec_offsets *fo);
224 static void eval_dst_asn(struct ftxlate_action *ftxa,
225 char *rec, struct fts3rec_offsets *fo);
226 static void eval_ip_src_addr_anon(struct ftxlate_action *ftxa,
227 char *rec, struct fts3rec_offsets *fo);
228 static void eval_ip_dst_addr_anon(struct ftxlate_action *ftxa,
229 char *rec, struct fts3rec_offsets *fo);
230 static void eval_ip_addr_anon(struct ftxlate_action *ftxa,
231 char *rec, struct fts3rec_offsets *fo);
232
233 #define PARSE_STATE_ACTION 0x1
234 #define PARSE_STATE_DEFINITION 0x2
235
236 #define NEXT_WORD(A,B)\
237 for (;;) {\
238 B = strsep(A, " \t");\
239 if ((B && *B != 0) || (!B))\
240 break;\
241 }\
242
243 struct jump {
244 char *name;
245 int state;
246 int (*func)(struct line_parser *lp, struct ftxlate *ftxlate);
247 };
248
249 static struct jump pjump[] = {
250 {"include-filter", 0, parse_include_filter},
251 {"xlate-action", 0, parse_action},
252 {"type", PARSE_STATE_ACTION, parse_action_type},
253 {"mask", PARSE_STATE_ACTION, parse_action_mask},
254 {"scale", PARSE_STATE_ACTION, parse_action_scale},
255 {"as", PARSE_STATE_ACTION, parse_action_asn},
256 {"key", PARSE_STATE_ACTION, parse_action_key},
257 {"key-file", PARSE_STATE_ACTION, parse_action_key_file},
258 {"key-file-refresh", PARSE_STATE_ACTION, parse_action_key_refresh},
259 {"algorithm", PARSE_STATE_ACTION, parse_action_algorithm},
260 {"xlate-definition", 0, parse_def},
261 {"term", PARSE_STATE_DEFINITION, parse_def_term},
262 {"filter", PARSE_STATE_DEFINITION, parse_def_filter},
263 {"stop", PARSE_STATE_DEFINITION, parse_def_stop},
264 {"action", PARSE_STATE_DEFINITION, parse_def_action},
265 {0, 0, 0},
266 };
267 /*
268 * data structures:
269 *
270 *
271 * ftxlate holds the head pointers to a list of actions, and definitions.
272 *
273 * Each definition holds a list of terms. A term is a combination of
274 * a filter and a list of actions
275 *
276 * struct ftxlate_def : linked list of definitions
277 * struct ftxlate_action : linked list of actions
278 * struct ftxlate_def_term : each term in a definition
279 * struct ftxlate_def_term_actions : each action in a term
280 *
281 * actions contain one of the following:
282 * - note for some actions no additional data is required and action
283 * will be null
284 *
285 * struct ftxlate_act_scale : scale
286 * struct ftxlate_act_tag_mask : source and destination tag mask
287 * struct ftxlate_act_priv_mask : source and destination privacy mask
288 * struct ftxlate_port_priv_mask : source and destination privacy mask
289 * struct ftxlate_act_asn : replacement ASN
290 *
291 *
292 */
293
294 /*
295 * function: ftxlate_load
296 *
297 * Process fname into ftxlate.
298 *
299 * returns: 0 ok
300 * <0 fail
301 */
ftxlate_load(struct ftxlate * ftxlate,struct ftvar * ftvar,const char * fname)302 int ftxlate_load(struct ftxlate *ftxlate, struct ftvar *ftvar, const char *fname)
303 {
304 struct stat sb;
305 struct jump *jmp;
306 struct line_parser lp;
307 int fd, ret, found;
308 char *buf, *buf2, *c;
309 char sbuf[FT_LP_MAXLINE];
310
311 ret = -1;
312 buf = (char*)0L;
313 bzero(&lp, sizeof lp);
314 bzero(ftxlate, sizeof *ftxlate);
315
316 FT_SLIST_INIT(&ftxlate->defs);
317 FT_SLIST_INIT(&ftxlate->actions);
318
319 lp.fname = fname;
320
321 if ((fd = open(fname, O_RDONLY, 0)) < 0) {
322 fterr_warn("open(%s)", fname);
323 goto load_xlate_out;
324 }
325
326 if (fstat(fd, &sb) < 0) {
327 fterr_warn("stat(%s)", fname);
328 goto load_xlate_out;
329 }
330
331 /* allocate storage for file */
332 if (!(buf = malloc(sb.st_size+1))) {
333 fterr_warn("malloc()");
334 goto load_xlate_out;
335 }
336
337 /* read in file */
338 if (read(fd, buf, sb.st_size) != sb.st_size) {
339 fterr_warnx("read(%s): short", fname);
340 goto load_xlate_out;
341 }
342
343 /* null terminate file */
344 buf[sb.st_size] = 0;
345
346 buf2 = buf;
347
348 for (;;) {
349
350 /* rip a line */
351 for (;;) {
352 c = strsep(&buf2, "\n");
353 ++lp.lineno;
354 if ((c && *c != 0) || (!c))
355 break;
356 }
357
358 /* no more lines */
359 if (!c) {
360 goto load_xlate_done;
361 }
362
363 /* do variable substitutions first */
364 if (ftvar) {
365 if (ftvar_evalstr(ftvar, c, sbuf, sizeof(sbuf)) < 0) {
366 fterr_warnx("ftvar_evalstr(): failed");
367 goto load_xlate_done;
368 }
369 } else {
370 strncpy(sbuf, c, sizeof(sbuf));
371 sbuf[sizeof(sbuf)-1] = 0;
372 }
373
374 lp.buf = sbuf;
375
376 /* first word */
377 NEXT_WORD(&lp.buf, c);
378
379 /* whitespace only line */
380 if (!c) {
381 continue;
382 }
383
384 /* comment line */
385 if (c && *c == '#')
386 continue;
387
388 for (jmp = pjump; jmp->name; ++jmp) {
389
390 found = 0;
391
392 if (((!jmp->state) || (jmp->state & lp.state))
393 && (!strcasecmp(c, jmp->name))) {
394
395 found = 1;
396
397 if (jmp->func(&lp, ftxlate))
398 goto load_xlate_out;
399
400 NEXT_WORD(&lp.buf, c);
401
402 if (c) {
403 fterr_warnx("%s line %d: Unexpected \"%s\".", lp.fname, lp.lineno, c);
404 goto load_xlate_out;
405 }
406
407 break;
408
409 }
410
411 } /* test each word */
412
413 if (!found) {
414 fterr_warnx("%s line %d: Unexpected \"%s\".", lp.fname, lp.lineno, c);
415 goto load_xlate_out;
416 }
417
418 } /* more lines */
419
420 load_xlate_done:
421
422 if (resolve_actions(ftxlate))
423 goto load_xlate_out;
424
425 ret = 0;
426
427 load_xlate_out:
428
429 if (fd != -1)
430 close(fd);
431
432 if (buf)
433 free(buf);
434
435 if (ret == -1)
436 ftxlate_free(ftxlate);
437
438 return ret;
439
440 } /* ftxlate_load */
441
442 /*
443 * function: ftxlate_defintion_find
444 *
445 * Return a pointer to a ftxlate_def_actionup for use later with
446 * ftxlate_def_eval
447 *
448 */
ftxlate_def_find(struct ftxlate * ftxlate,const char * name)449 struct ftxlate_def *ftxlate_def_find(struct ftxlate *ftxlate, const char *name)
450 {
451 struct ftxlate_def *ftx;
452
453 /* foreach definition */
454 FT_SLIST_FOREACH(ftx, &ftxlate->defs, chain) {
455
456 if (!(strcasecmp(ftx->name, name)))
457 return ftx;
458
459 }
460
461 return (struct ftxlate_def*)0L;
462
463 } /* ftxlate_def_find */
464
465 /*
466 * function: ftxlate_def_test_xfields
467 *
468 * Check if fields in current flow are valid for a xlate definition -- ie
469 * the definition does not reference a field not contained in the flow.
470 *
471 * returns: 0 okay
472 * 1 fail
473 */
ftxlate_def_test_xfields(struct ftxlate_def * active_def,uint64_t test)474 int ftxlate_def_test_xfields(struct ftxlate_def *active_def, uint64_t test)
475 {
476
477 if ((active_def->xfields & test) != active_def->xfields)
478 return 1;
479 else
480 return 0;
481
482 } /* ftxlate_def_test_xfields */
483
484 /*
485 * function: ftxlate_free
486 *
487 * free resources allocated by ftxlate_load()
488 *
489 */
ftxlate_free(struct ftxlate * ftxlate)490 void ftxlate_free(struct ftxlate *ftxlate)
491 {
492 struct ftxlate_action *ftxa;
493 struct ftxlate_def *ftx;
494 struct ftxlate_def_term *ftxt;
495 struct ftxlate_def_term_actions *ftxta;
496 struct ftxlate_act_ip_addr_anon *ftxiaa;
497
498 if (ftxlate->ftfil_init)
499 ftfil_free(&ftxlate->ftfil);
500
501 if (ftxlate->filter_fname)
502 free(ftxlate->filter_fname);
503
504 /* foreach action, remove the action and associated storge */
505 while (!FT_SLIST_EMPTY(&ftxlate->actions)) {
506
507 ftxa = FT_SLIST_FIRST(&ftxlate->actions);
508
509 FT_SLIST_REMOVE_HEAD(&ftxlate->actions, chain);
510
511 if (ftxa->action) {
512
513 /* *_ANON allocated internal resources */
514 if ((ftxa->type == FT_XLATE_TYPE_IP_ADDR_ANON) ||
515 (ftxa->type == FT_XLATE_TYPE_IP_SRC_ADDR_ANON) ||
516 (ftxa->type == FT_XLATE_TYPE_IP_DST_ADDR_ANON)) {
517
518 ftxiaa = ftxa->action;
519
520 if (ftxiaa->key_fname)
521 free(ftxiaa->key_fname);
522
523 if (ftxiaa->init)
524 cryptopan_free(&ftxiaa->cp);
525
526 } /* type *_ANON */
527
528 free(ftxa->action);
529
530 }
531
532 free(ftxa->name);
533 free(ftxa);
534
535 } /* while */
536
537 /* foreach definition, remove the definition and associated storage */
538 while (!FT_SLIST_EMPTY(&ftxlate->defs)) {
539
540 ftx = FT_SLIST_FIRST(&ftxlate->defs);
541
542 FT_SLIST_REMOVE_HEAD(&ftxlate->defs, chain);
543
544 /* foreach term in the definition */
545 while (!FT_STAILQ_EMPTY(&ftx->terms)) {
546
547 ftxt = FT_STAILQ_FIRST(&ftx->terms);
548
549 while (!FT_STAILQ_EMPTY(&ftxt->actions)) {
550
551 ftxta = FT_STAILQ_FIRST(&ftxt->actions);
552
553 if (ftxta->name)
554 free(ftxta->name);
555
556 FT_STAILQ_REMOVE_HEAD(&ftxt->actions, chain);
557
558 free(ftxta);
559
560 }
561
562 FT_STAILQ_REMOVE_HEAD(&ftx->terms, chain);
563
564 free (ftxt);
565
566 }
567
568 free(ftx->name);
569 free(ftx);
570
571 } /* while */
572
573 } /* ftxlate_free */
574
575 /*
576 * function: ftxlate_def_eval
577 *
578 * perform tag actions on a flow
579 *
580 * run down each term in the definition
581 * evaluate the filter, if okay
582 * run every action
583 *
584 * the filter is activated by
585 * FT_TAG_DEF_FILTER_INPUT - check input
586 * FT_TAG_DEF_FILTER_OUTPUT check output
587 * FT_TAG_DEF_FILTER_EXPORTER check exporter
588 *
589 *
590 * returns 0
591 */
ftxlate_def_eval(struct ftxlate_def * ftx,char * rec,struct fts3rec_offsets * fo)592 int ftxlate_def_eval(struct ftxlate_def *ftx,
593 char *rec, struct fts3rec_offsets *fo)
594 {
595 struct ftxlate_def_term *ftxt;
596 struct ftxlate_def_term_actions *ftxta;
597 struct ftxlate_action *ftxa;
598 int fpermit, stop;
599
600 /* early termination? */
601 stop = 0;
602
603 /* foreach term in the definition */
604 FT_STAILQ_FOREACH(ftxt, &ftx->terms, chain) {
605
606 /*
607 * if the filter allows this flow then call the xlate evaluation, else
608 * leave it alone.
609 */
610
611 /* this filter did not permit an action */
612 fpermit = 0;
613
614 if (ftxt->ftfd &&
615 ftfil_def_eval(ftxt->ftfd, rec, fo) == FT_FIL_MODE_DENY)
616 continue;
617 else
618 fpermit = 1;
619
620 /* stop after this term? */
621 if (fpermit && (ftxt->flags & FT_XLATE_FLAG_STOP))
622 stop = 1;
623
624 /* for every action chained to this term */
625 FT_STAILQ_FOREACH(ftxta, &ftxt->actions, chain) {
626
627 /* the action */
628 ftxa = ftxta->action;
629
630 /* based on the type do the action if a match is made */
631 ftxa->eval(ftxa, rec, fo);
632
633 } /* foreach action references by the term */
634
635 /* early termination due to stop keyword? */
636 if (stop)
637 break;
638
639 } /* foreach term */
640
641 return 0;
642
643 } /* ftxlate_def_eval */
644
645
646 /*
647 * function: parse_action
648 *
649 * process the 'action' line. Each action has a unique name which
650 * is added to the ftxlate->actions linked list. The current action is
651 * updated in lp. Actions by themself do nothing, they must be pointed
652 * to by a definition.
653 *
654 * returns: 0 ok
655 * <0 fail
656 */
parse_action(struct line_parser * lp,struct ftxlate * ftxlate)657 int parse_action(struct line_parser *lp, struct ftxlate *ftxlate)
658 {
659 struct ftxlate_action *ftxa;
660
661 NEXT_WORD(&lp->buf, lp->word);
662
663 if (!lp->word) {
664 fterr_warnx("%s line %d: Expecting name.", lp->fname, lp->lineno);
665 return -1;
666 }
667
668 /* check if it exists */
669 FT_SLIST_FOREACH(ftxa, &ftxlate->actions, chain) {
670
671 if (!strcasecmp(lp->word, ftxa->name)) {
672 fterr_warnx("%s line %d: Name (%s) previously defined.", lp->fname,
673 lp->lineno, lp->word);
674 return -1;
675 }
676
677 }
678
679 /* no, add a new entry to the list */
680 if (!(ftxa = (struct ftxlate_action*)malloc(sizeof
681 (struct ftxlate_action)))) {
682 fterr_warn("malloc()");
683 return -1;
684 }
685
686 bzero(ftxa, sizeof *ftxa);
687
688 if (!(ftxa->name = (char*)malloc(strlen(lp->word)+1))) {
689 fterr_warn("malloc()");
690 free(ftxa);
691 return -1;
692 }
693
694 strcpy(ftxa->name, lp->word);
695
696 FT_SLIST_INSERT_HEAD(&ftxlate->actions, ftxa, chain);
697
698 lp->state = PARSE_STATE_ACTION;
699 lp->cur_action = ftxa;
700
701 return 0;
702
703 } /* parse_action */
704
705 /*
706 * function: parse_action_type
707 *
708 * process the 'type' line. When the type is set the initial storage
709 * is allocated if necessary.
710 *
711 * returns: 0 ok
712 * <0 fail
713 */
parse_action_type(struct line_parser * lp,struct ftxlate * ftxlate)714 int parse_action_type(struct line_parser *lp, struct ftxlate *ftxlate)
715 {
716
717 if (!lp->cur_action) {
718 fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
719 return -1;
720 }
721
722 NEXT_WORD(&lp->buf, lp->word);
723
724 if (!lp->word) {
725 fterr_warnx("%s line %d: Expecting type.", lp->fname, lp->lineno);
726 return -1;
727 }
728
729 if (lp->cur_action->type) {
730 fterr_warnx("%s line %d: Type previously defined.", lp->fname, lp->lineno);
731 return -1;
732 }
733
734 if (!strcasecmp(lp->word, "ip-source-address-to-network")) {
735 lp->cur_action->type = FT_XLATE_TYPE_IP_SRC_ADDR2NET;
736 lp->cur_action->eval = eval_ip_src_addr2net;
737 lp->cur_action->xfields |= (FT_XFIELD_SRCADDR|FT_XFIELD_SRC_MASK);
738 } else if (!strcasecmp(lp->word, "ip-destination-address-to-network")) {
739 lp->cur_action->type = FT_XLATE_TYPE_IP_DST_ADDR2NET;
740 lp->cur_action->eval = eval_ip_dst_addr2net;
741 lp->cur_action->xfields |= (FT_XFIELD_DSTADDR|FT_XFIELD_DST_MASK);
742 } else if (!strcasecmp(lp->word, "ip-source-address-to-class-network")) {
743 lp->cur_action->type = FT_XLATE_TYPE_IP_SRC_ADDR2CNET;
744 lp->cur_action->eval = eval_ip_src_addr2cnet;
745 lp->cur_action->xfields |= FT_XFIELD_SRCADDR;
746 } else if (!strcasecmp(lp->word, "ip-destination-address-to-class-network")) {
747 lp->cur_action->type = FT_XLATE_TYPE_IP_DST_ADDR2CNET;
748 lp->cur_action->eval = eval_ip_dst_addr2cnet;
749 lp->cur_action->xfields |= FT_XFIELD_DSTADDR;
750 } else if (!strcasecmp(lp->word, "ip-address-privacy-mask")) {
751 lp->cur_action->type = FT_XLATE_TYPE_IP_ADDR_PRIV_MASK;
752 lp->cur_action->eval = eval_ip_addr_privacy_mask;
753 lp->cur_action->xfields |= (FT_XFIELD_DSTADDR|FT_XFIELD_SRCADDR);
754 } else if (!strcasecmp(lp->word, "ip-port-privacy-mask")) {
755 lp->cur_action->type = FT_XLATE_TYPE_IP_PORT_PRIV_MASK;
756 lp->cur_action->eval = eval_ip_port_privacy_mask;
757 lp->cur_action->xfields |= (FT_XFIELD_DSTPORT|FT_XFIELD_SRCPORT);
758 } else if (!strcasecmp(lp->word, "scale")) {
759 lp->cur_action->type = FT_XLATE_TYPE_SCALE;
760 lp->cur_action->eval = eval_scale;
761 lp->cur_action->xfields |= (FT_XFIELD_DPKTS|FT_XFIELD_DOCTETS);
762 } else if (!strcasecmp(lp->word, "tag-mask")) {
763 lp->cur_action->type = FT_XLATE_TYPE_TAG_MASK;
764 lp->cur_action->eval = eval_tag_mask;
765 lp->cur_action->xfields |= (FT_XFIELD_SRC_TAG|FT_XFIELD_DST_TAG);
766 } else if (!strcasecmp(lp->word, "replace-source-as0")) {
767 lp->cur_action->type = FT_XLATE_TYPE_SRC_AS;
768 lp->cur_action->eval = eval_src_asn;
769 lp->cur_action->xfields |= FT_XFIELD_SRC_AS;
770 } else if (!strcasecmp(lp->word, "replace-destination-as0")) {
771 lp->cur_action->type = FT_XLATE_TYPE_DST_AS;
772 lp->cur_action->eval = eval_dst_asn;
773 lp->cur_action->xfields |= FT_XFIELD_DST_AS;
774 } else if (!strcasecmp(lp->word, "ip-source-address-anonymize")) {
775 lp->cur_action->type = FT_XLATE_TYPE_IP_SRC_ADDR_ANON;
776 lp->cur_action->eval = eval_ip_src_addr_anon;
777 lp->cur_action->xfields |= FT_XFIELD_SRCADDR;
778 } else if (!strcasecmp(lp->word, "ip-destination-address-anonymize")) {
779 lp->cur_action->type = FT_XLATE_TYPE_IP_DST_ADDR_ANON;
780 lp->cur_action->eval = eval_ip_dst_addr_anon;
781 lp->cur_action->xfields |= FT_XFIELD_DSTADDR;
782 } else if (!strcasecmp(lp->word, "ip-address-anonymize")) {
783 lp->cur_action->type = FT_XLATE_TYPE_IP_ADDR_ANON;
784 lp->cur_action->eval = eval_ip_addr_anon;
785 lp->cur_action->xfields |= (FT_XFIELD_SRCADDR|FT_XFIELD_DSTADDR);
786 } else {
787 fterr_warnx("%s line %d: Unrecognized type.", lp->fname, lp->lineno);
788 return -1;
789 }
790
791 /* allocate storage for action if required */
792
793 if ((lp->cur_action->type == FT_XLATE_TYPE_IP_ADDR_PRIV_MASK) == 1) {
794
795 if (!(lp->cur_action->action = malloc(sizeof
796 (struct ftxlate_act_ip_addr_priv_mask)))) {
797 fterr_warn("malloc()");
798 return -1;
799 }
800
801 bzero(lp->cur_action->action, sizeof
802 (struct ftxlate_act_ip_addr_priv_mask));
803
804 } else if ((lp->cur_action->type == FT_XLATE_TYPE_IP_PORT_PRIV_MASK) == 1) {
805
806 if (!(lp->cur_action->action = malloc(sizeof
807 (struct ftxlate_act_ip_port_priv_mask)))) {
808 fterr_warn("malloc()");
809 return -1;
810 }
811
812 bzero(lp->cur_action->action, sizeof
813 (struct ftxlate_act_ip_port_priv_mask));
814
815 } else if (lp->cur_action->type == FT_XLATE_TYPE_TAG_MASK) {
816
817 if (!(lp->cur_action->action = malloc(sizeof
818 (struct ftxlate_act_tag_mask)))) {
819 fterr_warn("malloc()");
820 return -1;
821 }
822
823 bzero(lp->cur_action->action, sizeof (struct ftxlate_act_tag_mask));
824
825 } else if (lp->cur_action->type == FT_XLATE_TYPE_SCALE) {
826
827 if (!(lp->cur_action->action = malloc(sizeof (struct ftxlate_act_scale)))) {
828 fterr_warn("malloc()");
829 return -1;
830 }
831
832 bzero(lp->cur_action->action, sizeof (struct ftxlate_act_scale));
833
834 } else if ((lp->cur_action->type == FT_XLATE_TYPE_SRC_AS) ||
835 (lp->cur_action->type == FT_XLATE_TYPE_DST_AS)) {
836
837 if (!(lp->cur_action->action = malloc(sizeof (struct ftxlate_act_asn)))) {
838 fterr_warn("malloc()");
839 return -1;
840 }
841
842 bzero(lp->cur_action->action, sizeof (struct ftxlate_act_asn));
843
844 } else if ((lp->cur_action->type == FT_XLATE_TYPE_IP_SRC_ADDR_ANON) ||
845 (lp->cur_action->type == FT_XLATE_TYPE_IP_ADDR_ANON) ||
846 (lp->cur_action->type == FT_XLATE_TYPE_IP_DST_ADDR_ANON)) {
847
848 if (!(lp->cur_action->action =
849 malloc(sizeof (struct ftxlate_act_ip_addr_anon)))) {
850 fterr_warn("malloc()");
851 return -1;
852 }
853
854 bzero(lp->cur_action->action, sizeof (struct ftxlate_act_ip_addr_anon));
855
856 }
857
858
859 return 0;
860
861 } /* parse_action_type */
862
863 /*
864 * function: parse_action_mask
865 *
866 * process the 'mask' line in an action. Handles the tag-mask
867 * ip-address-privacy-mask and port-number-privacy-mask actions.
868 *
869 * returns: 0 ok
870 * <0 fail
871 */
parse_action_mask(struct line_parser * lp,struct ftxlate * ftxlate)872 int parse_action_mask(struct line_parser *lp, struct ftxlate *ftxlate)
873 {
874 struct ftxlate_act_tag_mask *ftxatm;
875 struct ftxlate_act_ip_addr_priv_mask *ftxaiapm;
876 struct ftxlate_act_ip_port_priv_mask *ftxaippm;
877 uint32_t src_mask, dst_mask;
878 char *src_maskc, *dst_maskc;
879
880 if (!lp->cur_action->type) {
881 fterr_warnx("%s line %d: Must set type first.", lp->fname, lp->lineno);
882 return -1;
883 }
884
885 if ((lp->cur_action->type != FT_XLATE_TYPE_IP_ADDR_PRIV_MASK) &&
886 (lp->cur_action->type != FT_XLATE_TYPE_TAG_MASK) &&
887 (lp->cur_action->type != FT_XLATE_TYPE_IP_PORT_PRIV_MASK)) {
888 fterr_warnx("%s line %d: Illegal keyword.", lp->fname, lp->lineno);
889 return -1;
890 }
891
892 ftxatm = lp->cur_action->action;
893 ftxaiapm = lp->cur_action->action;
894 ftxaippm = lp->cur_action->action;
895
896 NEXT_WORD(&lp->buf, lp->word);
897
898 if (!lp->word) {
899 fterr_warnx("%s line %d: Expecting source mask.", lp->fname, lp->lineno);
900 return -1;
901 }
902
903 src_maskc = lp->word;
904
905 NEXT_WORD(&lp->buf, lp->word);
906
907 if (!lp->word) {
908 fterr_warnx("%s line %d: Expecting destination mask.",
909 lp->fname, lp->lineno);
910 return -1;
911 }
912
913 dst_maskc = lp->word;
914
915 src_mask = strtoull(src_maskc, (char**)0L, 0);
916 dst_mask = strtoull(dst_maskc, (char**)0L, 0);
917
918 if (lp->cur_action->type == FT_XLATE_TYPE_TAG_MASK) {
919 ftxatm->src_mask = src_mask;
920 ftxatm->dst_mask = dst_mask;
921 } else if (lp->cur_action->type == FT_XLATE_TYPE_IP_ADDR_PRIV_MASK) {
922 ftxaiapm->src_mask = src_mask;
923 ftxaiapm->dst_mask = dst_mask;
924 } else if (lp->cur_action->type == FT_XLATE_TYPE_IP_PORT_PRIV_MASK) {
925 ftxaippm->src_mask = src_mask;
926 ftxaippm->dst_mask = dst_mask;
927 } else {
928 fterr_errx(1, "parse_action_match(): internal error");
929 }
930
931 return 0;
932
933 } /* parse_action_mask */
934
935 /*
936 * function: parse_action_scale
937 *
938 * process the 'scale' line in an action.
939 *
940 * returns: 0 ok
941 * <0 fail
942 */
parse_action_scale(struct line_parser * lp,struct ftxlate * ftxlate)943 int parse_action_scale(struct line_parser *lp, struct ftxlate *ftxlate)
944 {
945 struct ftxlate_act_scale *ftxs;
946
947 if (!lp->cur_action->type) {
948 fterr_warnx("%s line %d: Must set type first.", lp->fname, lp->lineno);
949 return -1;
950 }
951
952 if (lp->cur_action->type != FT_XLATE_TYPE_SCALE) {
953 fterr_warnx("%s line %d: Illegal keyword.", lp->fname, lp->lineno);
954 return -1;
955 }
956
957 ftxs = lp->cur_action->action;
958
959 NEXT_WORD(&lp->buf, lp->word);
960
961 if (!lp->word) {
962 fterr_warnx("%s line %d: Expecting scale.", lp->fname, lp->lineno);
963 return -1;
964 }
965
966 ftxs->scale = atoi(lp->word);
967
968 return 0;
969
970 } /* parse_action_scale */
971
972 /*
973 * function: parse_action_asn
974 *
975 * process the 'as' line in an action.
976 *
977 * returns: 0 ok
978 * <0 fail
979 */
parse_action_asn(struct line_parser * lp,struct ftxlate * ftxlate)980 int parse_action_asn(struct line_parser *lp, struct ftxlate *ftxlate)
981 {
982 struct ftxlate_act_asn *ftxasn;
983
984 if (!lp->cur_action->type) {
985 fterr_warnx("%s line %d: Must set type first.", lp->fname, lp->lineno);
986 return -1;
987 }
988
989 if ((lp->cur_action->type != FT_XLATE_TYPE_SRC_AS) &&
990 (lp->cur_action->type != FT_XLATE_TYPE_DST_AS)) {
991 fterr_warnx("%s line %d: Illegal keyword.", lp->fname, lp->lineno);
992 return -1;
993 }
994
995 ftxasn = lp->cur_action->action;
996
997 NEXT_WORD(&lp->buf, lp->word);
998
999 if (!lp->word) {
1000 fterr_warnx("%s line %d: Expecting AS.", lp->fname, lp->lineno);
1001 return -1;
1002 }
1003
1004 ftxasn->as = atoi(lp->word);
1005
1006 return 0;
1007
1008 } /* parse_action_asn */
1009
1010 /*
1011 * function: parse_action_key
1012 *
1013 * process the 'key' line in an action.
1014 *
1015 * returns: 0 ok
1016 * <0 fail
1017 */
parse_action_key(struct line_parser * lp,struct ftxlate * ftxlate)1018 int parse_action_key(struct line_parser *lp, struct ftxlate *ftxlate)
1019 {
1020 struct ftxlate_act_ip_addr_anon *ftxiaa;
1021
1022 if (!lp->cur_action->type) {
1023 fterr_warnx("%s line %d: Must set type first.", lp->fname, lp->lineno);
1024 return -1;
1025 }
1026
1027 if ((lp->cur_action->type != FT_XLATE_TYPE_IP_ADDR_ANON) &&
1028 (lp->cur_action->type != FT_XLATE_TYPE_IP_SRC_ADDR_ANON) &&
1029 (lp->cur_action->type != FT_XLATE_TYPE_IP_DST_ADDR_ANON)) {
1030 fterr_warnx("%s line %d: Illegal keyword.", lp->fname, lp->lineno);
1031 return -1;
1032 }
1033
1034 ftxiaa = lp->cur_action->action;
1035
1036 NEXT_WORD(&lp->buf, lp->word);
1037
1038 if (!lp->word) {
1039 fterr_warnx("%s line %d: Expecting Key.", lp->fname, lp->lineno);
1040 return -1;
1041 }
1042
1043 if (decode_hex(lp->word, 64, ftxiaa->key, 32) < 0) {
1044 fterr_warnx("%s line %d: decode_hex() failed.", lp->fname, lp->lineno);
1045 return -1;
1046 }
1047
1048 return 0;
1049
1050 } /* parse_action_key */
1051
1052 /*
1053 * function: parse_action_key_file
1054 *
1055 * process the 'key-file' line in an action.
1056 *
1057 * returns: 0 ok
1058 * <0 fail
1059 */
parse_action_key_file(struct line_parser * lp,struct ftxlate * ftxlate)1060 int parse_action_key_file(struct line_parser *lp, struct ftxlate *ftxlate)
1061 {
1062 struct ftxlate_act_ip_addr_anon *ftxiaa;
1063
1064 if (!lp->cur_action->type) {
1065 fterr_warnx("%s line %d: Must set type first.", lp->fname, lp->lineno);
1066 return -1;
1067 }
1068
1069 ftxiaa = lp->cur_action->action;
1070
1071 NEXT_WORD(&lp->buf, lp->word);
1072
1073 if (!lp->word) {
1074 fterr_warnx("%s line %d: Expecting key-file.", lp->fname, lp->lineno);
1075 return -1;
1076 }
1077
1078 if (!(ftxiaa->key_fname = (char*)malloc(strlen(lp->word)+1))) {
1079 fterr_warn("malloc()");
1080 return -1;
1081 }
1082
1083 strcpy(ftxiaa->key_fname, lp->word);
1084
1085 if (load_key_file(ftxiaa->key_fname, ftxiaa->key) < 0) {
1086 fterr_warnx("Failed to load key from %s.", ftxiaa->key_fname);
1087 }
1088
1089 return 0;
1090
1091 } /* parse_action_key_file */
1092
1093 /*
1094 * function: parse_action_algorithm
1095 *
1096 * process the 'algorithm' line in an action.
1097 *
1098 * returns: 0 ok
1099 * <0 fail
1100 */
parse_action_algorithm(struct line_parser * lp,struct ftxlate * ftxlate)1101 int parse_action_algorithm(struct line_parser *lp, struct ftxlate *ftxlate)
1102 {
1103 struct ftxlate_act_ip_addr_anon *ftxiaa;
1104
1105 if (!lp->cur_action->type) {
1106 fterr_warnx("%s line %d: Must set type first.", lp->fname, lp->lineno);
1107 return -1;
1108 }
1109
1110 ftxiaa = lp->cur_action->action;
1111
1112 NEXT_WORD(&lp->buf, lp->word);
1113
1114 if (!lp->word) {
1115 fterr_warnx("%s line %d: Expecting algorithm.", lp->fname, lp->lineno);
1116 return -1;
1117 }
1118
1119 #ifdef HAVE_OPENSSL
1120 if (strcasecmp(lp->word, "cryptopan-aes128")) {
1121 fterr_warnx("%s line %d: Expecting CryptoPAn-aes128", lp->fname,
1122 lp->lineno);
1123 return -1;
1124 }
1125 #else
1126 fterr_warnx("%s line %d: OpenSSL not compiled in.", lp->fname, lp->lineno);
1127 return -1;
1128 #endif /* HAVE_OPENSSL */
1129
1130 ftxiaa->algorithm = FT_XLATE_ALG_CRYPTOPAN_AES128;
1131
1132 return 0;
1133
1134 } /* parse_action_algorithm */
1135
1136 /*
1137 * function: parse_action_key_refresh
1138 *
1139 * process the 'key-refresh' line in an action.
1140 *
1141 * returns: 0 ok
1142 * <0 fail
1143 */
parse_action_key_refresh(struct line_parser * lp,struct ftxlate * ftxlate)1144 int parse_action_key_refresh(struct line_parser *lp, struct ftxlate *ftxlate)
1145 {
1146 time_t now, t1;
1147 struct tm *tm;
1148 struct ftxlate_act_ip_addr_anon *ftxiaa;
1149 char *c;
1150 int hour, min, sec, interval;
1151
1152 if (!lp->cur_action->type) {
1153 fterr_warnx("%s line %d: Must set type first.", lp->fname, lp->lineno);
1154 return -1;
1155 }
1156
1157 ftxiaa = lp->cur_action->action;
1158
1159 /* key-refresh interval start-time */
1160
1161 NEXT_WORD(&lp->buf, lp->word);
1162
1163 if (!lp->word) {
1164 fterr_warnx("%s line %d: Expecting interval.", lp->fname, lp->lineno);
1165 return -1;
1166 }
1167
1168 interval = ftxiaa->key_refresh_interval = atoi(lp->word);
1169
1170 NEXT_WORD(&lp->buf, lp->word);
1171
1172 /* parse out time */
1173 hour = min = sec = 0;
1174
1175 if (!(c = strsep(&lp->word, ":")))
1176 goto done;
1177
1178 hour = atoi(c);
1179
1180 if (!(c = strsep(&lp->word, ":")))
1181 goto done;
1182
1183 min = atoi(c);
1184
1185 if (!(c = strsep(&lp->word, ":")))
1186 goto done;
1187
1188 sec = atoi(c);
1189
1190 if (lp->word) {
1191 fterr_warnx("%s line %d: Unexpected text: %s", lp->fname, lp->lineno,
1192 lp->word);
1193 return -1;
1194 }
1195
1196 done:
1197
1198 now = time(NULL);
1199 tm = localtime(&now);
1200
1201 /* calculate start time based on user input? */
1202 if (hour|min|sec) {
1203
1204 tm->tm_hour = hour;
1205 tm->tm_min = min;
1206 tm->tm_sec = sec;
1207
1208 t1 = mktime(tm);
1209
1210 /* start time is always in the future */
1211 if (t1 < now)
1212 t1 += 86400;
1213
1214 /* else it's on next interval minutes */
1215 } else {
1216
1217 tm->tm_min = (tm->tm_min / interval)*interval + interval;
1218 tm->tm_sec = 0;
1219
1220 if (tm->tm_min >= 60)
1221 tm->tm_min -= 60;
1222
1223 t1 = mktime(tm);
1224
1225 /* start time is always in the future */
1226 if (t1 < now)
1227 t1 += 3600; /* minute rollover */
1228
1229 }
1230
1231 ftxiaa->key_refresh_next = t1;
1232
1233 fterr_info("cryptopan key refresh at %lu.", ftxiaa->key_refresh_next);
1234
1235 return 0;
1236
1237 } /* parse_action_key_refresh */
1238
1239
1240 /*
1241 * function: parse_def
1242 *
1243 * process the 'definition' line. Each definition has a unique name which
1244 * is added to the ftxlate->defs linked list. The current definition is
1245 * updated in lp.
1246 *
1247 * returns: 0 ok
1248 * <0 fail
1249 */
parse_def(struct line_parser * lp,struct ftxlate * ftxlate)1250 int parse_def(struct line_parser *lp, struct ftxlate *ftxlate)
1251 {
1252 struct ftxlate_def *ftx;
1253
1254 NEXT_WORD(&lp->buf, lp->word);
1255
1256 if (!lp->word) {
1257 fterr_warnx("%s line %d: Expecting name.", lp->fname, lp->lineno);
1258 return -1;
1259 }
1260
1261 /* check if it exists */
1262 FT_SLIST_FOREACH(ftx, &ftxlate->defs, chain) {
1263
1264 if (!strcasecmp(lp->word, ftx->name)) {
1265 fterr_warnx("%s line %d: Name (%s) previously defined.", lp->fname,
1266 lp->lineno, lp->word);
1267 return -1;
1268 }
1269
1270 }
1271
1272 /* no, add a new entry to the list */
1273 if (!(ftx = (struct ftxlate_def*)malloc(sizeof
1274 (struct ftxlate_def)))) {
1275 fterr_warn("malloc()");
1276 return -1;
1277 }
1278
1279 bzero(ftx, sizeof *ftx);
1280
1281 FT_STAILQ_INIT(&ftx->terms);
1282
1283 if (!(ftx->name = (char*)malloc(strlen(lp->word)+1))) {
1284 fterr_warn("malloc()");
1285 free(ftx);
1286 return -1;
1287 }
1288
1289 strcpy(ftx->name, lp->word);
1290
1291 FT_SLIST_INSERT_HEAD(&ftxlate->defs, ftx, chain);
1292
1293 lp->state = PARSE_STATE_DEFINITION;
1294 lp->cur_def = ftx;
1295 lp->cur_def_term = ( struct ftxlate_def_term*)0L;
1296
1297 return 0;
1298
1299 } /* parse_def */
1300
1301 /*
1302 * function: parse_def_term
1303 *
1304 * process the term line. Each definition has a list of terms, the
1305 * terms have a common input, output, and exporter IP filter and
1306 * may have one or more actions. Without an action a term has
1307 * no purpose.
1308 *
1309 * returns: 0 ok
1310 * <0 fail
1311 */
parse_def_term(struct line_parser * lp,struct ftxlate * ftxlate)1312 int parse_def_term(struct line_parser *lp, struct ftxlate *ftxlate)
1313 {
1314 struct ftxlate_def_term *ftxt;
1315
1316 if (!lp->cur_def) {
1317 fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);
1318 return -1;
1319 }
1320
1321 /* no, add a new term entry to this definition */
1322 if (!(ftxt = (struct ftxlate_def_term*)malloc(sizeof *ftxt))) {
1323 fterr_warn("malloc()");
1324 return -1;
1325 }
1326
1327 bzero(ftxt, sizeof *ftxt);
1328
1329 FT_STAILQ_INIT(&ftxt->actions);
1330
1331 FT_STAILQ_INSERT_TAIL(&lp->cur_def->terms, ftxt, chain);
1332
1333 lp->cur_def_term = ftxt;
1334
1335 return 0;
1336
1337 } /* parse_def_term */
1338
1339 /*
1340 * function: parse_def_stop
1341 *
1342 * process the stop line. When the filter for this term matches
1343 * and a 'stop' is defined no further actions are performed.
1344 *
1345 * returns: 0 ok
1346 * <0 fail
1347 */
parse_def_stop(struct line_parser * lp,struct ftxlate * ftxlate)1348 int parse_def_stop(struct line_parser *lp, struct ftxlate *ftxlate)
1349 {
1350
1351 if (!lp->cur_def_term) {
1352 fterr_warnx("%s line %d: Must start term.", lp->fname, lp->lineno);
1353 return -1;
1354 }
1355
1356 lp->cur_def_term->flags |= FT_XLATE_FLAG_STOP;
1357
1358 return 0;
1359
1360 } /* parse_def_term */
1361
1362
1363 /*
1364 * function: parse_def_filter
1365 *
1366 * process the 'filter' line.
1367 *
1368 * returns: 0 ok
1369 * <0 fail
1370 */
parse_def_filter(struct line_parser * lp,struct ftxlate * ftxlate)1371 int parse_def_filter(struct line_parser *lp, struct ftxlate *ftxlate)
1372 {
1373
1374 if (!lp->cur_def_term) {
1375 fterr_warnx("%s line %d: Must start term.", lp->fname, lp->lineno);
1376 return -1;
1377 }
1378
1379 NEXT_WORD(&lp->buf, lp->word);
1380
1381 if (!lp->word) {
1382 fterr_warnx("%s line %d: Expecting filter name.", lp->fname, lp->lineno);
1383 return -1;
1384 }
1385
1386 if (lp->cur_def_term->ftfd) {
1387 fterr_warnx("%s line %d: Filter previously defined for term.",
1388 lp->fname, lp->lineno);
1389 return -1;
1390 }
1391
1392 /* delay loading the filters until one is requested */
1393 if (load_filters(ftxlate)) {
1394 fterr_warnx("%s line %d: Filters not loaded.", lp->fname, lp->lineno);
1395 return -1;
1396 }
1397
1398 if (!(lp->cur_def_term->ftfd = ftfil_def_find(&ftxlate->ftfil,
1399 lp->word))) {
1400 fterr_warnx("%s line %d: Filter definition not found.", lp->fname,
1401 lp->lineno);
1402 return -1;
1403 }
1404
1405 /* any fields referenced in the filter are now required for the xlate */
1406 lp->cur_def->xfields |= lp->cur_def_term->ftfd->xfields;
1407
1408 return 0;
1409
1410 } /* parse_def_filter */
1411
1412 /*
1413 * function: parse_def_action
1414 *
1415 * foreach action listed, add it to a linked list of actions for the
1416 * definition. Note resolve_actions() must be called before the actions
1417 * are valid.
1418 *
1419 * returns: 0 ok
1420 * <0 fail
1421 */
parse_def_action(struct line_parser * lp,struct ftxlate * ftxlate)1422 int parse_def_action(struct line_parser *lp, struct ftxlate *ftxlate)
1423 {
1424 struct ftxlate_def_term_actions *ftxta;
1425
1426 if (!lp->cur_def_term) {
1427 fterr_warnx("%s line %d: Must start term.", lp->fname, lp->lineno);
1428 return -1;
1429 }
1430
1431 NEXT_WORD(&lp->buf, lp->word);
1432
1433 if (!lp->word) {
1434 fterr_warnx("%s line %d: Expecting action.", lp->fname, lp->lineno);
1435 return -1;
1436 }
1437
1438 /* add a new entry to the list */
1439 if (!(ftxta = (struct ftxlate_def_term_actions*)malloc(sizeof *ftxta))) {
1440 fterr_warn("malloc()");
1441 return -1;
1442 }
1443
1444 bzero(ftxta, sizeof *ftxta);
1445
1446 if (!(ftxta->name = (char*)malloc(strlen(lp->word)+1))) {
1447 fterr_warn("malloc()");
1448 free(ftxta);
1449 return -1;
1450 }
1451 strcpy(ftxta->name, lp->word);
1452
1453 FT_STAILQ_INSERT_TAIL(&lp->cur_def_term->actions, ftxta, chain);
1454
1455 /* resolve the ftxta->action later in resolve_actions */
1456
1457 return 0;
1458
1459 } /* parse_def_action */
1460
1461 /*
1462 * function: parse_include_filter
1463 *
1464 * process the 'include-filter' line. Allow the default filter location
1465 * to be changed.
1466 *
1467 * returns: 0 ok
1468 * <0 fail
1469 */
parse_include_filter(struct line_parser * lp,struct ftxlate * ftxlate)1470 int parse_include_filter(struct line_parser *lp, struct ftxlate *ftxlate)
1471 {
1472
1473 NEXT_WORD(&lp->buf, lp->word);
1474
1475 if (!lp->word) {
1476 fterr_warnx("%s line %d: Expecting pathname.", lp->fname, lp->lineno);
1477 return -1;
1478 }
1479
1480 if (ftxlate->filter_fname) {
1481 fterr_warnx("%s line %d: Filter pathname previously specified.",
1482 lp->fname, lp->lineno);
1483 return -1;
1484 }
1485
1486 if (!(ftxlate->filter_fname = (char*)malloc(strlen(lp->word)+1))) {
1487 fterr_warn("malloc()");
1488 return -1;
1489 }
1490 strcpy(ftxlate->filter_fname, lp->word);
1491
1492 return 0;
1493
1494 } /* parse_include_filter */
1495
1496
1497 /*
1498 * function: resolve_actions
1499 *
1500 * The parser points to the name of the action in the definition to allow
1501 * for definitions to be defined before actions in the config file. This
1502 * fixes the pointers so the definitions point to the actions
1503 *
1504 * returns: 0 ok
1505 * <0 fail (an action could not be resolved)
1506 */
resolve_actions(struct ftxlate * ftxlate)1507 int resolve_actions(struct ftxlate *ftxlate)
1508 {
1509 struct ftxlate_def *ftx;
1510 struct ftxlate_def_term *ftxt;
1511 struct ftxlate_def_term_actions *ftxta;
1512 struct ftxlate_action *ftxa;
1513 struct ftxlate_act_ip_addr_anon *ftxiaa;
1514 int i, found;
1515
1516 /* foreach action do any additional initialization */
1517 FT_SLIST_FOREACH(ftxa, &ftxlate->actions, chain) {
1518
1519 /* *_ANON types need some extra work */
1520 if ((ftxa->type == FT_XLATE_TYPE_IP_ADDR_ANON) ||
1521 (ftxa->type == FT_XLATE_TYPE_IP_SRC_ADDR_ANON) ||
1522 (ftxa->type == FT_XLATE_TYPE_IP_DST_ADDR_ANON)) {
1523
1524 ftxiaa = ftxa->action;
1525
1526 /* only supported alg is cryptopan-eas128 */
1527 if (ftxiaa->algorithm != FT_XLATE_ALG_CRYPTOPAN_AES128) {
1528 fterr_warnx("Action %s: unknown anonymization algorithm", ftxa->name);
1529 return -1;
1530 }
1531
1532 /* check for key of all 0's */
1533 found = 0;
1534 for (i = 0; i < 32; ++i)
1535 if (ftxiaa->key[i] != 0)
1536 found = 1;
1537
1538 if (found == 0) {
1539 fterr_warnx("Action %s: uninitialized key.", ftxa->name);
1540 return -1;
1541 }
1542
1543 /* initialize cryptopan */
1544 if (cryptopan_init(&ftxiaa->cp, ftxiaa->key) < 0) {
1545 fterr_warnx("Action %s: cryptopan_init() failed.", ftxa->name);
1546 return -1;
1547 }
1548
1549 ftxiaa->init = 1;
1550
1551 } /* *_ANON work */
1552 }
1553
1554 /* foreach definition */
1555 FT_SLIST_FOREACH(ftx, &ftxlate->defs, chain) {
1556
1557 /* foreach term in the definition */
1558 FT_STAILQ_FOREACH(ftxt, &ftx->terms, chain) {
1559
1560 /* foreach action in the term */
1561 FT_STAILQ_FOREACH(ftxta, &ftxt->actions, chain) {
1562
1563 found = 0;
1564
1565 /* foreach action */
1566 FT_SLIST_FOREACH(ftxa, &ftxlate->actions, chain) {
1567
1568 if (!(strcasecmp(ftxa->name, ftxta->name))) {
1569
1570 ftxta->action = ftxa;
1571 ftx->xfields |= ftxa->xfields;
1572 found = 1;
1573 break;
1574
1575 }
1576
1577 }
1578
1579 }
1580
1581 if (!found) {
1582
1583 fterr_warnx("Unable to resolve action \"%s\" in xlate-definition \"%s\".", ftxta->name, ftx->name);
1584 return -1;
1585
1586 }
1587
1588 }
1589
1590 }
1591
1592 return 0;
1593
1594 } /* resolve actions */
1595
eval_ip_src_addr2net(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1596 static void eval_ip_src_addr2net(struct ftxlate_action *ftxa,
1597 char *rec, struct fts3rec_offsets *fo)
1598 {
1599 struct fts3rec_all2 cur;
1600
1601 FT_RECGET_SRC_MASK(cur,rec,*fo);
1602
1603 *((uint32_t*)(rec+(*fo).srcaddr)) &= ipv4_len2mask(cur.src_mask);
1604
1605 } /* eval_ip_src_addr2net */
1606
eval_ip_dst_addr2net(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1607 static void eval_ip_dst_addr2net(struct ftxlate_action *ftxa,
1608 char *rec, struct fts3rec_offsets *fo)
1609 {
1610 struct fts3rec_all2 cur;
1611
1612 FT_RECGET_DST_MASK(cur,rec,*fo);
1613
1614 *((uint32_t*)(rec+(*fo).dstaddr)) &= ipv4_len2mask(cur.dst_mask);
1615
1616 } /* eval_ip_dst_addr2net */
1617
eval_ip_src_addr2cnet(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1618 static void eval_ip_src_addr2cnet(struct ftxlate_action *ftxa,
1619 char *rec, struct fts3rec_offsets *fo)
1620 {
1621 struct fts3rec_all2 cur;
1622
1623 FT_RECGET_SRCADDR(cur,rec,*fo);
1624
1625 if ((cur.srcaddr & 0x80000000) == 0)
1626 *((uint32_t*)(rec+(*fo).srcaddr)) &= 0xFF000000;
1627 else if ((cur.srcaddr & 0xC0000000) == 0x80000000)
1628 *((uint32_t*)(rec+(*fo).srcaddr)) &= 0xFFFF0000;
1629 else if ((cur.srcaddr & 0xC0000000) == 0xC0000000)
1630 *((uint32_t*)(rec+(*fo).srcaddr)) &= 0xFFFFFF00;
1631
1632 } /* eval_ip_src_addr2cnet */
1633
eval_ip_dst_addr2cnet(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1634 static void eval_ip_dst_addr2cnet(struct ftxlate_action *ftxa,
1635 char *rec, struct fts3rec_offsets *fo)
1636 {
1637 struct fts3rec_all2 cur;
1638
1639 FT_RECGET_DSTADDR(cur,rec,*fo);
1640
1641 if ((cur.dstaddr & 0x80000000) == 0)
1642 *((uint32_t*)(rec+(*fo).dstaddr)) &= 0xFF000000;
1643 else if ((cur.dstaddr & 0xC0000000) == 0x80000000)
1644 *((uint32_t*)(rec+(*fo).dstaddr)) &= 0xFFFF0000;
1645 else if ((cur.dstaddr & 0xC0000000) == 0xC0000000)
1646 *((uint32_t*)(rec+(*fo).dstaddr)) &= 0xFFFFFF00;
1647
1648 } /* eval_ip_dst_addr2cnet */
1649
eval_ip_addr_privacy_mask(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1650 static void eval_ip_addr_privacy_mask(struct ftxlate_action *ftxa,
1651 char *rec, struct fts3rec_offsets *fo)
1652 {
1653 struct ftxlate_act_ip_addr_priv_mask *ftxiapm;
1654
1655 ftxiapm = ftxa->action;
1656
1657 *((uint32_t*)(rec+(*fo).srcaddr)) &= ftxiapm->src_mask;
1658 *((uint32_t*)(rec+(*fo).dstaddr)) &= ftxiapm->dst_mask;
1659
1660 } /* eval_ip_addr_privacy_mask */
1661
eval_ip_port_privacy_mask(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1662 static void eval_ip_port_privacy_mask(struct ftxlate_action *ftxa,
1663 char *rec, struct fts3rec_offsets *fo)
1664 {
1665 struct ftxlate_act_ip_port_priv_mask *ftxaipm;
1666
1667 ftxaipm = ftxa->action;
1668
1669 *((uint16_t*)(rec+(*fo).srcport)) &= ftxaipm->src_mask;
1670 *((uint16_t*)(rec+(*fo).dstport)) &= ftxaipm->dst_mask;
1671
1672 } /* eval_ip_port_privacy_mask */
1673
eval_tag_mask(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1674 static void eval_tag_mask(struct ftxlate_action *ftxa,
1675 char *rec, struct fts3rec_offsets *fo)
1676 {
1677 struct ftxlate_act_tag_mask *ftxatm;
1678
1679 ftxatm = ftxa->action;
1680
1681 *((uint32_t*)(rec+(*fo).src_tag)) &= ftxatm->src_mask;
1682 *((uint32_t*)(rec+(*fo).dst_tag)) &= ftxatm->dst_mask;
1683
1684 } /* eval_tag_mask */
1685
eval_scale(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1686 static void eval_scale(struct ftxlate_action *ftxa,
1687 char *rec, struct fts3rec_offsets *fo)
1688 {
1689 struct ftxlate_act_scale *ftxs;
1690
1691 ftxs = ftxa->action;
1692
1693 *((uint32_t*)(rec+(*fo).dOctets)) *= ftxs->scale;
1694 *((uint32_t*)(rec+(*fo).dPkts)) *= ftxs->scale;
1695
1696 } /* eval_scale */
1697
eval_src_asn(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1698 static void eval_src_asn(struct ftxlate_action *ftxa,
1699 char *rec, struct fts3rec_offsets *fo)
1700 {
1701 struct ftxlate_act_asn *ftxasn;
1702
1703 if (*((uint16_t*)(rec+(*fo).src_as)) == 0) {
1704 ftxasn = ftxa->action;
1705 *((uint16_t*)(rec+(*fo).src_as)) = ftxasn->as;
1706 }
1707
1708 } /* eval_src_asn */
1709
eval_dst_asn(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1710 static void eval_dst_asn(struct ftxlate_action *ftxa,
1711 char *rec, struct fts3rec_offsets *fo)
1712 {
1713 struct ftxlate_act_asn *ftxasn;
1714
1715 if (*((uint16_t*)(rec+(*fo).dst_as)) == 0) {
1716 ftxasn = ftxa->action;
1717 *((uint16_t*)(rec+(*fo).dst_as)) = ftxasn->as;
1718 }
1719
1720 } /* eval_dst_asn */
1721
eval_ip_src_addr_anon(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1722 static void eval_ip_src_addr_anon(struct ftxlate_action *ftxa,
1723 char *rec, struct fts3rec_offsets *fo)
1724 {
1725 struct ftxlate_act_ip_addr_anon *ftxiaa;
1726 uint32_t new;
1727 time_t now;
1728
1729 ftxiaa = ftxa->action;
1730
1731 /* if key_refresh_next is set check for key to be loaded */
1732 if (ftxiaa->key_refresh_next) {
1733
1734 now = time(NULL);
1735
1736 if (now > ftxiaa->key_refresh_next) {
1737
1738 /* get next interval, handle skipped intervals (no flows to trigger) */
1739 while (now > ftxiaa->key_refresh_next)
1740 ftxiaa->key_refresh_next += ftxiaa->key_refresh_interval*60;
1741
1742 /*
1743 * load new key and re-init cryptopan. If key load fails continue
1744 * using existing key
1745 */
1746 if (load_key_file(ftxiaa->key_fname, ftxiaa->key) < 0) {
1747
1748 fterr_warnx("Failed to load key from %s.", ftxiaa->key_fname);
1749
1750 } else {
1751
1752 fterr_info("cryptopan key reload from %s successful. Next refresh at %lu.", ftxiaa->key_fname, ftxiaa->key_refresh_next);
1753
1754 cryptopan_free(&ftxiaa->cp);
1755
1756 if (cryptopan_init(&ftxiaa->cp, ftxiaa->key) < 0)
1757 fterr_warnx("cryptopan_init(): failed.");
1758
1759 }
1760 }
1761 } /* refresh key? */
1762
1763 if (cryptopan_anon(&ftxiaa->cp, *((uint32_t*)(rec+(*fo).srcaddr)),
1764 &new) < 0) {
1765 fterr_errx(1, "cryptopan_anon(): failed");
1766 }
1767
1768 *((uint32_t*)(rec+(*fo).srcaddr)) = new;
1769
1770 } /* eval_ip_src_addr_anon */
1771
eval_ip_dst_addr_anon(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1772 static void eval_ip_dst_addr_anon(struct ftxlate_action *ftxa,
1773 char *rec, struct fts3rec_offsets *fo)
1774 {
1775 struct ftxlate_act_ip_addr_anon *ftxiaa;
1776 uint32_t new;
1777 time_t now;
1778
1779 ftxiaa = ftxa->action;
1780
1781 /* if key_refresh_next is set check for key to be loaded */
1782 if (ftxiaa->key_refresh_next) {
1783
1784 now = time(NULL);
1785
1786 if (now > ftxiaa->key_refresh_next) {
1787
1788 /* get next interval, handle skipped intervals (no flows to trigger) */
1789 while (now > ftxiaa->key_refresh_next)
1790 ftxiaa->key_refresh_next += ftxiaa->key_refresh_interval*60;
1791
1792 /*
1793 * load new key and re-init cryptopan. If key load fails continue
1794 * using existing key
1795 */
1796 if (load_key_file(ftxiaa->key_fname, ftxiaa->key) < 0) {
1797
1798 fterr_warnx("Failed to load key from %s.", ftxiaa->key_fname);
1799
1800 } else {
1801
1802 fterr_info("cryptopan key reload from %s successful. Next refresh at %lu.", ftxiaa->key_fname, ftxiaa->key_refresh_next);
1803
1804 cryptopan_free(&ftxiaa->cp);
1805
1806 if (cryptopan_init(&ftxiaa->cp, ftxiaa->key) < 0)
1807 fterr_warnx("cryptopan_init(): failed.");
1808
1809 }
1810 }
1811 } /* refresh key? */
1812
1813 if (cryptopan_anon(&ftxiaa->cp, *((uint32_t*)(rec+(*fo).dstaddr)),
1814 &new) < 0) {
1815 fterr_errx(1, "cryptopan_anon(): failed");
1816 }
1817
1818 *((uint32_t*)(rec+(*fo).dstaddr)) = new;
1819
1820 } /* eval_ip_dst_addr_anon */
1821
eval_ip_addr_anon(struct ftxlate_action * ftxa,char * rec,struct fts3rec_offsets * fo)1822 static void eval_ip_addr_anon(struct ftxlate_action *ftxa,
1823 char *rec, struct fts3rec_offsets *fo)
1824 {
1825
1826 eval_ip_src_addr_anon(ftxa, rec, fo);
1827 eval_ip_dst_addr_anon(ftxa, rec, fo);
1828
1829 } /* eval_ip_addr_anon */
1830
1831 /*
1832 * function: load_filters
1833 *
1834 * load the filter definitions if they have not been loaded
1835 *
1836 * return value of ftfil_load()
1837 *
1838 */
load_filters(struct ftxlate * ftxlate)1839 static int load_filters(struct ftxlate *ftxlate)
1840 {
1841
1842 /* work to do? */
1843 if (ftxlate->ftfil_init)
1844 return 0;
1845
1846 if (ftfil_load(&ftxlate->ftfil, ftxlate->ftvar, (ftxlate->filter_fname) ?
1847 ftxlate->filter_fname : FT_PATH_CFG_FILTER)) {
1848 return 1;
1849 }
1850
1851 ftxlate->ftfil_init = 1;
1852 return 0;
1853
1854 } /* load_filters */
1855
1856 /*
1857 * function: load_key_file
1858 *
1859 * load 32 byte hex key from fname
1860 *
1861 * returns: 0 okay
1862 * -1 fail
1863 */
load_key_file(char * fname,unsigned char * key)1864 static int load_key_file(char *fname, unsigned char *key)
1865 {
1866 struct stat sb;
1867 int fd, ret;
1868 char *buf;
1869
1870 buf = (char*)0L;
1871 ret = -1;
1872
1873 if ((fd = open(fname, O_RDONLY, 0)) < 0) {
1874 fterr_warn("open(%s)", fname);
1875 goto load_key_file_out;
1876 }
1877
1878 if (fstat(fd, &sb) < 0) {
1879 fterr_warn("stat(%s)", fname);
1880 goto load_key_file_out;
1881 }
1882
1883 /* allocate storage for file */
1884 if (!(buf = malloc(sb.st_size+1))) {
1885 fterr_warn("malloc()");
1886 goto load_key_file_out;
1887 }
1888
1889 /* read in file */
1890 if (read(fd, buf, sb.st_size) != sb.st_size) {
1891 fterr_warnx("read(%s): short", fname);
1892 goto load_key_file_out;
1893 }
1894
1895 /* null terminate file */
1896 buf[sb.st_size] = 0;
1897
1898 /* only using 64 hex digits */
1899 if (sb.st_size > 64)
1900 buf[64] = 0;
1901
1902 if (decode_hex(buf, 64, key, 32) < 0) {
1903 fterr_warnx("decode_hex(): failed for %s.", fname);
1904 goto load_key_file_out;
1905 }
1906
1907 ret = 0; /* good */
1908
1909 load_key_file_out:
1910
1911 if (fd != -1)
1912 close(fd);
1913
1914 if (buf)
1915 free(buf);
1916
1917 return ret;
1918
1919 } /* load_key_file */
1920
1921
1922 /*
1923 * function: decode_hex()
1924 *
1925 * decode max of in_len bytes from in as hex, store result in out.
1926 * out is out_len bytes
1927 *
1928 * in - null terminated character string to decode.
1929 * in_len - max hex digits to decode (may be > strlen(in)
1930 * out - decoded bits
1931 * out_len - length of out buffer
1932 *
1933 * return -1 - error (non hex digit encountered)
1934 * 0 - successful decode
1935 *
1936 */
decode_hex(char * in,int in_len,unsigned char * out,int out_len)1937 static int decode_hex(char *in, int in_len, unsigned char *out, int out_len)
1938 {
1939 int i, l;
1940 unsigned char v, odd;
1941
1942 bzero(out, out_len);
1943 l = strlen(in);
1944 odd = 0;
1945 out += out_len-1;
1946
1947 if (l > in_len)
1948 return -1;
1949
1950 in += l-1;
1951
1952 for (i = 0; i < l; ++i) {
1953
1954 if (*in >= '0' && *in <= '9')
1955 v = *in - '0';
1956 else if (*in >= 'a' && *in <= 'f')
1957 v = *in - 'a' + 10;
1958 else if (*in >= 'A' && *in <= 'F')
1959 v = *in - 'A' + 10;
1960 else return -1;
1961
1962 if (!odd) {
1963 *out |= v;
1964 } else {
1965 *out |= v<<4;
1966 --out;
1967 }
1968
1969 --in;
1970 odd = odd ? 0 : 1;
1971
1972 }
1973
1974 return 0;
1975
1976 } /* decode_hex */
1977
1978 /*
1979 * cryptopan_* code closely based on Crypto-PAn.1.0 by Jinliang Fan
1980 *
1981 * Crypto-PAn copyright:
1982 *
1983 * Name of Software: Crypto-PAn, hereafter (Software)
1984 *
1985 * Copyright 2002
1986 * Georgia Tech Research Corporation
1987 * Atlanta, Georgia 30332.
1988 * All Rights Reserved
1989 *
1990 * The following Software is posted on the Internet by the Georgia
1991 * Tech Research Corporation (GTRC). It was developed by employees
1992 * of the Georgia Institute of Technology in the College of Computing.
1993 * GTRC hereby grants to the user a non-exclusive, royalty-free
1994 * license to utilize such Software for the User's own purposes
1995 * pursuant to the following conditions.
1996 *
1997 *
1998 * THE SOFTWARE IS LICENSED ON AN "AS IS" BASIS. GTRC MAKES NO WARRANTY
1999 * THAT ALL ERRORS CAN BE OR HAVE BEEN ELIMINATED FROM THE SOFTWARE.
2000 * GTRC SHALL NOT BE RESPONSIBLE FOR LOSSES OF ANY KIND RESULTING FROM
2001 * THE USE OF THE SOFTWARE AND ITS ACCOMPANYING DOCUMENTATION, AND CAN
2002 * IN NO WAY PROVIDE COMPENSATION FOR ANY LOSSES SUSTAINED, INCLUDING
2003 * BUT NOT LIMITED TO ANY OBLIGATION, LIABILITY, RIGHT, CLAIM OR REMEDY
2004 * FOR TORT, OF FOR ANY ACTUAL OR ALLEGED INFRINGEMENT OF PATENTS, COPYRIGHTS,
2005 * TRADE SECRETS, OR SIMILAR RIGHTS OF THIRD PARTIES, NOR ANY BUSINESS
2006 * EXPENSE, MACHINE DOWNTIME, OR DAMAGES CAUSED LICENSEE BY ANY DEFICIENCY,
2007 * DEFECT OR ERROR IN THE SOFTWARE OR MALFUNCTION THEREOF, NOR ANY
2008 * INCIDENTAL OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED. GTRC DISCLAIMS
2009 * ALL WARRANTIES, BOTH EXPRESS AND IMPLIED RESPECTING THE USE AND
2010 * OPERATION OF THE SOFTWARE AND ANY ACCOMPANYING DOCUMENTATION,
2011 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2012 * PARTICULAR PURPOSE AND ANY IMPLIED WARRANTY ARISING FROM COURSE
2013 * OF PERFORMANCE, COURSE OF DEALING OR USAGE OF TRADE. GTRC MAKES NO
2014 * WARRANTY THAT THE SOFTWARE IS ADEQUATELY OR COMPLETELY DESCRIBED
2015 * IN, OR BEHAVES IN ACCORDANCE WITH ANY OF THE ACCOMPANYING
2016 * DOCUMENTATION. THE USER OF THE SOFTWARE IS EXPECTED TO MAKE THE FINAL
2017 * EVALUATION OF THE SOFTWARE'S USEFULNESS IN USER'S OWN ENVIRONMENT.
2018 *
2019 */
2020
2021 /*
2022 * function: cryptopan_init
2023 *
2024 * Initializes cryptopan structure. cryptopan_free() must be called
2025 * to deallocate resources
2026 *
2027 * returns: 0 okay
2028 * -1 fail
2029 */
cryptopan_init(struct cryptopan * cp,unsigned char * key)2030 static int cryptopan_init(struct cryptopan *cp, unsigned char *key)
2031 {
2032 #ifdef HAVE_OPENSSL
2033 int i;
2034
2035 /* clear */
2036 bzero(cp, sizeof *cp);
2037
2038 /* copy in key */
2039 bcopy(key, cp->m_key, 16);
2040
2041
2042 /* init crypto */
2043 cp->cipher_ctx = EVP_CIPHER_CTX_new();
2044 if (cp->cipher_ctx == NULL)
2045 return -1;
2046
2047 /* disable padding */
2048 if (!(EVP_CIPHER_CTX_set_padding(cp->cipher_ctx, 0))) {
2049 cryptopan_free(cp);
2050 EVP_CIPHER_CTX_free(cp->cipher_ctx);
2051 return -1;
2052 }
2053
2054 /* init encryption */
2055 if (!(EVP_EncryptInit(cp->cipher_ctx, EVP_aes_128_ecb(), key, NULL))) {
2056 cryptopan_free(cp);
2057 EVP_CIPHER_CTX_free(cp->cipher_ctx);
2058 return -1;
2059 }
2060
2061 /* set pad */
2062 i = 16;
2063 if (!(EVP_EncryptUpdate(cp->cipher_ctx, cp->m_pad, &i, key+16, i))) {
2064 cryptopan_free(cp);
2065 EVP_CIPHER_CTX_free(cp->cipher_ctx);
2066 return -1;
2067 }
2068 EVP_CIPHER_CTX_free(cp->cipher_ctx);
2069
2070 #endif /* HAVE_OPENSSL */
2071
2072 return 0;
2073
2074 } /* cryptopan_init */
2075
2076 /*
2077 * function: cryptopan_free
2078 *
2079 * Frees resources allocated by cryptopan_init()
2080 *
2081 * returns: 0 okay
2082 * -1 fail
2083 */
cryptopan_free(struct cryptopan * cp)2084 static int cryptopan_free(struct cryptopan *cp)
2085 {
2086
2087 #ifdef HAVE_OPENSSL
2088 EVP_CIPHER_CTX_cleanup(cp->cipher_ctx);
2089
2090 if (cp->cipher_ctx)
2091 free (cp->cipher_ctx);
2092 #endif /* HAVE_OPENSSL */
2093
2094 return 0;
2095
2096 } /* cryptopan_free */
2097
2098 /*
2099 * function: cryptopan_free
2100 *
2101 * Anonymize orig_addr, storing result in new_addr
2102 * see - http://www.cc.gatech.edu/computing/Telecomm/cryptopan/
2103 *
2104 * returns: 0 okay
2105 * -1 fail
2106 */
cryptopan_anon(struct cryptopan * cp,uint32_t orig_addr,uint32_t * new_addr)2107 static int cryptopan_anon(struct cryptopan *cp, uint32_t orig_addr, uint32_t *new_addr)
2108 {
2109 uint8_t rin_output[16];
2110 uint8_t rin_input[16];
2111 uint8_t *m_pad;
2112 uint32_t result, first4bytes_pad, first4bytes_input;
2113 int i, pos;
2114
2115 result = 0;
2116 m_pad = cp->m_pad;
2117
2118 bcopy(m_pad, rin_input, 16);
2119
2120 first4bytes_pad = (((uint32_t) m_pad[0]) << 24) +
2121 (((uint32_t) m_pad[1]) << 16) +
2122 (((uint32_t) m_pad[2]) << 8) +
2123 (uint32_t) m_pad[3];
2124
2125 /*
2126 * For each prefixes with length from 0 to 31, generate a bit using the
2127 * Rijndael cipher, which is used as a pseudorandom function here. The
2128 * bits generated in every rounds are combineed into a pseudorandom
2129 * one-time-pad.
2130 */
2131 for (pos = 0; pos <= 31 ; pos++) {
2132
2133 /*
2134 * Padding: The most significant pos bits are taken from orig_addr.
2135 * The other 128-pos bits are taken from m_pad. The variables
2136 * first4bytes_pad and first4bytes_input are used to handle the
2137 * annoying byte order problem.
2138 */
2139
2140 if (pos == 0)
2141 first4bytes_input = first4bytes_pad;
2142 else
2143 first4bytes_input = ((orig_addr >> (32-pos)) << (32-pos)) |
2144 ((first4bytes_pad<<pos) >> pos);
2145
2146 rin_input[0] = (uint8_t) (first4bytes_input >> 24);
2147 rin_input[1] = (uint8_t) ((first4bytes_input << 8) >> 24);
2148 rin_input[2] = (uint8_t) ((first4bytes_input << 16) >> 24);
2149 rin_input[3] = (uint8_t) ((first4bytes_input << 24) >> 24);
2150
2151 /*
2152 * Encryption: The Rijndael cipher is used as pseudorandom function.
2153 * During each round, only the first bit of rin_output is used.
2154 */
2155
2156 i = 16;
2157 #ifdef HAVE_OPENSSL
2158 if (!(EVP_EncryptUpdate(cp->cipher_ctx, rin_output, &i, rin_input, i))) {
2159 cryptopan_free(cp);
2160 return -1;
2161 }
2162 #endif /* HAVE_OPENSSL */
2163 /* Combination: the bits are combined into a pseudorandom one-time-pad */
2164 result |= (rin_output[0] >> 7) << (31-pos);
2165
2166 }
2167
2168 /* XOR the orginal address with the pseudorandom one-time-pad */
2169 *new_addr = result ^ orig_addr;
2170
2171 return 0;
2172
2173 } /* cryptopan_anon */
2174
2175