1 /* $NetBSD: dns_rr_filter.c,v 1.2 2017/02/14 01:16:44 christos Exp $ */
2
3 /*++
4 /* NAME
5 /* dns_rr_filter 3
6 /* SUMMARY
7 /* DNS resource record filter
8 /* SYNOPSIS
9 /* #include <dns.h>
10 /*
11 /* void dns_rr_filter_compile(title, map_names)
12 /* const char *title;
13 /* const char *map_names;
14 /* INTERNAL INTERFACES
15 /* int dns_rr_filter_execute(rrlist)
16 /* DNS_RR **rrlist;
17 /*
18 /* MAPS *dns_rr_filter_maps;
19 /* DESCRIPTION
20 /* This module implements a simple filter for dns_lookup*()
21 /* results.
22 /*
23 /* dns_rr_filter_compile() initializes a result filter. The
24 /* title and map_names arguments are as with maps_create().
25 /* This function may be invoked more than once; only the last
26 /* filter takes effect.
27 /*
28 /* dns_rr_filter_execute() converts each resource record in the
29 /* specified list with dns_strrecord to ASCII form and matches
30 /* that against the specified maps. If a match is found it
31 /* executes the corresponding action. Currently, only the
32 /* "ignore" action is implemented. This removes the matched
33 /* record from the list. The result is 0 in case of success,
34 /* -1 in case of error.
35 /*
36 /* dns_rr_filter_maps is updated by dns_rr_filter_compile().
37 /* LICENSE
38 /* .ad
39 /* .fi
40 /* The Secure Mailer license must be distributed with this software.
41 /* AUTHOR(S)
42 /* Wietse Venema
43 /* IBM T.J. Watson Research
44 /* P.O. Box 704
45 /* Yorktown Heights, NY 10598, USA
46 /*--*/
47
48 /*
49 * System library.
50 */
51 #include <sys_defs.h>
52 #include <ctype.h>
53
54 #ifdef STRCASECMP_IN_STRINGS_H
55 #include <strings.h>
56 #endif
57
58 /*
59 * Utility library.
60 */
61 #include <msg.h>
62 #include <vstring.h>
63 #include <myaddrinfo.h>
64
65 /*
66 * Global library.
67 */
68 #include <maps.h>
69
70 /*
71 * DNS library.
72 */
73 #define LIBDNS_INTERNAL
74 #include <dns.h>
75
76 /*
77 * Application-specific.
78 */
79 MAPS *dns_rr_filter_maps;
80
81 static DNS_RR dns_rr_filter_error[1];
82
83 #define STR vstring_str
84
85 /* dns_rr_filter_compile - compile dns result filter */
86
dns_rr_filter_compile(const char * title,const char * map_names)87 void dns_rr_filter_compile(const char *title, const char *map_names)
88 {
89 if (dns_rr_filter_maps != 0)
90 maps_free(dns_rr_filter_maps);
91 dns_rr_filter_maps = maps_create(title, map_names,
92 DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
93 }
94
95 /* dns_rr_action - execute action from filter map */
96
dns_rr_action(const char * cmd,DNS_RR * rr,const char * rr_text)97 static DNS_RR *dns_rr_action(const char *cmd, DNS_RR *rr, const char *rr_text)
98 {
99 const char *cmd_args = cmd + strcspn(cmd, " \t");
100 int cmd_len = cmd_args - cmd;
101
102 while (*cmd_args && ISSPACE(*cmd_args))
103 cmd_args++;
104
105 #define STREQUAL(x,y,l) (strncasecmp((x), (y), (l)) == 0 && (y)[l] == 0)
106
107 if (STREQUAL(cmd, "IGNORE", cmd_len)) {
108 msg_info("ignoring DNS RR: %s", rr_text);
109 return (0);
110 } else {
111 msg_warn("%s: unknown DNS filter action: \"%s\"",
112 dns_rr_filter_maps->title, cmd);
113 return (dns_rr_filter_error);
114 }
115 return (rr);
116 }
117
118 /* dns_rr_filter_execute - filter DNS lookup result */
119
dns_rr_filter_execute(DNS_RR ** rrlist)120 int dns_rr_filter_execute(DNS_RR **rrlist)
121 {
122 static VSTRING *buf = 0;
123 DNS_RR **rrp;
124 DNS_RR *rr;
125 const char *map_res;
126 DNS_RR *act_res;
127
128 /*
129 * Convert the resource record to string form, then search the maps for a
130 * matching action.
131 */
132 if (buf == 0)
133 buf = vstring_alloc(100);
134 for (rrp = rrlist; (rr = *rrp) != 0; /* see below */ ) {
135 map_res = maps_find(dns_rr_filter_maps, dns_strrecord(buf, rr),
136 DICT_FLAG_NONE);
137 if (map_res != 0) {
138 if ((act_res = dns_rr_action(map_res, rr, STR(buf))) == 0) {
139 *rrp = rr->next; /* do not advance in the list */
140 rr->next = 0;
141 dns_rr_free(rr);
142 continue;
143 } else if (act_res == dns_rr_filter_error) {
144 return (-1);
145 }
146 } else if (dns_rr_filter_maps->error) {
147 return (-1);
148 }
149 rrp = &(rr->next); /* do advance in the list */
150 }
151 return (0);
152 }
153