~ubuntu-branches/ubuntu/natty/amavisd-new/natty

« back to all changes in this revision

Viewing changes to amavisd-new-qmqpqq.patch

  • Committer: Bazaar Package Importer
  • Author(s): Christian Perrier
  • Date: 2007-02-24 19:27:53 UTC
  • mfrom: (3.1.7 feisty)
  • Revision ID: james.westby@ubuntu.com-20070224192753-fvvima53q1jrp34x
Tags: 1:2.4.2-6.1
* Non-maintainer upload to fix pending l10n issues.
* Debconf translations
  - Remove extra debian/po/de.po~
  - Convert all translation files to UTF-8
  - Russian. Closes: #405243
  - Spanish. Closes: #408734
  - Italian. Closes: #409831
* Add very simple LSB headers to init scripts

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
--- amavisd.conf.ori    Tue Jun 29 18:14:44 2004
2
 
+++ amavisd.conf        Tue Jun 29 18:20:12 2004
3
 
@@ -224,8 +224,22 @@
4
 
 
5
 
 # SMTP SERVER (INPUT) PROTOCOL SETTINGS (e.g. with Postfix, Exim v4, ...)
6
 
-#   (used when MTA is configured to pass mail to amavisd via SMTP or LMTP)
7
 
-$inet_socket_port = 10024;        # accept SMTP on this local TCP port
8
 
+#   (used when MTA passing mail to amavisd via SMTP, LMTP or QMQPqq)
9
 
+$inet_socket_port = 10024;        # accept on this local TCP port
10
 
                                   # (default is undef, i.e. disabled)
11
 
-# multiple ports may be provided: $inet_socket_port = [10024, 10026, 10028];
12
 
+# multiple ports may be provided:
13
 
+#   $inet_socket_port = [10024, 10026, 10028, 10628];
14
 
+# multiple protocols may be provided with multiple ports
15
 
+# (according to the protocol port settings below)
16
 
+
17
 
+# SMTP or LMTP port
18
 
+$inet_smtp_port = 10024;          # accept on this local TCP port
19
 
+                                  # (default is undef, i.e. disabled)
20
 
+# multiple ports may be provided: $inet_smtp_port = [10024, 10025];
21
 
+
22
 
+# QMQPqq port (can be used only with qmail)
23
 
+$inet_qmqpqq_port = 10628;        # accept on this local TCP port
24
 
+                                  # (default is undef, i.e. disabled)
25
 
+# multiple ports may be provided: $inet_qmqpqq_port = [10628, 10629];
26
 
+
27
 
 
28
 
 # SMTP SERVER (INPUT) access control
29
 
--- amavisd.ori Tue Jun 29 18:14:54 2004
30
 
+++ amavisd     Tue Jun 29 18:20:12 2004
31
 
@@ -84,4 +84,5 @@
32
 
 #  Amavis::In::AMCL
 
1
--- amavisd.ori Tue Jun 27 13:22:56 2006
 
2
+++ amavisd     Tue Jun 27 13:30:29 2006
 
3
@@ -97,4 +97,5 @@
33
4
 #  Amavis::In::SMTP
 
5
 #( Amavis::In::Courier )
34
6
+#  Amavis::In::QMQPqq
35
 
 #  Amavis::AV
36
 
 #  Amavis::SpamControl
37
 
@@ -159,4 +160,5 @@
38
 
            $log_templ
39
 
            $unix_socketname $inet_socket_port $inet_socket_bind @inet_acl
40
 
+           $inet_smtp_port $inet_qmqpqq_port   
41
 
            $myhostname $localhost_name
42
 
            $insert_received_line
43
 
@@ -808,5 +810,6 @@
44
 
        &retcode &prolong_timer &sanitize_str &min &max
45
 
        &strip_tempdir &rmdir_recursively &rmdir_flat
46
 
-       &read_text &read_l10n_templates &read_hash &run_command);
47
 
+       &read_text &read_l10n_templates &read_hash &run_command
48
 
+       &if_exists_in_array);
49
 
 }
50
 
 use subs @EXPORT_OK;
51
 
@@ -1147,4 +1150,17 @@
52
 
 }
53
 
 
54
 
+# returns undef if value does not exist in array or position of the first occurence in the array
55
 
+sub if_exists_in_array($$) {
56
 
+my($value,$ref) = @_;
57
 
+(ref $ref eq 'ARRAY') || return(undef);
58
 
+
59
 
+for(my $i=0;$i<@{$ref};$i++) {
60
 
+       if($value eq $ref->[$i]) {
61
 
+               return($i);
62
 
+               }
63
 
+       }
64
 
+return(undef);
65
 
+}
66
 
+
67
 
 1;
68
 
 
69
 
@@ -1226,11 +1242,23 @@
70
 
 sub received_line($$$$) {
71
 
     my($conn, $msginfo, $id, $folded) = @_;
72
 
-    my($smtp_proto,$recips) = ($conn->smtp_proto, $msginfo->recips);
73
 
+    my($proto,$helo);
74
 
+
75
 
+    if(defined $conn->smtp_proto) {
76
 
+       $proto = $conn->smtp_proto;
77
 
+       $helo = $conn->smtp_helo;
78
 
+    }
79
 
+    elsif(defined $conn->qmqp_proto) {
80
 
+       $proto = $conn->qmqp_proto;
81
 
+       $helo = $conn->qmqp_helo;
82
 
+    }
83
 
+
84
 
     my($client_ip) = $conn->client_ip;
85
 
     if ($client_ip =~ /:/ && $client_ip !~ /^IPv6:/i) {
86
 
        $client_ip = 'IPv6:' . $client_ip;
87
 
     }
88
 
+
89
 
+    my($recips) = $msginfo->recips;
90
 
     my($s) = sprintf("from %s%s\n by %s%s (amavisd-new, %s)",
91
 
-       ($conn->smtp_helo eq '' ? 'unknown' : $conn->smtp_helo),
92
 
+       ($helo eq '' ? 'unknown' : $helo),
93
 
        ($client_ip eq '' ? '' : " ([$client_ip])"),
94
 
        $localhost_name,
95
 
@@ -1238,5 +1266,5 @@
96
 
            : sprintf(" (%s [%s])", $myhostname, $conn->socket_ip)),
97
 
        ($conn->socket_port eq '' ? 'unix socket' : "port ".$conn->socket_port));
98
 
-    $s .= "\n with $smtp_proto" if $smtp_proto =~ /^(ES|S|L)MTP$/i;
99
 
+    $s .= "\n with $proto" if defined($proto);
100
 
     $s .= "\n id $id"           if $id ne '';
101
 
     # do not disclose if many
102
 
@@ -2180,4 +2208,8 @@
103
 
 sub smtp_helo       # (E)SMTP HELO/EHLO parameter
104
 
   { my($self)=shift; !@_ ? $self->{smtp_helo} : ($self->{smtp_helo}=shift) }
105
 
+sub qmqp_proto      # QMQP/QMQPqq
106
 
+  { my($self)=shift; !@_ ? $self->{qmqp_proto}: ($self->{qmqp_proto}=shift) }
107
 
+sub qmqp_helo       # for future use maybe
108
 
+  { my($self)=shift; !@_ ? $self->{qmqp_helo} : ($self->{qmqp_helo}=shift) }
109
 
 
110
 
 1;
111
 
@@ -4922,5 +4954,5 @@
112
 
     import Amavis::Conf qw(:platform :confvars :notifyconf :sa);
113
 
     import Amavis::Util qw(do_log debug_oneshot am_id prolong_timer
114
 
-                          min max);
115
 
+                          min max if_exists_in_array);
116
 
     import Amavis::Timing qw(section_time);
117
 
     import Amavis::Log;
118
 
@@ -4950,4 +4982,5 @@
119
 
 use vars qw($extra_code_sql $extra_code_ldap
120
 
            $extra_code_in_amcl $extra_code_in_smtp
121
 
+           $extra_code_in_qmqpqq
122
 
            $extra_code_antivirus $extra_code_antispam);
123
 
 
124
 
@@ -4986,5 +5019,9 @@
125
 
            @banned_filename @bad_headers);
126
 
 
127
 
-use vars qw($amcl_in_obj $smtp_in_obj); # Amavis::In::AMCL and In::SMTP objects
128
 
+use vars qw($amcl_in_obj); # Amavis::In::AMCL object
129
 
+use vars qw($smtp_in_obj); # Amavis::In::SMTP object
130
 
+use vars qw($qmqpqq_in_obj); # Amavis::In::QMQPqq object
131
 
+use vars qw($inet_smtp_port $inet_qmqpqq_port);
132
 
+
133
 
 use vars qw($sql_policy $sql_wblist);   # Amavis::Lookup::SQL objects
134
 
 
135
 
@@ -5175,15 +5212,22 @@
136
 
            $conn->socket_port($prop->{sockport});
137
 
            $conn->client_ip($prop->{peeraddr});
138
 
-           if (!$extra_code_in_smtp) {
139
 
+
140
 
+           if (!$extra_code_in_smtp && !$extra_code_in_qmqpqq) {
141
 
                die ("incomming TCP connection, but dynamic code ".
142
 
-                    "to handle SMTP or LMTP not loaded");
143
 
-           } else {
144
 
+                    "to handle SMTP, LMTP or QMQPqq not loaded");
145
 
+           } elsif(defined if_exists_in_array($prop->{sockport},$inet_smtp_port)) {
146
 
                my($lmtp);  # false by default, start as a SMTP server
147
 
 #              $lmtp = $prop->{sockport} != 25 &&
148
 
 #                      $prop->{sockport} != $inet_socket_port;
149
 
                $smtp_in_obj = Amavis::In::SMTP->new  if !$smtp_in_obj;
150
 
-               $smtp_in_obj->process_smtp_request(
151
 
-                   $sock, $lmtp, $conn, \&check_mail);
152
 
+               $smtp_in_obj->process_smtp_request($sock, $lmtp, $conn, \&check_mail);
153
 
+           } elsif(defined if_exists_in_array($prop->{sockport},$inet_qmqpqq_port)) {
154
 
+               $qmqpqq_in_obj = Amavis::In::QMQPqq->new if !$qmqpqq_in_obj;
155
 
+               $qmqpqq_in_obj->process_qmqpqq_request($sock,$conn,\&check_mail);
156
 
+           } else {  # better to be safe than sorry
157
 
+               die ("dynamic code to handle incomming TCP connection on port '" .
158
 
+                    "$prop->{sockport}' is not loaded or does not exist (yet)");
159
 
            }
160
 
+
161
 
        } else {
162
 
            die ("unsupported protocol: " . $sock->NS_proto);
163
 
@@ -5235,6 +5279,7 @@
164
 
     local $SIG{CHLD} = 'DEFAULT';
165
 
 #   do_log(0, "Amavis::In::SMTP::DESTROY will be called from 'child_finish_hook'");
166
 
-    $smtp_in_obj = undef;  # calls Amavis::In::SMTP::DESTROY
167
 
-    $amcl_in_obj = undef;  # (currently does nothing for Amavis::In::AMCL)
168
 
+    $smtp_in_obj = undef;    # calls Amavis::In::SMTP::DESTROY
169
 
+    $qmqpqq_in_obj = undef;  # calls Amavis::In::QMQPqq::DESTROY
170
 
+    $amcl_in_obj = undef;    # (currently does nothing for Amavis::In::AMCL)
171
 
 }
172
 
 
173
 
@@ -6483,5 +6528,5 @@
174
 
     map { chomp($_ = <Amavis::DATA>) }
175
 
        ($extra_code_sql, $extra_code_ldap,
176
 
-        $extra_code_in_amcl, $extra_code_in_smtp,
177
 
+        $extra_code_in_amcl, $extra_code_in_smtp, $extra_code_in_qmqpqq,
178
 
         $extra_code_antivirus, $extra_code_antispam,
179
 
         $log_templ,
180
 
@@ -6510,5 +6555,5 @@
181
 
 $amavisd_path = $1 if $amavisd_path=~m{^([A-Za-z0-9/._=+-]+)$(?!\n)}; # untaint
182
 
 
183
 
-my($config_file) = '/etc/amavisd.conf';  # default location of config file
184
 
+my($config_file) = '/usr/local/etc/amavisd.conf';  # default location of config file
185
 
 if (@ARGV >= 2 && $ARGV[0] eq '-c') {    # override by command line option -c
186
 
     shift @ARGV; $config_file = shift @ARGV;
187
 
@@ -6537,10 +6582,88 @@
188
 
     $extra_code_in_amcl = 1;   # release memory occupied by the source code
189
 
 }
190
 
-if ($inet_socket_port eq '' || ref $inet_socket_port && !@$inet_socket_port) {
191
 
-    $extra_code_in_smtp = undef;
192
 
-} else {
193
 
-    eval $extra_code_in_smtp or die "Problem in the In::SMTP code: $@";
194
 
-    $extra_code_in_smtp = 1;   # release memory occupied by the source code
195
 
-}
196
 
+
197
 
+# make it a reference
198
 
+$inet_socket_port = ($inet_socket_port eq ''?
199
 
+       undef : (ref $inet_socket_port?
200
 
+               (@$inet_socket_port ?
201
 
+                       $inet_socket_port : undef) : [$inet_socket_port]));
202
 
+
203
 
+if(!ref $inet_socket_port) {
204
 
+       $extra_code_in_smtp = undef;
205
 
+       $extra_code_in_qmqpqq = undef;
206
 
+       }
207
 
+else {
208
 
+       # make it a reference
209
 
+       $inet_smtp_port = ($inet_smtp_port eq ''?
210
 
+               undef : (ref $inet_smtp_port?
211
 
+                       (@$inet_smtp_port ?
212
 
+                               [@$inet_smtp_port] : undef) : [$inet_smtp_port]));
213
 
+       # make it a reference
214
 
+       $inet_qmqpqq_port = ($inet_qmqpqq_port eq ''?
215
 
+               undef : (ref $inet_qmqpqq_port ?
216
 
+                       (@$inet_qmqpqq_port ?
217
 
+                               [@$inet_qmqpqq_port] : undef) : [$inet_qmqpqq_port]));
218
 
+
219
 
+       # check whether these two does not overlay
220
 
+       if(ref $inet_smtp_port && ref $inet_qmqpqq_port) {
221
 
+               foreach my $port (@$inet_smtp_port) {
222
 
+                       (!defined if_exists_in_array($port,$inet_qmqpqq_port)) ||
223
 
+                               die("QMQPqq port '$port' is already assigned to SMTP/LMTP");
224
 
+                       }
225
 
+               }
226
 
+
227
 
+       # check whether every $inet_socket_port is assigned some service
228
 
+       foreach my $port (@$inet_socket_port) {
229
 
+               if(ref $inet_smtp_port && defined if_exists_in_array($port,$inet_smtp_port)) {
230
 
+                       next;
231
 
+                       }
232
 
+               if(ref $inet_qmqpqq_port && defined if_exists_in_array($port,$inet_qmqpqq_port)) {
233
 
+                       next;
234
 
+                       }
235
 
+               die("Port '$port' is not assigned any service");
236
 
+               }
237
 
+       
238
 
+       if(ref $inet_smtp_port) {
239
 
+               # check whether $inet_smtp_port is in $inet_socket_port
240
 
+               my $if_any = undef;
241
 
+               foreach my $port (@$inet_smtp_port) {
242
 
+                       if(defined if_exists_in_array($port,$inet_socket_port)) {
243
 
+                               $if_any = 1;
244
 
+                               last;
245
 
+                               }
246
 
+                       }
247
 
+               if(!$if_any) {
248
 
+                       $extra_code_in_smtp = undef; # feature not a bug
249
 
+                       }
250
 
+               else {
251
 
+                       eval $extra_code_in_smtp || die("Problem in the In::SMTP code: $@");
252
 
+                       $extra_code_in_smtp = 1; # release memory occupied by the source code
253
 
+                       }
254
 
+               }
255
 
+       else {
256
 
+               $extra_code_in_smtp = undef;
257
 
+               }
258
 
+
259
 
+       if(ref $inet_qmqpqq_port) {
260
 
+               # check whether $inet_qmqpqq_port is in $inet_socket_port
261
 
+               my $if_any = undef;
262
 
+               foreach my $port (@$inet_qmqpqq_port) {
263
 
+                       if(defined if_exists_in_array($port,$inet_socket_port)) {
264
 
+                               $if_any = 1;
265
 
+                               last;
266
 
+                               }
267
 
+                       }
268
 
+               if(!$if_any) {
269
 
+                       $extra_code_in_qmqpqq = undef; # feature not a bug
270
 
+                       }
271
 
+               else {
272
 
+                       eval $extra_code_in_qmqpqq || die("Problem in the In::QMQPqq code: $@");
273
 
+                       $extra_code_in_qmqpqq = 1; # release memory occupied by the source code
274
 
+                       }
275
 
+               }
276
 
+       else {
277
 
+               $extra_code_in_qmqpqq = undef;
278
 
+               }
279
 
+       }
280
 
 
281
 
 if (!@av_scanners && !@av_scanners_backup) {
282
 
@@ -6633,4 +6756,5 @@
283
 
 do_log(1, "AMCL-in protocol code ".($extra_code_in_amcl?'':" NOT")." loaded");
284
 
 do_log(1, "SMTP-in protocol code ".($extra_code_in_smtp?'':" NOT")." loaded");
285
 
+do_log(1, "QMQPqq-in protocol code ".($extra_code_in_qmqpqq?'':" NOT")." loaded");
286
 
 do_log(1, "ANTI-VIRUS code       ".($extra_code_antivirus?'':" NOT")." loaded");
287
 
 do_log(1, "ANTI-SPAM  code       ".($extra_code_antispam?'':" NOT")." loaded");
288
 
@@ -7942,4 +8066,329 @@
289
 
        @{$self->{smtp_outbuf}} = ();
290
 
     }
291
 
+}
 
7
 #  Amavis::Out::SMTP
 
8
 #  Amavis::Out::Pipe
 
9
@@ -2422,4 +2423,5 @@
 
10
       : sprintf(" (%s [%s])", c('myhostname'), $conn->socket_ip) ),
 
11
     ($conn->socket_port eq '' ? 'unix socket' : "port ".$conn->socket_port) );
 
12
+  # must not use proto name QMQPqq in 'with'
 
13
   $s .= "\n with $smtp_proto"  if $smtp_proto=~/^(ES|S|L)MTPS?A?\z/i; # rfc3848
 
14
   $s .= "\n id $id"  if $id ne '';
 
15
@@ -6424,4 +6426,5 @@
 
16
   $extra_code_sql_lookup $extra_code_ldap
 
17
   $extra_code_in_amcl $extra_code_in_smtp $extra_code_in_courier
 
18
+  $extra_code_in_qmqpqq
 
19
   $extra_code_out_smtp $extra_code_out_pipe
 
20
   $extra_code_out_bsmtp $extra_code_out_local $extra_code_p0f
 
21
@@ -6447,4 +6450,5 @@
 
22
 # Amavis::In::AMCL, Amavis::In::SMTP and In::Courier objects
 
23
 use vars qw($amcl_in_obj $smtp_in_obj $courier_in_obj);
 
24
+use vars qw($qmqpqq_in_obj);            # Amavis::In::QMQPqq object
 
25
 use vars qw($sql_dataset_conn_lookups); # Amavis::Out::SQL::Connection object
 
26
 use vars qw($sql_dataset_conn_storage); # Amavis::Out::SQL::Connection object
 
27
@@ -6824,4 +6828,5 @@
 
28
   do_log(0,"SMTP-in proto code  %s loaded", $extra_code_in_smtp    ?'':" NOT");
 
29
   do_log(0,"Courier proto code  %s loaded", $extra_code_in_courier ?'':" NOT");
 
30
+  do_log(0,"QMQPqq-in proto code %s loaded", $extra_code_in_qmqpqq ?'':" NOT");
 
31
   do_log(0,"SMTP-out proto code %s loaded", $extra_code_out_smtp   ?'':" NOT");
 
32
   do_log(0,"Pipe-out proto code %s loaded", $extra_code_out_pipe   ?'':" NOT");
 
33
@@ -7214,4 +7219,10 @@
 
34
         $amcl_in_obj = Amavis::In::AMCL->new  if !$amcl_in_obj;
 
35
         $amcl_in_obj->process_policy_request($sock, $conn, \&check_mail, 0);
 
36
+      } elsif ($suggested_protocol eq 'QMQPqq') {
 
37
+        if (!$extra_code_in_qmqpqq) {
 
38
+          die "incoming TCP connection, but dynamic QMQPqq code not loaded";
 
39
+        }
 
40
+        $qmqpqq_in_obj = Amavis::In::QMQPqq->new if !$qmqpqq_in_obj;
 
41
+        $qmqpqq_in_obj->process_qmqpqq_request($sock,$conn,\&check_mail);
 
42
       } else {  # defaults to SMTP or LMTP
 
43
         if (!$extra_code_in_smtp) {
 
44
@@ -7297,4 +7308,5 @@
 
45
   do_log(5,"child_finish_hook: invoking DESTROY methods");
 
46
   undef $smtp_in_obj; undef $amcl_in_obj; undef $courier_in_obj;
 
47
+  undef $qmqpqq_in_obj;
 
48
   undef $sql_storage; undef $sql_wblist; undef $sql_policy; undef $ldap_policy;
 
49
   undef $sql_dataset_conn_lookups; undef $sql_dataset_conn_storage;
 
50
@@ -7307,4 +7319,5 @@
 
51
 # do_log(5,"at the END handler: invoking DESTROY methods");
 
52
   undef $smtp_in_obj; undef $amcl_in_obj; undef $courier_in_obj;
 
53
+  undef $qmqpqq_in_obj;
 
54
   undef $sql_storage; undef $sql_wblist; undef $sql_policy; undef $ldap_policy;
 
55
   undef $sql_dataset_conn_lookups; undef $sql_dataset_conn_storage;
 
56
@@ -9208,4 +9221,5 @@
 
57
     $extra_code_sql_lookup, $extra_code_ldap,
 
58
     $extra_code_in_amcl, $extra_code_in_smtp, $extra_code_in_courier,
 
59
+    $extra_code_in_qmqpqq,
 
60
     $extra_code_out_smtp, $extra_code_out_pipe,
 
61
     $extra_code_out_bsmtp, $extra_code_out_local, $extra_code_p0f,
 
62
@@ -9455,5 +9469,10 @@
 
63
     $extra_code_in_courier = undef;
 
64
   }
 
65
-  if ($needed_protocols_in{'QMQPqq'})  { die "In::QMQPqq code not available" }
 
66
+  if ($needed_protocols_in{'QMQPqq'}) {
 
67
+    eval $extra_code_in_qmqpqq or die "Problem in the In::QMQPqq code: $@";
 
68
+    $extra_code_in_qmqpqq = 1;  # release memory occupied by the source code
 
69
+  } else {
 
70
+    $extra_code_in_qmqpqq = undef;
 
71
+  }
 
72
 }
 
73
 
 
74
@@ -12152,4 +12171,270 @@
 
75
 
 
76
 BEGIN { die "Code not available for module Amavis::In::Courier" }
292
77
+
293
78
+1;
294
79
+
296
81
+#
297
82
+package Amavis::In::QMQPqq;
298
83
+use strict;
 
84
+# use re 'taint';   # (is this module ready for this yet?)
299
85
+
300
86
+BEGIN {
301
87
+    use Exporter ();
302
88
+    use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
303
 
+    $VERSION = '1.15';
 
89
+    $VERSION = '1.18';
304
90
+    @ISA = qw(Exporter);
305
91
+}
306
92
+use POSIX qw(strftime);
307
93
+use Errno qw(ENOENT);
308
 
+use Time::HiRes qw(time);
309
94
+
310
95
+BEGIN {
311
 
+    import Amavis::Conf qw(:platform :confvars);
312
 
+    import Amavis::Util qw(do_log am_id prolong_timer debug_oneshot
313
 
+       sanitize_str strip_tempdir rmdir_recursively);
 
96
+    import Amavis::Conf qw(:platform :confvars :dynamic_confvars c cr ca);
 
97
+    import Amavis::Util qw(ll do_log am_id new_am_id prolong_timer
 
98
+                           debug_oneshot sanitize_str rmdir_recursively);
314
99
+    import Amavis::Lookup qw(lookup);
315
100
+    import Amavis::Timing qw(section_time);
316
101
+    import Amavis::rfc2821_2822_Tools;
 
102
+    import Amavis::TempDir;
317
103
+    import Amavis::In::Message;
318
104
+    import Amavis::In::Connection;
319
105
+}
321
107
+sub new($) {
322
108
+    my($class) = @_;
323
109
+    my($self) = bless {}, $class;
324
 
+    $self->{fh_pers} = undef;           # persistent file handle for email.txt
325
 
+    $self->{tempdir_pers} = undef;     # temporary directory for check_mail
326
 
+    $self->{preserve} = undef;          # don't delete tempdir on exit
327
 
+    $self->{tempdir_empty} = 1;         # anything of interest in tempdir?
328
110
+    $self->{bytesleft} = undef;                # bytes left for whole package
329
111
+    $self->{len} = undef;              # set by getlen() method
330
112
+    $self->{sock} = undef;             # connected socket
331
113
+    $self->{proto} = undef;            # protocol
 
114
+    $self->{tempdir} = Amavis::TempDir->new;   # TempDir object
332
115
+    $self->{session_closed_normally} = undef; # closed properly? (waited for K/Z/D)
333
116
+    $self;
334
117
+}
335
118
+
336
 
+sub preserve_evidence  # try to preserve temporary files etc in case of trouble
337
 
+  { my($self)=shift; !@_ ? $self->{preserve} : ($self->{preserve}=shift) }
338
 
+
339
119
+sub DESTROY {
340
 
+    my($self) = shift;
341
 
+#   do_log(0, "Amavis::In::QMQPqq::DESTROY called");
342
 
+    $self->{fh_pers}->close
343
 
+       or die "Can't close temp file: $!"  if $self->{fh_pers};
344
 
+    my($errn) = $self->{tempdir_pers} eq '' ? ENOENT
345
 
+                   : (stat($self->{tempdir_pers}) ? 0 : 0+$!);
346
 
+    if (defined $self->{tempdir_pers} && $errn != ENOENT) {
347
 
+       # this will not be included in the TIMING report,
348
 
+       # but it only occurs infrequently and doesn't take that long
349
 
+       if ($self->preserve_evidence && !$self->{tempdir_empty}) {
350
 
+           do_log(0, "tempdir is to be PRESERVED: ".$self->{tempdir_pers});
351
 
+       } else {
352
 
+           do_log(2, "tempdir being removed: ".$self->{tempdir_pers});
353
 
+           rmdir_recursively($self->{tempdir_pers});
354
 
+       }
355
 
+    }
356
 
+    if (! $self->{session_closed_normally}) {
357
 
+       $self->qmqpqq_resp("Z","Service shutting down, closing channel");
358
 
+    }
359
 
+}
360
 
+
361
 
+sub prepare_tempdir($) {
362
 
+    my($self) = @_;
363
 
+    if (! defined $self->{tempdir_pers} ) {
364
 
+       # invent a name for a temporary directory for this child, and create it
365
 
+       my($now_iso8601) = strftime("%Y%m%dT%H%M%S", localtime);
366
 
+       $self->{tempdir_pers} = sprintf("%s/amavis-%s-%05d",
367
 
+                                       $TEMPBASE, $now_iso8601, $$);
368
 
+    }
369
 
+    my($errn) = stat($self->{tempdir_pers}) ? 0 : 0+$!;
370
 
+    if ($errn == ENOENT || ! -d _) {
371
 
+       mkdir($self->{tempdir_pers}, 0750)
372
 
+           or die "Can't create directory $self->{tempdir_pers}: $!";
373
 
+       $self->{tempdir_empty} = 1;
374
 
+       section_time('mkdir tempdir');
375
 
+    }
376
 
+    # prepare temporary file for writing (and reading later)
377
 
+    my($fname) = $self->{tempdir_pers} . "/email.txt";
378
 
+    my($errn) = stat($fname) ? 0 : 0+$!;
379
 
+    if ($self->{fh_pers} && !$errn && -f _) {
380
 
+       $self->{fh_pers}->seek(0,0) or die "Can't rewind mail file: $!";
381
 
+       $self->{fh_pers}->truncate(0) or die "Can't truncate mail file: $!";
382
 
+    } else {
383
 
+       $self->{fh_pers} = IO::File->new($fname, 'w+', 0640)
384
 
+           or die "Can't create file $fname: $!";
385
 
+       section_time('create email.txt');
386
 
+    }
387
 
+}
388
 
+
 
120
+  my($self) = shift;
 
121
+  eval { do_log(5,"Amavis::In::QMQPqq DESTROY called, sock=%s, normal=%s",
 
122
+                  $self->{sock}, $self->{session_closed_normally}) };
 
123
+  eval {
 
124
+    if (ref($self->{sock}) && ! $self->{session_closed_normally}) {
 
125
+      $self->qmqpqq_resp("Z","Service shutting down, closing channel");
 
126
+    }
 
127
+  };
 
128
+  if ($@ ne '')
 
129
+    { my($eval_stat) = $@; eval { do_log(1,"QMQPqq shutdown: %s",$eval_stat) } }
 
130
+}
389
131
+
390
132
+# get byte, die if no bytes left
391
133
+sub getbyte($) {
430
172
+$self->getcomma;
431
173
+}
432
174
+
433
 
+
434
175
+# Accept a QMQPqq connect
435
176
+# and call content checking for the message received
436
177
+#
441
182
+# $check_mail: subroutine ref to be called with file handle
442
183
+
443
184
+$self->{proto} = "QMQPqq";
 
185
+$self->{session_closed_normally} = 0;  # closed properly?
444
186
+$self->{sock} = $sock;         # store $sock info for getbyte() method
445
187
+$self->{bytesleft} = 20;       # initial bytesleft value, there should
446
188
+                               # NEVER EVER be longer email than 10^20 (approximately)
448
190
+$self->{len} = undef;
449
191
+
450
192
+my($msginfo);
451
 
+
452
193
+my($sender,@recips);
453
 
+
454
194
+my($len);
455
195
+
456
 
+$conn->qmqp_proto("QMQPqq");
457
 
+$conn->qmqp_helo("QMQPqq client");  # for future possible use
 
196
+new_am_id(undef, $Amavis::child_invocation_count, undef);
 
197
+Amavis::Timing::init();
 
198
+
 
199
+$conn->smtp_proto("QMQPqq");  # the name of the method is too specific
458
200
+eval {
459
201
+       # get length of whole package
460
202
+       $self->{bytesleft} = $self->getlen;
463
205
+       $len = $self->getlen;
464
206
+       section_time('initial length determination');
465
207
+
466
 
+       am_id(sprintf("%05d-%02d",$$,$Amavis::child_invocation_count));
467
 
+
468
208
+       # prepare tempdir
469
 
+       $self->prepare_tempdir;
 
209
+       Amavis::check_mail_begin_task();
 
210
+       $self->{tempdir}->prepare;
 
211
+       $self->{tempdir}->prepare_file;
 
212
+
470
213
+       $msginfo = Amavis::In::Message->new;
471
214
+       $msginfo->rx_time(time);
 
215
+       $msginfo->delivery_method(c('forward_method'));
472
216
+
473
217
+       # get 'email'
474
 
+       $self->{tempdir_empty} = 0;
 
218
+       $self->{tempdir}->empty(0);
475
219
+       my $size = 16384;
476
220
+       while(($len > 0) && ($sock->read($_,($len >= $size ? $size : $size = $len)) == $size)) {
477
 
+               (print {$self->{fh_pers}} $_) ||
 
221
+               (print {$self->{tempdir}->fh} $_) ||
478
222
+                       die("Can't write to mail file: $!");
479
223
+               $len -= $size;
480
224
+               }
481
225
+       if($len > 0) {
482
226
+               die("EOF on socket");
483
227
+               }
484
 
+       $self->{fh_pers}->flush || die("Can't flush mail file: $!");
485
 
+       $self->{fh_pers}->seek(0,1) || die("Can't seek on file: $!");
 
228
+       $self->{tempdir}->fh->flush || die("Can't flush mail file: $!");
 
229
+       $self->{tempdir}->fh->seek(0,1) || die("Can't seek on file: $!");
486
230
+       $self->{bytesleft} -= $self->{len};
487
231
+       section_time('email receiving');
488
232
+       # comma has to follow
519
263
+                       received_line($conn,$msginfo,am_id(),0) )
520
264
+               ));
521
265
+
522
 
+       $msginfo->mail_text($self->{fh_pers});
 
266
+       $msginfo->mail_tempdir($self->{tempdir}->path);
 
267
+       $msginfo->mail_text_fn($self->{tempdir}->path . '/email.txt');
 
268
+       $msginfo->mail_text($self->{tempdir}->fh);
 
269
+
523
270
+       my($smtp_resp,$exit_code,$preserve_evidence) =
524
 
+               &$check_mail($conn,$msginfo,0,$self->{tempdir_pers});
525
 
+
526
 
+       if ($preserve_evidence) {
527
 
+               $self->preserve_evidence(1);
528
 
+               }
 
271
+               &$check_mail($conn,$msginfo,0);
 
272
+
 
273
+       if ($preserve_evidence) { $self->{tempdir}->preserve(1) }
 
274
+
529
275
+       if ($smtp_resp !~ /^4/ &&
530
276
+               grep { !$_->recip_done } @{$msginfo->per_recip_data}) {
531
277
+               die("TROUBLE/MISCONFIG: not all recipients done, ".
532
278
+                       "\$forward_method is \"$forward_method\"");
533
279
+               }
534
280
+
 
281
+       if ($smtp_resp !~ /^4/ &&
 
282
+               grep { !$_->recip_done } @{$msginfo->per_recip_data}) {
 
283
+               if ($msginfo->delivery_method eq '') {
 
284
+                       do_log(2,"not all recipients done, forward_method is empty");
 
285
+                       }
 
286
+               else {
 
287
+                       die "TROUBLE: (MISCONFIG) not all recipients done, " .
 
288
+                       "forward_method is: " . $msginfo->delivery_method;
 
289
+                       }
 
290
+               }
 
291
+
535
292
+       # all ok
536
293
+       if($smtp_resp =~ /^2/) {
537
294
+               $self->qmqpqq_resp("K",$smtp_resp);
546
303
+               }
547
304
+       };
548
305
+
549
 
+alarm(0); do_log(5,"timer stopped after QMQPqq eval");
 
306
+$self->{tempdir}->clean;
 
307
+alarm(0); do_log(4,"timer stopped after QMQPqq eval");
550
308
+
551
309
+if($@ ne '') {
552
310
+       chomp($@);
554
312
+       do_log(0,"QMQPqq: NOTICE: $@");
555
313
+       $self->qmqpqq_resp("Z","Service shutting down, $@");
556
314
+       }
557
 
+
558
 
+if ($self->preserve_evidence && !$self->{tempdir_empty}) {
559
 
+       # keep evidence in case of trouble
560
 
+       do_log(0,"PRESERVING EVIDENCE in ".$self->{tempdir_pers});
561
 
+       $self->{fh_pers}->close or die "Can't close mail file: $!";
562
 
+       $self->{fh_pers} = undef; $self->{tempdir_pers} = undef;
563
 
+       $self->{tempdir_empty} = 1;
564
 
+       }
565
 
+
566
 
+# cleanup, but leave directory (and file handle
567
 
+# if possible) for reuse
568
 
+if ($self->{fh_pers} && !$can_truncate) {
569
 
+       # truncate is not standard across all Unix variants,
570
 
+       # it is not Posix, but is XPG4-UNIX.
571
 
+       # So if we can't truncate a file and leave it open,
572
 
+       # we have to create it anew later, at some cost.
573
 
+       #
574
 
+       $self->{fh_pers}->close or die "Can't close mail file: $!";
575
 
+       $self->{fh_pers} = undef;
576
 
+       unlink($self->{tempdir_pers}."/email.txt")
577
 
+               or die "Can't delete file ".
578
 
+       $self->{tempdir_pers}."/email.txt: $!";
579
 
+       section_time('delete email.txt');
580
 
+       }
581
 
+
582
 
+if (defined $self->{tempdir_pers}) { # prepare for the next one
583
 
+       strip_tempdir($self->{tempdir_pers});
584
 
+       $self->{tempdir_empty} = 1;
585
 
+       }
586
 
+
587
 
+$self->preserve_evidence(0);  # reset
588
315
+# report elapsed times by section for each transaction
589
 
+do_log(2, Amavis::Timing::report());
 
316
+do_log(2, "%s", Amavis::Timing::report());
590
317
+
591
318
+$self->{session_closed_normally} = 1;
592
319
+# closes connection after child_finish_hook
604
331
+       sleep 5;
605
332
+       section_time('QMQPqq penalty wait');
606
333
+       }
607
 
+my($taint) = substr($resp,0,0);
608
334
+$resp = sanitize_str($resp,1);
609
335
+do_log(4,"QMQPqq> $resp");
610
336
+print($self->netstring($code . $resp));
613
339
+sub netstring($$) {
614
340
+my($self,$string) = @_;
615
341
+return(sprintf("%d:%s,",length($string),$string));
616
 
 }
617
 
 
 
342
+}
 
343
 
 
344
 1;
 
345
--- amavisd.conf.ori    Tue Jun 27 13:23:18 2006
 
346
+++ amavisd.conf        Tue Jun 27 13:30:29 2006
 
347
@@ -49,5 +49,6 @@
 
348
 $enable_global_cache = 1;    # enable use of libdb-based cache if $enable_db=1
 
349
 
 
350
-$inet_socket_port = 10024;   # listen on this local TCP port(s) (see $protocol)
 
351
+$protocol = 'QMQPqq';        # suggested protocol to use on all input sockets
 
352
+$inet_socket_port = 10628;   # accept connections on this local TCP port(s)
 
353
 $unix_socketname = "$MYHOME/amavisd.sock";  # amavisd-release or amavis-milter
 
354
                 # option(s) -p overrides $inet_socket_port and $unix_socketname
 
355
--- amavisd.conf-sample.ori     Tue Jun 27 13:23:34 2006
 
356
+++ amavisd.conf-sample Tue Jun 27 13:30:29 2006
 
357
@@ -225,8 +225,11 @@
 
358
 # SMTP SERVER (INPUT) PROTOCOL SETTINGS (e.g. with Postfix, Exim v4, ...)
 
359
 #   (used when MTA is configured to pass mail to amavisd via SMTP or LMTP)
 
360
-$inet_socket_port = 10024;        # accept SMTP on this local TCP port
 
361
+#$inet_socket_port = 10024;       # accept connection on this local TCP port
 
362
                                   # (default is undef, i.e. disabled)
 
363
 # multiple ports may be provided: $inet_socket_port = [10024, 10026, 10028];
 
364
 
 
365
+$protocol = 'QMQPqq';        # suggested protocol to use on all input sockets
 
366
+$inet_socket_port = 10628;   # accept connections on this local TCP port(s)
 
367
+
 
368
 # SMTP SERVER (INPUT) access control
 
369
 # - do not allow free access to the amavisd SMTP port !!!
 
370
@@ -2247,8 +2250,14 @@
 
371
 #   ],
 
372
 # };
 
373
+#
 
374
+# $policy_bank{'QMQPqq'} = {
 
375
+#   log_level => 3,
 
376
+#   protocol=>'QMQPqq', # possible with patch amavisd-new-qmqpqq.patch applied
 
377
+# };
 
378
 
 
379
 # NOTE: the use of policy banks for changing protocol on the input socket is
 
380
 # only needed when different protocols need to be spoken on different sockets
 
381
 # at the same time. For normal use just set globally e.g.: $protocol='AM.PDP';
 
382
+# $interface_policy{'10628'} = 'QMQPqq';
 
383
 #
 
384
 #$policy_bank{'AM.PDP-SOCK'} = {