1#!/usr/bin/env perl
2#
3# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
4#
5# This Source Code Form is subject to the terms of the Mozilla Public
6# License, v. 2.0. If a copy of the MPL was not distributed with this
7# file, you can obtain one at https://mozilla.org/MPL/2.0/.
8#
9# See the COPYRIGHT file distributed with this work for additional
10# information regarding copyright ownership.
11
12use strict;
13use warnings;
14
15my $boilerplate_header = <<'EOB';
16# common configuration
17include "named.conf.header";
18
19view "recursive" {
20    zone "." {
21        type hint;
22        file "root.hint";
23    };
24
25    # policy configuration to be tested
26    response-policy {
27EOB
28
29my $no_option = <<'EOB';
30    };
31
32    # policy zones to be tested
33EOB
34
35my $qname_wait_recurse = <<'EOB';
36    } qname-wait-recurse no;
37
38    # policy zones to be tested
39EOB
40
41my $boilerplate_end = <<'EOB';
42};
43EOB
44
45my $policy_option = $qname_wait_recurse;
46
47my $serialnum = "1";
48my $policy_zone_header = <<'EOH';
49$TTL 60
50@ IN SOA root.ns ns SERIAL 3600 1800 86400 60
51     NS ns
52ns A 127.0.0.1
53EOH
54
55sub policy_client_ip {
56    return "32.1.0.0.127.rpz-client-ip CNAME .\n";
57}
58
59sub policy_qname {
60    my $query_nbr = shift;
61    return sprintf "q%02d.l2.l1.l0 CNAME .\n", $query_nbr;
62}
63
64sub policy_ip {
65    return "32.255.255.255.255.rpz-ip CNAME .\n";
66}
67
68sub policy_nsdname {
69    return "ns.example.org.rpz-nsdname CNAME .\n";
70}
71
72sub policy_nsip {
73    return "32.255.255.255.255.rpz-ip CNAME .\n";
74}
75
76my %static_triggers = (
77    'client-ip' => \&policy_client_ip,
78    'ip'        => \&policy_ip,
79    'nsdname'   => \&policy_nsdname,
80    'nsip'      => \&policy_nsip,
81);
82
83sub mkconf {
84    my $case_id = shift;
85    my $n_queries = shift;
86
87    { # generate the query list
88        my $query_list_filename = "ns2/$case_id.queries";
89        my $query_list_fh;
90
91        open $query_list_fh, ">$query_list_filename" or die;
92
93        for( my $i = 1; $i <= $n_queries; $i++ ) {
94            print $query_list_fh sprintf "q%02d.l2.l1.l0\n", $i;
95        }
96    }
97
98    my @zones;
99
100    { # generate the conf file
101        my $conf_filename = "ns2/named.$case_id.conf";
102
103        my $conf_fh;
104
105        open $conf_fh, ">$conf_filename" or die;
106
107        print $conf_fh $boilerplate_header;
108
109        my $zone_seq = 0;
110
111        @zones = map {
112            [
113                sprintf( "$case_id.%02d.policy.local", $zone_seq++ ),
114                $_,
115            ];
116        } @_;
117
118        print $conf_fh map { qq{        zone "$_->[0]";\n} } @zones;
119
120        print $conf_fh $policy_option;
121
122        print $conf_fh map { qq{    zone "$_->[0]" { type master; file "db.$_->[0]"; };\n} } @zones;
123
124        print $conf_fh $boilerplate_end;
125    }
126
127    # generate the policy zone contents
128    foreach my $policy_zone_info( @zones ) {
129        my $policy_zone_name = $policy_zone_info->[0];
130        my $policy_zone_contents = $policy_zone_info->[1];
131
132        my $policy_zone_filename = "ns2/db.$policy_zone_name";
133        my $policy_zone_fh;
134
135        open $policy_zone_fh, ">$policy_zone_filename" or die;
136
137        my $header = $policy_zone_header;
138        $header =~ s/SERIAL/$serialnum/;
139        print $policy_zone_fh $header;
140
141        foreach my $trigger( @$policy_zone_contents ) {
142            if( exists $static_triggers{$trigger} ) {
143                # matches a trigger type with a static value
144                print $policy_zone_fh $static_triggers{$trigger}->();
145            }
146            else {
147                # a qname trigger, where what was specified is the query number it should match
148                print $policy_zone_fh policy_qname( $trigger );
149            }
150        }
151    }
152}
153
154mkconf(
155    '1a',
156    1,
157    [ 'client-ip' ],
158);
159
160mkconf(
161    '1b',
162    2,
163    [ 1 ],
164);
165
166mkconf(
167    '1c',
168    1,
169    [ 'client-ip', 2 ],
170);
171
172mkconf(
173    '2a',
174    33,
175    map { [ $_ ]; }  1 .. 32
176);
177
178mkconf(
179    '3a',
180    1,
181    [ 'ip' ],
182);
183
184mkconf(
185    '3b',
186    1,
187    [ 'nsdname' ],
188);
189
190mkconf(
191    '3c',
192    1,
193    [ 'nsip' ],
194);
195
196mkconf(
197    '3d',
198    2,
199    [ 'ip', 1 ]
200);
201
202mkconf(
203    '3e',
204    2,
205    [ 'nsdname', 1 ]
206);
207
208mkconf(
209    '3f',
210    2,
211    [ 'nsip', 1 ]
212);
213
214{
215    my $seq_code = 'aa';
216    my $seq_nbr = 0;
217
218    while( $seq_nbr < 32 ) {
219
220        mkconf(
221            "4$seq_code",
222            33,
223            ( map { [ $_ ]; } 1 .. $seq_nbr ),
224            [ 'ip', $seq_nbr + 2 ],
225            ( map { [ $_ + 2 ]; } ($seq_nbr + 1) .. 31 ),
226        );
227
228        $seq_code++;
229        $seq_nbr++;
230    }
231}
232
233mkconf(
234    '5a',
235    6,
236    [ 1 ],
237    [ 2, 'ip' ],
238    [ 4 ],
239    [ 5, 'ip' ],
240    [ 6 ],
241);
242
243$policy_option = $no_option;
244
245mkconf(
246    '6a',
247    0,
248    [ ],
249);
250
251$serialnum = "2";
252mkconf(
253    '6b',
254    0,
255    [ 'nsdname' ],
256);
257
258$serialnum = "3";
259mkconf(
260    '6c',
261    0,
262    [ ],
263);
264
265__END__
266
2670x01 - has client-ip
268    32.1.0.0.127.rpz-client-ip CNAME .
2690x02 - has qname
270    qX.l2.l1.l0 CNAME .
2710x10 - has ip
272    32.255.255.255.255.rpz-ip CNAME .
2730x20 - has nsdname
274    ns.example.org.rpz-nsdname CNAME .
2750x40 - has nsip
276    32.255.255.255.255.rpz-nsip CNAME .
277
278$case.$seq.policy.local
279
280case 1a = 0x01
281    .q01 = (00,0x01)=-r
282case 1b = 0x02
283    .q01 = (00,0x02)=-r
284    .q02 = (--,----)=+r
285case 1c = 0x03
286    .q01 = (00,0x01)=-r
287
288case 2a = 0x03{32}
289    .q01 = (00,0x02)=-r
290    .q02 = (01,0x02)=-r
291     ...
292    .q31 = (30,0x02)=-r
293    .q32 = (31,0x02)=-r
294    .q33 = (--,----)=+r
295
296case 3a = 0x10
297    .q01 = (00,0x10)=+r
298case 3b = 0x20
299    .q01 = (00,0x20)=+r
300case 3c = 0x40
301    .q01 = (00,0x40)=+r
302case 3d = 0x12
303    .q01 = (00,0x10)=+r
304    .q02 = (00,0x02)=-r
305case 3e = 0x22
306    .q01 = (00,0x20)=+r
307    .q02 = (00,0x02)=-r
308case 3f = 0x42
309    .q01 = (00,0x40)=+r
310    .q02 = (00,0x02)=-r
311
312case 4aa = 0x12,0x02{31}
313    .q01 = (00,0x10)=+r
314    .q02 = (00,0x02)=-r
315    .q03 = (01,0x02)=+r
316     ...
317    .q32 = (30,0x02)=+r
318    .q33 = (31,0x02)=+r
319case 4__ = 0x02{n(1->30)},0x12,0x02{31-n}
320    .q01 = (00,0x02)=-r
321     ...
322    .q(n+1) = (n,0x10)=+r
323    .q(n+2) = (n,0x02)=-r
324     ...
325    .q33 = (31,0x02)=+r
326case 4bf = 0x02{31},0x12
327    .q01 = (00,0x02)=-r
328    .q02 = (01,0x02)=-r
329     ...
330    .q31 = (30,0x02)=-r
331    .q32 = (31,0x10)=+r
332    .q33 = (31,0x02)=-r
333
334case 5a = 0x02,0x12,0x02,0x12,0x02
335    .q01 = (00,0x02)=-r
336    .q02 = (01,0x02)=-r
337    .q03 = (01,0x10)=+r
338    .q04 = (02,0x02)=+r
339    .q05 = (03,0x02)=+r
340    .q06 = (04,0x02)=+r
341
342