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