1 |
unnilennium |
1.1 |
diff -Nur qpsmtpd-plugins-openfusion-20050429.old/plugins/whitelist_soft qpsmtpd-plugins-openfusion-20050429/plugins/whitelist_soft |
2 |
|
|
--- qpsmtpd-plugins-openfusion-20050429.old/plugins/whitelist_soft 2005-03-29 00:02:37.000000000 -0500 |
3 |
|
|
+++ qpsmtpd-plugins-openfusion-20050429/plugins/whitelist_soft 1969-12-31 19:00:00.000000000 -0500 |
4 |
|
|
@@ -1,223 +0,0 @@ |
5 |
|
|
-=head1 NAME |
6 |
|
|
- |
7 |
|
|
-whitelist_soft - whitelist override for other qpsmtpd plugins |
8 |
|
|
- |
9 |
|
|
- |
10 |
|
|
-=head1 DESCRIPTION |
11 |
|
|
- |
12 |
|
|
-The whitelist_soft plugin allows selected hosts or senders or recipients |
13 |
|
|
-to be whitelisted as exceptions to later plugin processing. It is a more |
14 |
|
|
-conservative variant of Devin Carraway's 'whitelist' plugin. |
15 |
|
|
- |
16 |
|
|
- |
17 |
|
|
-=head1 CONFIGURATION |
18 |
|
|
- |
19 |
|
|
-To enable the plugin, add it to the qpsmtpd/config/plugins file as usual. |
20 |
|
|
-It should precede any plugins you might wish to whitelist for. |
21 |
|
|
- |
22 |
|
|
-Several configuration files are supported, corresponding to different |
23 |
|
|
-parts of the SMTP conversation: |
24 |
|
|
- |
25 |
|
|
-=over 4 |
26 |
|
|
- |
27 |
|
|
-=item whitelisthosts |
28 |
|
|
- |
29 |
|
|
-Any IP address (or start-anchored fragment thereof) listed in the |
30 |
|
|
-whitelisthosts file is exempted from any further validation during |
31 |
|
|
-'connect', and can be selectively exempted at other stages by |
32 |
|
|
-plugins testing for a 'whitelisthost' connection note. |
33 |
|
|
- |
34 |
|
|
-Similarly, if the environment variable $WHITELISTCLIENT is set |
35 |
|
|
-(which can be done by tcpserver), the connection will be exempt from |
36 |
|
|
-further 'connect' validation, and the host can be selectively |
37 |
|
|
-exempted by other plugins testing for a 'whitelistclient' connection |
38 |
|
|
-note. |
39 |
|
|
- |
40 |
|
|
-=item whitelisthelo |
41 |
|
|
- |
42 |
|
|
-Any host that issues a HELO matching an entry in whitelisthelo will |
43 |
|
|
-be exempted from further validation at the 'helo' stage. Subsequent |
44 |
|
|
-plugins can test for a 'whitelisthelo' connection note. Note that |
45 |
|
|
-this does not actually amount to an authentication in any meaningful |
46 |
|
|
-sense. |
47 |
|
|
- |
48 |
|
|
-=item whitelistsenders |
49 |
|
|
- |
50 |
|
|
-If the envelope sender of a mail (that which is sent as the MAIL FROM) |
51 |
|
|
-matches an entry in whitelistsenders, or if the hostname component |
52 |
|
|
-matches, the mail will be exempted from any further validation within |
53 |
|
|
-the 'mail' stage. Subsequent plugins can test for this exemption as a |
54 |
|
|
-'whitelistsender' transaction note. |
55 |
|
|
- |
56 |
|
|
-=item whitelistrcpt |
57 |
|
|
- |
58 |
|
|
-If any recipient of a mail (that sent as the RCPT TO) matches an |
59 |
|
|
-entry from whitelistrcpt, or if the hostname component matches, no |
60 |
|
|
-further validation will be required for this recipient. Subsequent |
61 |
|
|
-plugins can test for this exemption using a 'whitelistrcpt' |
62 |
|
|
-transaction note, which holds the count of whitelisted recipients. |
63 |
|
|
- |
64 |
|
|
-=back |
65 |
|
|
- |
66 |
|
|
-whitelist_soft also supports per-recipient whitelisting when using |
67 |
|
|
-the per_user_config plugin. To enable the per-recipient behaviour |
68 |
|
|
-(delaying all whitelisting until the rcpt part of the smtp |
69 |
|
|
-conversation, and using per-recipient whitelist configs, if |
70 |
|
|
-available), pass a true 'per_recipient' argument in the |
71 |
|
|
-config/plugins invocation i.e. |
72 |
|
|
- |
73 |
|
|
- whitelist_soft per_recipient 1 |
74 |
|
|
- |
75 |
|
|
-By default global and per-recipient whitelists are merged; to turn off |
76 |
|
|
-the merge behaviour pass a false 'merge' argument in the config/plugins |
77 |
|
|
-invocation i.e. |
78 |
|
|
- |
79 |
|
|
- whitelist_soft per_recipient 1 merge 0 |
80 |
|
|
- |
81 |
|
|
- |
82 |
|
|
-=head1 BUGS |
83 |
|
|
- |
84 |
|
|
-Whitelist lookups are all O(n) linear scans of configuration files, even |
85 |
|
|
-though they're all associative lookups. Something should be done about |
86 |
|
|
-this when CDB/DB/GDBM configs are supported. |
87 |
|
|
- |
88 |
|
|
- |
89 |
|
|
-=head1 AUTHOR |
90 |
|
|
- |
91 |
|
|
-Based on the 'whitelist' plugin by Devin Carraway <qpsmtpd@devin.com>. |
92 |
|
|
- |
93 |
|
|
-Modified by Gavin Carr <gavin@openfusion.com.au> to not inherit |
94 |
|
|
-whitelisting across hooks, but use per-hook whitelist notes instead. |
95 |
|
|
-This is a more conservative approach e.g. whitelisting an IP will not |
96 |
|
|
-automatically allow relaying from that IP. |
97 |
|
|
- |
98 |
|
|
-=cut |
99 |
|
|
- |
100 |
|
|
-my $VERSION = 0.02; |
101 |
|
|
- |
102 |
|
|
-# Default is to merge whitelists in per_recipient mode |
103 |
|
|
-my %MERGE = ( merge => 1 ); |
104 |
|
|
- |
105 |
|
|
-sub register { |
106 |
|
|
- my ($self, $qp, %arg) = @_; |
107 |
|
|
- |
108 |
|
|
- $self->{_per_recipient} = 1 if $arg{per_recipient}; |
109 |
|
|
- $MERGE{merge} = $arg{merge} if defined $arg{merge}; |
110 |
|
|
- |
111 |
|
|
- # Normal mode - whitelist per hook |
112 |
|
|
- unless ($arg{per_recipient}) { |
113 |
|
|
- $self->register_hook("connect", "check_host"); |
114 |
|
|
- $self->register_hook("helo", "check_helo"); |
115 |
|
|
- $self->register_hook("ehlo", "check_helo"); |
116 |
|
|
- $self->register_hook("mail", "check_sender"); |
117 |
|
|
- $self->register_hook("rcpt", "check_rcpt"); |
118 |
|
|
- } |
119 |
|
|
- # Per recipient mode - defer all whitelisting to rcpt hook |
120 |
|
|
- else { |
121 |
|
|
- $self->register_hook("rcpt", "check_host"); |
122 |
|
|
- $self->register_hook("helo", "helo_helper"); |
123 |
|
|
- $self->register_hook("ehlo", "helo_helper"); |
124 |
|
|
- $self->register_hook("rcpt", "check_helo"); |
125 |
|
|
- $self->register_hook("rcpt", "check_sender"); |
126 |
|
|
- $self->register_hook("rcpt", "check_rcpt"); |
127 |
|
|
- } |
128 |
|
|
-} |
129 |
|
|
- |
130 |
|
|
-sub check_host { |
131 |
|
|
- my ($self, $transaction, $rcpt) = @_; |
132 |
|
|
- my $ip = $self->qp->connection->remote_ip || return (DECLINED); |
133 |
|
|
- |
134 |
|
|
- # From tcpserver |
135 |
|
|
- if (exists $ENV{WHITELISTCLIENT}) { |
136 |
|
|
- $self->qp->connection->notes('whitelistclient', 1); |
137 |
|
|
- $self->log(2,"host $ip is a whitelisted client"); |
138 |
|
|
- return OK; |
139 |
|
|
- } |
140 |
|
|
- |
141 |
|
|
- my $config_arg = $self->{_per_recipient} ? { rcpt => $rcpt, %MERGE } : {}; |
142 |
|
|
- for my $h ($self->qp->config('whitelisthosts', $config_arg)) { |
143 |
|
|
- if ($h eq $ip or $ip =~ /^\Q$h\E/) { |
144 |
|
|
- $self->qp->connection->notes('whitelisthost', 1); |
145 |
|
|
- $self->log(2,"host $ip is a whitelisted host"); |
146 |
|
|
- return OK; |
147 |
|
|
- } |
148 |
|
|
- } |
149 |
|
|
- return DECLINED; |
150 |
|
|
-} |
151 |
|
|
- |
152 |
|
|
-sub helo_helper { |
153 |
|
|
- my ($self, $transaction, $helo) = @_; |
154 |
|
|
- $self->{_whitelist_soft_helo} = $helo; |
155 |
|
|
- return DECLINED; |
156 |
|
|
-} |
157 |
|
|
- |
158 |
|
|
-sub check_helo { |
159 |
|
|
- my ($self, $transaction, $helo) = @_; |
160 |
|
|
- |
161 |
|
|
- # If per_recipient will be rcpt hook, and helo actually rcpt |
162 |
|
|
- my $config_arg = {}; |
163 |
|
|
- if ($self->{_per_recipient}) { |
164 |
|
|
- $config_arg = { rcpt => $helo, %MERGE }; |
165 |
|
|
- $helo = $self->{_whitelist_soft_helo}; |
166 |
|
|
- } |
167 |
|
|
- |
168 |
|
|
- for my $h ($self->qp->config('whitelisthelo', $config_arg)) { |
169 |
|
|
- if ($helo and lc $h eq lc $helo) { |
170 |
|
|
- $self->qp->connection->notes('whitelisthelo', 1); |
171 |
|
|
- $self->log(2,"helo host $helo in whitelisthelo"); |
172 |
|
|
- return OK; |
173 |
|
|
- } |
174 |
|
|
- } |
175 |
|
|
- return DECLINED; |
176 |
|
|
-} |
177 |
|
|
- |
178 |
|
|
-sub check_sender { |
179 |
|
|
- my ($self, $transaction, $sender) = @_; |
180 |
|
|
- |
181 |
|
|
- # If per_recipient will be rcpt hook, and sender actually rcpt |
182 |
|
|
- my $config_arg = {}; |
183 |
|
|
- if ($self->{_per_recipient}) { |
184 |
|
|
- $config_arg = { rcpt => $sender, %MERGE }; |
185 |
|
|
- $sender = $transaction->sender; |
186 |
|
|
- } |
187 |
|
|
- |
188 |
|
|
- return DECLINED if $sender->format eq '<>'; |
189 |
|
|
- my $addr = lc $sender->address or return DECLINED; |
190 |
|
|
- my $host = lc $sender->host or return DECLINED; |
191 |
|
|
- |
192 |
|
|
- for my $h ($self->qp->config('whitelistsenders', $config_arg)) { |
193 |
|
|
- next unless $h; |
194 |
|
|
- $h = lc $h; |
195 |
|
|
- |
196 |
|
|
- if ($addr eq $h or $host eq $h) { |
197 |
|
|
- $transaction->notes('whitelistsender', 1); |
198 |
|
|
- $self->log(2,"envelope sender $addr in whitelistsenders"); |
199 |
|
|
- return OK; |
200 |
|
|
- } |
201 |
|
|
- } |
202 |
|
|
- return DECLINED; |
203 |
|
|
-} |
204 |
|
|
- |
205 |
|
|
-sub check_rcpt { |
206 |
|
|
- my ($self, $transaction, $rcpt) = @_; |
207 |
|
|
- |
208 |
|
|
- my $addr = lc $rcpt->address or return DECLINED; |
209 |
|
|
- my $host = lc $rcpt->host or return DECLINED; |
210 |
|
|
- |
211 |
|
|
- my $config_arg = $self->{_per_recipient} ? { rcpt => $rcpt, %MERGE } : {}; |
212 |
|
|
- for my $h ($self->qp->config('whitelistrcpt', $config_arg)) { |
213 |
|
|
- next unless $h; |
214 |
|
|
- $h = lc $h; |
215 |
|
|
- |
216 |
|
|
- if ($addr eq $h or $host eq $h) { |
217 |
|
|
- my $note = $transaction->notes('whitelistrcpt'); |
218 |
|
|
- $transaction->notes('whitelistrcpt', ++$note); |
219 |
|
|
- $self->log(2,"recipient $addr in whitelistrcpt"); |
220 |
|
|
- return OK; |
221 |
|
|
- } |
222 |
|
|
- } |
223 |
|
|
- return DECLINED; |
224 |
|
|
-} |
225 |
|
|
- |
226 |
|
|
-# arch-tag: 15a093f1-2960-4dbe-be72-584d7ff1d92a |
227 |
|
|
- |