]>
Commit | Line | Data |
---|---|---|
64524026 GS |
1 | diff -urN dkfilter-0.11.orig/scripts/dkfilter.out dkfilter-0.11/scripts/dkfilter.out |
2 | --- dkfilter-0.11.orig/scripts/dkfilter.out 2006-09-21 16:21:36.000000000 +0200 | |
3 | +++ dkfilter-0.11/scripts/dkfilter.out 2006-12-05 20:43:15.000000000 +0100 | |
4 | @@ -18,6 +18,8 @@ | |
5 | # GNU General Public License for more details. | |
6 | # | |
7 | # Written by Bennett Todd <bet@rahul.net> | |
8 | +# Support for multiple keys and configuration file added by | |
9 | +# Xavier Perseguers <xavier.perseguers@a3.epfl.ch> | |
10 | ||
11 | use strict; | |
12 | use warnings; | |
13 | @@ -26,6 +28,7 @@ | |
14 | use Pod::Usage; | |
15 | use IO::File; | |
16 | use Sys::Syslog; | |
17 | +use AppConfig::File; | |
18 | ||
19 | use DKMessage; | |
20 | use MySmtpServer; | |
21 | @@ -35,11 +38,8 @@ | |
22 | ||
23 | my $reject_fail = 0; # not actually used in this filter | |
24 | my $reject_error = 0; | |
25 | -my $keyfile; | |
26 | -my $selector; | |
27 | -my $domain_arg; | |
28 | -my $method = "simple"; | |
29 | my $headers = 0; | |
30 | +my $configfile; | |
31 | my $setuser; | |
32 | my $setgroup; | |
33 | my $daemonize; | |
34 | @@ -50,10 +50,7 @@ | |
35 | "reject-fail" => \$reject_fail, | |
36 | "reject-error" => \$reject_error, | |
37 | "hostname=s" => \$hostname, | |
38 | - "keyfile=s" => \$keyfile, | |
39 | - "selector=s" => \$selector, | |
40 | - "domain=s" => \$domain_arg, | |
41 | - "method=s" => \$method, | |
42 | + "configfile=s" => \$configfile, | |
43 | "headers" => \$headers, | |
44 | "user=s" => \$setuser, | |
45 | "group=s" => \$setgroup, | |
46 | @@ -73,32 +70,88 @@ | |
47 | pod2usage("Error: source or destination port is missing"); | |
48 | } | |
49 | ||
50 | -unless (defined $keyfile) | |
51 | +unless (defined $configfile) | |
52 | { | |
53 | - pod2usage("Error: no keyfile specified"); | |
54 | + pod2usage("Error: no configfile specified"); | |
55 | } | |
56 | -unless (-r $keyfile) | |
57 | +unless (-r $configfile) | |
58 | { | |
59 | - pod2usage("Error: cannot read keyfile $keyfile"); | |
60 | + pod2usage("Error: cannot read configfile $configfile"); | |
61 | } | |
62 | -unless (defined $selector) | |
63 | + | |
64 | +# Parse the configuration file | |
65 | + | |
66 | +my $state = AppConfig::State->new(); | |
67 | + | |
68 | +$state->define( | |
69 | + 'domain_name', { | |
70 | + ARGCOUNT => AppConfig::ARGCOUNT_LIST | |
71 | + }, | |
72 | + 'domain_selector', { | |
73 | + ARGCOUNT => AppConfig::ARGCOUNT_LIST | |
74 | + }, | |
75 | + 'domain_method', { | |
76 | + ARGCOUNT => AppConfig::ARGCOUNT_LIST, | |
77 | + VALIDATE => \&check_method | |
78 | + }, | |
79 | + 'domain_private_key', { | |
80 | + ARGCOUNT => AppConfig::ARGCOUNT_LIST, | |
81 | + VALIDATE => \&check_private_key | |
82 | + } | |
83 | +); | |
84 | + | |
85 | +sub check_method { | |
86 | + my $var = shift; | |
87 | + my $val = shift; | |
88 | + | |
89 | + return ($val eq "simple" || $val eq "nofws") ? 1 : 0; | |
90 | +} | |
91 | + | |
92 | +sub check_private_key { | |
93 | + my $var = shift; | |
94 | + my $val = shift; | |
95 | + | |
96 | + return (-r $val) ? 1 : 0; | |
97 | +} | |
98 | + | |
99 | +my $config = AppConfig::File->new($state); | |
100 | +$config->parse($configfile); | |
101 | + | |
102 | +my $domains = $state->get('domain_name'); | |
103 | +my $_methods = $state->get('domain_method'); | |
104 | +my $_selectors = $state->get('domain_selector'); | |
105 | +my $_keys = $state->get('domain_private_key'); | |
106 | + | |
107 | +unless ( scalar @$domains == scalar @$_methods ) | |
108 | { | |
109 | - pod2usage("Error: selector not specified"); | |
110 | + pod2usage("Error: number of methods is different than number of domains"); | |
111 | } | |
112 | -unless (defined $domain_arg) | |
113 | +unless ( scalar @$domains == scalar @$_selectors ) | |
114 | { | |
115 | - pod2usage("Error: domain not specified"); | |
116 | + pod2usage("Error: number of selectors is different than number of domains"); | |
117 | } | |
118 | -my @domains = split(/,\s*/, $domain_arg); | |
119 | -unless (@domains) | |
120 | +unless ( scalar @$domains == scalar @$_keys ) | |
121 | { | |
122 | - pod2usage("Error: domain not specified"); | |
123 | + pod2usage("Error: number of private keys is different than number of domains"); | |
124 | } | |
125 | -unless ($method eq "simple" || $method eq "nofws") | |
126 | + | |
127 | +my %methods; | |
128 | +my %selectors; | |
129 | +my %keys; | |
130 | + | |
131 | +for ( my $i = 0; $i < scalar @$domains; $i++ ) | |
132 | { | |
133 | - die "Error: invalid method; must be simple or nofws\n"; | |
134 | + $methods{ @$domains[$i] } = @$_methods[$i]; | |
135 | + $selectors{ @$domains[$i] } = @$_selectors[$i]; | |
136 | + $keys{ @$domains[$i] } = @$_keys[$i]; | |
137 | } | |
138 | ||
139 | +# Compare number of key files and number of domains | |
140 | +# If there is only one key file, each domain will use | |
141 | +# the same key (dkfilter original version). Otherwise | |
142 | +# there should be as many key file as domain definitions. | |
143 | +# If all goes well, create a hash with a key for each domain. | |
144 | + | |
145 | use base "MySmtpProxyServer"; | |
146 | main->run( | |
147 | host => $srcaddr, | |
148 | @@ -166,7 +219,7 @@ | |
149 | { | |
150 | while ($domain) | |
151 | { | |
152 | - if (grep { lc($_) eq $domain } @domains) | |
153 | + if (grep { lc($_) eq $domain } @$domains) | |
154 | { | |
155 | last; | |
156 | } | |
157 | @@ -177,14 +230,14 @@ | |
158 | unless ($domain) | |
159 | { | |
160 | # message has no senderdomain | |
161 | - $domain = $domains[0]; | |
162 | + $domain = @$domains[0]; | |
163 | } | |
164 | ||
165 | $result = $mess->sign( | |
166 | - Method => $method, | |
167 | - Selector => $selector, | |
168 | + Method => $methods{ $domain }, | |
169 | + Selector => $selectors{ $domain }, | |
170 | Domain => $domain, | |
171 | - KeyFile => $keyfile, | |
172 | + KeyFile => $keys{ $domain }, | |
173 | Headers => $headers | |
174 | ); | |
175 | $result_detail = $mess->result_detail; | |
176 | @@ -246,10 +299,7 @@ | |
177 | dkfilter.out [options] listen.addr:port talk.addr:port | |
178 | options: | |
179 | --reject-error | |
180 | - --keyfile=filename | |
181 | - --selector=SELECTOR | |
182 | - --domain=DOMAIN | |
183 | - --method=simple|nofws | |
184 | + --configfile=filename | |
185 | --headers | |
186 | --user=USER | |
187 | --group=GROUP | |
188 | @@ -259,6 +309,24 @@ | |
189 | dkfilter.out --help | |
190 | to see a full description of the various options | |
191 | ||
192 | + Format of the configuration file: | |
193 | + | |
194 | + # ------------------------------------------ | |
195 | + # domain 1 | |
196 | + [domain] | |
197 | + name = domain.tld | |
198 | + method = METHOD | |
199 | + selector = SELECTOR | |
200 | + private_key = FILENAME | |
201 | + | |
202 | + # domain 2 | |
203 | + [domain] | |
204 | + name = otherdomain.tld | |
205 | + method = METHOD | |
206 | + selector = SELECTOR | |
207 | + private_key = FILENAME | |
208 | + # ------------------------------------------ | |
209 | + | |
210 | =head1 OPTIONS | |
211 | ||
212 | =over | |
213 | @@ -274,17 +342,18 @@ | |
214 | ||
215 | The most common error is a message parse error. | |
216 | ||
217 | -=item B<--keyfile=FILENAME> | |
218 | +=item B<--configfile=FILENAME> | |
219 | ||
220 | This is a required argument. Use it to specify the filename containing | |
221 | -the private key used in signing outgoing messages. | |
222 | +the configuration of domains and private keys used in signing outgoing | |
223 | +messages. | |
224 | ||
225 | -=item B<--selector=SELECTOR> | |
226 | +=item B<SELECTOR> | |
227 | ||
228 | This is a required argument. Use it to specify the name of the key | |
229 | selector. | |
230 | ||
231 | -=item B<--domain=DOMAIN> | |
232 | +=item B<DOMAIN> | |
233 | ||
234 | This is a required argument. Use it to specify what domain(s) emails | |
235 | are signed for. If you want to sign for multiple domains, specify the | |
236 | @@ -293,11 +362,10 @@ | |
237 | specified in this argument. If it sees a match, it will sign the message | |
238 | using the matching domain. | |
239 | ||
240 | -=item B<--method=simple|nofws> | |
241 | +=item B<METHOD> | |
242 | ||
243 | This option specifies the canonicalization algorithm to use for signing | |
244 | -messages. Specify either C<simple> or C<nofws>. If not specified, | |
245 | -the default is C<simple>. | |
246 | +messages. Specify either C<simple> or C<nofws>. | |
247 | ||
248 | =item B<--headers> | |
249 | ||
250 | @@ -335,7 +403,7 @@ | |
251 | ||
252 | =head1 EXAMPLE | |
253 | ||
254 | - dkfilter.out --keyfile=private.key --selector=sydney \ | |
255 | - --domain=example.org 127.0.0.1:10027 127.0.0.1:10028 | |
256 | + dkfilter.out --configfile=/etc/dkfilter.conf \ | |
257 | + 127.0.0.1:10027 127.0.0.1:10028 | |
258 | ||
259 | =cut |