Completed
Pull Request — master (#27)
by Michael
01:42
created

include/phpmailer_bmh/phpmailer-bmh_rules.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*~ phpmailer-bmh_rules.php
3
.---------------------------------------------------------------------------.
4
|  Software: PHPMailer-BMH (Bounce Mail Handler)                            |
5
|   Version: 5.0.0rc1                                                       |
6
|   Contact: [email protected]                             |
7
|      Info: http://phpmailer.codeworxtech.com                              |
8
| ------------------------------------------------------------------------- |
9
|    Author: Andy Prevost [email protected] (admin)                 |
10
| Copyright (c) 2002-2009, Andy Prevost. All Rights Reserved.               |
11
| ------------------------------------------------------------------------- |
12
|   License: Distributed under the General Public License (GPL)             |
13
|            (http://www.gnu.org/licenses/gpl.html)                         |
14
| This program is distributed in the hope that it will be useful - WITHOUT  |
15
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |
16
| FITNESS FOR A PARTICULAR PURPOSE.                                         |
17
| ------------------------------------------------------------------------- |
18
| This is a update of the original Bounce Mail Handler script               |
19
| http://sourceforge.net/projects/bmh/                                      |
20
| The script has been renamed from Bounce Mail Handler to PHPMailer-BMH     |
21
| ------------------------------------------------------------------------- |
22
| We offer a number of paid services:                                       |
23
| - Web Hosting on highly optimized fast and secure servers                 |
24
| - Technology Consulting                                                   |
25
| - Oursourcing (highly qualified programmers and graphic designers)        |
26
'---------------------------------------------------------------------------'
27
Last updated: January 21 2009 13:49 EST
28
29
/**
30
* next rule number (BODY): 0238 <br>
31
* default category:        unrecognized: <br>
32
* default rule no.:        0000 <br>
33
*/
34
35
global $rule_categories;
36
$rule_categories = [
37
    'antispam'       => ['remove' => 0, 'bounce_type' => 'blocked'],
38
    'autoreply'      => ['remove' => 0, 'bounce_type' => 'autoreply'],
39
    'concurrent'     => ['remove' => 2, 'bounce_type' => 'soft'],
40
    'content_reject' => ['remove' => 2, 'bounce_type' => 'soft'],
41
    'command_reject' => ['remove' => 1, 'bounce_type' => 'hard'],
42
    'internal_error' => ['remove' => 0, 'bounce_type' => 'temporary'],
43
    'defer'          => ['remove' => 2, 'bounce_type' => 'soft'],
44
    'delayed'        => ['remove' => 0, 'bounce_type' => 'temporary'],
45
    'dns_loop'       => ['remove' => 1, 'bounce_type' => 'hard'],
46
    'dns_unknown'    => ['remove' => 1, 'bounce_type' => 'hard'],
47
    'full'           => ['remove' => 2, 'bounce_type' => 'soft'],
48
    'inactive'       => ['remove' => 1, 'bounce_type' => 'hard'],
49
    'latin_only'     => ['remove' => 2, 'bounce_type' => 'soft'],
50
    'other'          => ['remove' => 0, 'bounce_type' => 'generic'],
51
    'oversize'       => ['remove' => 2, 'bounce_type' => 'soft'],
52
    'outofoffice'    => ['remove' => 2, 'bounce_type' => 'soft'],
53
    'unknown'        => ['remove' => 1, 'bounce_type' => 'hard'],
54
    'unrecognized'   => ['remove' => 0, 'bounce_type' => false],
55
    'user_reject'    => ['remove' => 1, 'bounce_type' => 'hard'],
56
    'warning'        => ['remove' => 2, 'bounce_type' => 'soft'],
57
];
58
59
/*
60
 * var for new line ending
61
 */
62
$bmh_newline = "<br>\n";
63
64
/**
65
 * Defined bounce parsing rules for non-standard DSN
66
 *
67
 * @param string $body       body of the email
68
 * @param string $structure  message structure
69
 * @param bool   $debug_mode show debug info. or not
70
 *
71
 * @return array $result an array include the following fields: 'email', 'bounce_type','remove','rule_no','rule_cat'
72
 *               if we could NOT detect the type of bounce, return rule_no = '0000'
73
 */
74
function bmhBodyRules($body, $structure, $debug_mode = false)
75
{
76
    // initialize the result array
77
    $result = [
78
        'email'       => '',
79
        'bounce_type' => false,
80
        'remove'      => 0,
81
        'rule_cat'    => 'unrecognized',
82
        'rule_no'     => '0000',
83
    ];
84
85
    // ======== rule =========
86
    if (false) {
87
    } /*
88
   * rule: mailbox unknow;
89
   * sample:
90
   * Delivery to the following recipients failed.
91
   * [email protected]
92 View Code Duplication
   */ elseif (preg_match("/delivery[^\n\r]+failed\S*\s+(\S+@\S+\w)\s/is", $body, $match)) {
93
        $result['rule_cat'] = 'unknown';
94
        $result['rule_no']  = '0013';
95
        $result['email']    = $match[1];
96
    } /*
97
   * rule: western chars only
98
   * sample:
99
   * <[email protected]>:
100
   * The user does not accept email in non-Western (non-Latin) character sets.
101 View Code Duplication
   */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*does not accept[^\r\n]*non-Western/i", $body, $match)) {
102
        $result['rule_cat'] = 'latin_only';
103
        $result['rule_no']  = '0043';
104
        $result['email']    = $match[1];
105
    } /*
106
   * rule: mailbox full;
107
   * sample:
108
   *   ----- Transcript of session follows -----
109
   * mail.local: /var/mail/2b/10/kellen.lee: Disc quota exceeded
110
   * 554 <[email protected]>... Service unavailable
111 View Code Duplication
   */ elseif (preg_match("/quota exceeded.*\n?.*<(\S+@\S+\w)>/i", $body, $match)) {
112
        $result['rule_cat'] = 'full';
113
        $result['rule_no']  = '0126';
114
        $result['email']    = $match[1];
115
    } /*
116
   * rule: mailbox unknown;
117
   * sample:
118
   * <[email protected]>:
119
   * Sorry, no mailbox here by that name. vpopmail (#5.1.1)
120 View Code Duplication
   */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*no mailbox/i", $body, $match)) {
121
        $result['rule_cat'] = 'unknown';
122
        $result['rule_no']  = '0157';
123
        $result['email']    = $match[1];
124
    } /*
125
   * rule: mailbox full;
126
   * sample:
127
   * Hi. This is the qmail-send program at 263.domain.com.
128
   * <[email protected]>:
129
   * - User disk quota exceeded. (#4.3.0)
130 View Code Duplication
   */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*quota exceeded/i", $body, $match)) {
131
        $result['rule_cat'] = 'full';
132
        $result['rule_no']  = '0158';
133
        $result['email']    = $match[1];
134
    } /*
135
   * rule: defer
136
   * sample:
137
   * <[email protected]>:
138
   * 111.111.111.111 failed after I sent the message.
139
   * Remote host said: 451 mta283.mail.scd.yahoo.com Resources temporarily unavailable. Please try again later [#4.16.5].
140 View Code Duplication
   */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*\n?.*Resources temporarily unavailable/i", $body, $match)) {
141
        $result['rule_cat'] = 'defer';
142
        $result['rule_no']  = '0163';
143
        $result['email']    = $match[1];
144
    } /*
145
   * rule: mailbox unknown;
146
   * sample:
147
   * [email protected]<br>
148
   * local: Sorry, can't find user's mailbox. (#5.1.1)<br>
149 View Code Duplication
   */ elseif (preg_match("/(\S+@\S+\w)<br>.*\n?.*\n?.*can't find.*mailbox/i", $body, $match)) {
150
        $result['rule_cat'] = 'unknown';
151
        $result['rule_no']  = '0164';
152
        $result['email']    = $match[1];
153
    } /*
154
   * rule: mailbox full;
155
   * sample:
156
   * [email protected]
157
   * mailbox is full (MTA-imposed quota exceeded while writing to file /mbx201/mbx011/A100/09/35/A1000935772/mail/.inbox):
158 View Code Duplication
   */ elseif (preg_match("/\s(\S+@\S+\w)\s.*\n?.*mailbox.*full/i", $body, $match)) {
159
        $result['rule_cat'] = 'full';
160
        $result['rule_no']  = '0166';
161
        $result['email']    = $match[1];
162
    } /*
163
   * rule: autoreply
164
   * sample:
165
   * AutoReply message from [email protected]
166 View Code Duplication
   */ elseif (preg_match("/^AutoReply message from (\S+@\S+\w)/i", $body, $match)) {
167
        $result['rule_cat'] = 'autoreply';
168
        $result['rule_no']  = '0167';
169
        $result['email']    = $match[1];
170
    } /*
171
   * rule: mailbox full;
172
   * sample:
173
   * The message to [email protected] is bounced because : Quota exceed the hard limit
174 View Code Duplication
   */ elseif (preg_match("/The message to (\S+@\S+\w)\s.*bounce.*Quota exceed/i", $body, $match)) {
175
        $result['rule_cat'] = 'full';
176
        $result['rule_no']  = '0168';
177
        $result['email']    = $match[1];
178
    } /*
179
   * rule: mailbox unknown;
180
   * sample:
181
   *     ##########################################################
182
   *     #  This is an automated response from a mail delivery    #
183
   *     #  program.  Your message could not be delivered to      #
184
   *     #  the following address:                                #
185
   *     #                                                        #
186
   *     #      "|/usr/local/bin/mailfilt -u #dkms"               #
187
   *     #        (reason: Can't create output)                   #
188
   *     #        (expanded from: <[email protected]>)         #
189
   *     #                                                        #
190 View Code Duplication
   */ elseif (preg_match("/Can't create output.*\n?.*<(\S+@\S+\w)>/i", $body, $match)) {
191
        $result['rule_cat'] = 'unknown';
192
        $result['rule_no']  = '0169';
193
        $result['email']    = $match[1];
194
    } /*
195
   * rule: inactive
196
   * sample:
197
   * [email protected]<br>
198
   * 553 user is inactive (eyou mta)
199 View Code Duplication
   */ elseif (preg_match("/(\S+@\S+\w)<br>.*\n?.*\n?.*user is inactive/i", $body, $match)) {
200
        $result['rule_cat'] = 'inactive';
201
        $result['rule_no']  = '0171';
202
        $result['email']    = $match[1];
203
    } /*
204
   * rule: internal_error
205
   * sample:
206
   * <[email protected]>:
207
   * Unable to switch to /var/vpopmail/domains/domain.com: input/output error. (#4.3.0)
208 View Code Duplication
   */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*input\/output error/i", $body, $match)) {
209
        $result['rule_cat']    = 'internal_error';
210
        $result['rule_no']     = '0172';
211
        $result['bounce_type'] = 'hard';
212
        $result['remove']      = 1;
213
        $result['email']       = $match[1];
214
    } /*
215
   * rule: internal_error
216
   * sample:
217
   * <[email protected]>:
218
   * can not open new email file errno=13 file=/home/vpopmail/domains/fromc.com/0/domain/Maildir/tmp/1155254417.28358.mx05,S=212350
219 View Code Duplication
   */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*can not open new email file/i", $body, $match)) {
220
        $result['rule_cat']    = 'internal_error';
221
        $result['rule_no']     = '0173';
222
        $result['bounce_type'] = 'hard';
223
        $result['remove']      = 1;
224
        $result['email']       = $match[1];
225
    } /*
226
   * rule: mailbox unknown;
227
   * sample:
228
   * ????????????????:
229
   * [email protected] : ????, ?????.
230 View Code Duplication
   */ elseif (preg_match("/(\S+@\S+\w).*=D5=CA=BA=C5=B2=BB=B4=E6=D4=DA/i", $body, $match)) {
231
        $result['rule_cat'] = 'unknown';
232
        $result['rule_no']  = '0174';
233
        $result['email']    = $match[1];
234
    } /*
235
   * rule: mailbox unknown;
236
   * sample:
237
   * [email protected]
238
   * Unrouteable address
239 View Code Duplication
   */ elseif (preg_match("/(\S+@\S+\w).*\n?.*Unrouteable address/i", $body, $match)) {
240
        $result['rule_cat'] = 'unknown';
241
        $result['rule_no']  = '0179';
242
        $result['email']    = $match[1];
243
    } /*
244
   * rule: inactive
245
   * sample:
246
   * [email protected] [Inactive account]
247 View Code Duplication
   */ elseif (preg_match("/(\S+@\S+\w).*inactive account/i", $body, $match)) {
248
        $result['rule_cat'] = 'inactive';
249
        $result['rule_no']  = '0181';
250
        $result['email']    = $match[1];
251
    } /*
252
   * rule: full
253
   * sample 1:
254
   * <[email protected]>:
255
   * This account is over quota and unable to receive mail.
256
   * sample 2:
257
   * <[email protected]>:
258
   * Warning: undefined mail delivery mode: normal (ignored).
259
   * The users mailfolder is over the allowed quota (size). (#5.2.2)
260 View Code Duplication
   */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*\n?.*over.*quota/i", $body, $match)) {
261
        $result['rule_cat'] = 'full';
262
        $result['rule_no']  = '0182';
263
        $result['email']    = $match[1];
264
    } /*
265
   * rule: mailbox unknow;
266
   * sample:
267
   * A message that you sent could not be delivered to one or more of its^M
268
   * recipients. This is a permanent error. The following address(es) failed:^M
269
   * ^M
270
   * [email protected]^M
271
   * unknown local-part "xxxxx" in domain "yourdomain.com"^M
272 View Code Duplication
   */ elseif (preg_match("/(\S+@\S+\w).*\n?.*unknown local-part/i", $body, $match)) {
273
        $result['rule_cat'] = 'unknown';
274
        $result['rule_no']  = '0232';
275
        $result['email']    = $match[1];
276
    } /*
277
   * rule: mailbox unknow;
278
   * sample:
279
   * <[email protected]>:^M
280
   * 111.111.111.11 does not like recipient.^M
281
   * Remote host said: 550 Invalid recipient: <[email protected]>^M
282 View Code Duplication
   */ elseif (preg_match("/Invalid.*(?:alias|account|recipient|address|email|mailbox|user).*<(\S+@\S+\w)>/i", $body, $match)) {
283
        $result['rule_cat'] = 'unknown';
284
        $result['rule_no']  = '0233';
285
        $result['email']    = $match[1];
286
    } /*
287
   * rule: mailbox unknow;
288
   * sample:
289
   * Sent >>> RCPT TO: <[email protected]>^M
290
   * Received <<< 550 [email protected]... No such user^M
291
   * ^M
292
   * Could not deliver mail to this user.^M
293
   * [email protected]^M
294
   * *****************     End of message     ***************^M
295 View Code Duplication
   */ elseif (preg_match("/\s(\S+@\S+\w).*No such.*(?:alias|account|recipient|address|email|mailbox|user)>/i", $body, $match)) {
296
        $result['rule_cat'] = 'unknown';
297
        $result['rule_no']  = '0234';
298
        $result['email']    = $match[1];
299
    } /*
300
   * rule: mailbox unknow;
301
   * sample:
302
   * <[email protected]>:^M
303
   * This address no longer accepts mail.
304 View Code Duplication
   */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*(?:alias|account|recipient|address|email|mailbox|user).*no.*accept.*mail>/i", $body, $match)) {
305
        $result['rule_cat'] = 'unknown';
306
        $result['rule_no']  = '0235';
307
        $result['email']    = $match[1];
308
    } /*
309
   * <[email protected]>:
310
   * 111.111.111.111 does not like recipient.
311
   * Remote host said: 550 User unknown
312 View Code Duplication
   */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*\n?.*user unknown/i", $body, $match)) {
313
        $result['rule_cat'] = 'unknown';
314
        $result['rule_no']  = '0236';
315
        $result['email']    = $match[1];
316
    } /*
317
   * rule: mailbox unknown;
318
   * sample:
319
   * [email protected]
320
   * no such address here
321 View Code Duplication
   */ elseif (preg_match("/(\S+@\S+\w).*\n?.*no such address here/i", $body, $match)) {
322
        $result['rule_cat'] = 'unknown';
323
        $result['rule_no']  = '0237';
324
        $result['email']    = $match[1];
325
    }
326
327
    //rules added by gofffy
328
    /*
329
    * rule: connection refused
330
    * <[email protected]>: connect to yourdomain.com[174.137.125.47]:25: Connection
331
    * refused
332 View Code Duplication
    */ elseif (preg_match("/<(\S+@\S+\w)>.*connect to.*Connection.*\n?.*refused/i", $body, $match)) {
333
        $result['rule_cat'] = 'unknown';
334
        $result['rule_no']  = '0300';
335
        $result['email']    = $match[1];
336
    } /*
337
  * rule: host or domain name not found
338
  * <[email protected]>: Host or domain name not found.
339 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*host or domain name not found/i", $body, $match)) {
340
        $result['rule_cat'] = 'unknown';
341
        $result['rule_no']  = '0301';
342
        $result['email']    = $match[1];
343
    } /*
344
  * rule: mailbox full
345
  * <[email protected]>:
346
  *.....said: 550 sorry this mailbox is over
347
  *  quota.....
348 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*mailbox is over.*\n?.*quota/i", $body, $match)) {
349
        $result['rule_cat'] = 'full';
350
        $result['rule_no']  = '0302';
351
        $result['email']    = $match[1];
352
    } /*
353
  * rule: user unknown
354
  * <[email protected]>: .... said: 550 5.1.1 User
355
  *  unknown (in reply to RCPT TO command).....
356 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*user.*\n?.*unknown/i", $body, $match)) {
357
        $result['rule_cat'] = 'unknown';
358
        $result['rule_no']  = '0303';
359
        $result['email']    = $match[1];
360
    } /*
361
  * rule: user unknown
362
  * <[email protected]>: .... said: 550 Requested
363
    action not taken: mailbox unavailable (in reply to RCPT TO command).....
364 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*\n?.*mailbox unavailable/i", $body, $match)) {
365
        $result['rule_cat'] = 'unknown';
366
        $result['rule_no']  = '0304';
367
        $result['email']    = $match[1];
368
    } /*
369
  * rule: user unknown
370
  * <[email protected]>: .... Command rejected (in reply to RCPT TO command).....
371 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*command rejected/i", $body, $match)) {
372
        $result['rule_cat'] = 'command_reject';
373
        $result['rule_no']  = '0305';
374
        $result['email']    = $match[1];
375
    } /*
376
  * rule: user unknown
377
  * <[email protected]>: .... said: 550 No
378
    such local user, unauthenticated relaying denied (in reply to RCPT TO
379
    command).....
380 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*550 no.*\n?.*such local user/i", $body, $match)) {
381
        $result['rule_cat'] = 'unknown';
382
        $result['rule_no']  = '0306';
383
        $result['email']    = $match[1];
384
    } /*
385
  * rule: user unknown
386
  * <[email protected]>: host ... said: 550 5.1.1
387
    unknown or illegal alias: ... (in reply to RCPT TO command).....
388 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*550.*\n?.*unknown or illegal alias/i", $body, $match)) {
389
        $result['rule_cat'] = 'unknown';
390
        $result['rule_no']  = '0307';
391
        $result['email']    = $match[1];
392
    } /*
393
  * rule: user unknown
394
  * <[email protected]>: Recipient address rejected: ...(in reply to RCPT
395
    TO command).....
396 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*recipient address rejected/i", $body, $match)) {
397
        $result['rule_cat'] = 'unknown';
398
        $result['rule_no']  = '0308';
399
        $result['email']    = $match[1];
400
    } /*
401
  * rule: user unknown
402
  * <[email protected]>: host ... said: 550 Recipient
403
    does not exist (in reply to RCPT TO command).....
404 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*550 recipient.*\n?.*does not exist/i", $body, $match)) {
405
        $result['rule_cat'] = 'unknown';
406
        $result['rule_no']  = '0309';
407
        $result['email']    = $match[1];
408
    } /*
409
  * rule: user unknown
410
  * <[email protected]>: host .... said: 554 mailbox not found.....
411 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*554 mailbox not found/i", $body, $match)) {
412
        $result['rule_cat'] = 'unknown';
413
        $result['rule_no']  = '0310';
414
        $result['email']    = $match[1];
415
    } /*
416
  * rule: too many recipients
417
  * <[email protected]>: .... said: 553 sorry, too many recipients.....
418 View Code Duplication
  */ elseif (preg_match("/<(\S+@\S+\w)>.*553 sorry, too many recipients/i", $body, $match)) {
419
        $result['rule_cat']    = 'other';
420
        $result['rule_no']     = '0311';
421
        $result['bounce_type'] = 'soft';
422
        $result['remove']      = 2;
423
        $result['email']       = $match[1];
424
    }
425
426
    global $rule_categories, $bmh_newline;
427
    if ('0000' == $result['rule_no']) {
428
        if ($debug_mode) {
429
            echo 'Body:' . $bmh_newline . $body . $bmh_newline;
430
            echo $bmh_newline;
431
        }
432 View Code Duplication
    } else {
433
        if (false === $result['bounce_type']) {
434
            $result['bounce_type'] = $rule_categories[$result['rule_cat']]['bounce_type'];
435
            $result['remove']      = $rule_categories[$result['rule_cat']]['remove'];
436
        }
437
    }
438
439
    return $result;
440
}
441
442
/**
443
 * Defined bounce parsing rules for standard DSN (Delivery Status Notification)
444
 *
445
 * @param string $dsn_msg    human-readable explanation
446
 * @param string $dsn_report delivery-status report
447
 * @param bool   $debug_mode show debug info. or not
448
 *
449
 * @return array $result an array include the following fields: 'email', 'bounce_type','remove','rule_no','rule_cat'
450
 *               if we could NOT detect the type of bounce, return rule_no = '0000'
451
 */
452
function bmhDSNRules($dsn_msg, $dsn_report, $debug_mode = false)
453
{
454
    // initialize the result array
455
    $result      = [
456
        'email'       => '',
457
        'bounce_type' => false,
458
        'remove'      => 0,
459
        'rule_cat'    => 'unrecognized',
460
        'rule_no'     => '0000',
461
    ];
462
    $action      = false;
463
    $status_code = false;
464
    $diag_code   = false;
465
466
    // ======= parse $dsn_report ======
467
    // get the recipient email
468
    if (preg_match('/Original-Recipient: rfc822;(.*)/i', $dsn_report, $match)) {
469
        $email_arr = imap_rfc822_parse_adrlist($match[1], 'default.domain.name');
470 View Code Duplication
        if (isset($email_arr[0]->host) && '.SYNTAX-ERROR.' !== $email_arr[0]->host
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
471
            && 'default.domain.name' !== $email_arr[0]->host) {
472
            $result['email'] = $email_arr[0]->mailbox . '@' . $email_arr[0]->host;
473
        }
474
    } else {
475
        if (preg_match('/Final-Recipient: rfc822;(.*)/i', $dsn_report, $match)) {
476
            $email_arr = imap_rfc822_parse_adrlist($match[1], 'default.domain.name');
477 View Code Duplication
            if (isset($email_arr[0]->host) && '.SYNTAX-ERROR.' !== $email_arr[0]->host
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
478
                && 'default.domain.name' !== $email_arr[0]->host) {
479
                $result['email'] = $email_arr[0]->mailbox . '@' . $email_arr[0]->host;
480
            }
481
        }
482
    }
483
484
    if (preg_match('/Action: (.+)/i', $dsn_report, $match)) {
485
        $action = mb_strtolower(trim($match[1]));
486
    }
487
488
    if (preg_match("/Status: ([0-9\.]+)/i", $dsn_report, $match)) {
489
        $status_code = $match[1];
490
    }
491
492
    // Could be multi-line , if the new line is beginning with SPACE or HTAB
493
    if (preg_match("/Diagnostic-Code:((?:[^\n]|\n[\t ])+)(?:\n[^\t ]|$)/is", $dsn_report, $match)) {
494
        $diag_code = $match[1];
495
    }
496
    // ======= rules ======
497
    if (empty($result['email'])) {
498
        /* email address is empty
499
         * rule: full
500
         * sample:   DSN Message only
501
         * User quota exceeded: SMTP <[email protected]>
502
         */
503 View Code Duplication
        if (preg_match("/quota exceed.*<(\S+@\S+\w)>/is", $dsn_msg, $match)) {
504
            $result['rule_cat'] = 'full';
505
            $result['rule_no']  = '0161';
506
            $result['email']    = $match[1];
507
        }
508
    } else {
509
        /* action could be one of them as RFC:1894
510
         * "failed" / "delayed" / "delivered" / "relayed" / "expanded"
511
         */
512
        switch ($action) {
513
            case 'failed':
514
                /* rule: full
515
                 * sample:
516
                 * Diagnostic-Code: X-Postfix; me.domain.com platform: said: 552 5.2.2 Over
517
                 *   quota (in reply to RCPT TO command)
518
                 */
519
                if (preg_match('/over.*quota/is', $diag_code)) {
520
                    $result['rule_cat'] = 'full';
521
                    $result['rule_no']  = '0105';
522
                } /* rule: full
523
         * sample:
524
         * Diagnostic-Code: SMTP; 552 Requested mailbox exceeds quota.
525
         */ elseif (preg_match('/exceed.*quota/is', $diag_code)) {
526
                    $result['rule_cat'] = 'full';
527
                    $result['rule_no']  = '0129';
528
                } /* rule: full
529
         * sample 1:
530
         * Diagnostic-Code: smtp;552 5.2.2 This message is larger than the current system limit or the recipient's mailbox is full. Create a shorter message body or remove attachments and try sending it again.
531
         * sample 2:
532
         * Diagnostic-Code: X-Postfix; host mta5.us4.domain.com.int[111.111.111.111] said:
533
         *   552 recipient storage full, try again later (in reply to RCPT TO command)
534
         * sample 3:
535
         * Diagnostic-Code: X-HERMES; host 127.0.0.1[127.0.0.1] said: 551 bounce as<the
536
         *   destination mailbox <[email protected]> is full> queue as
537
         *   [email protected] (in reply to end of
538
         *   DATA command)
539
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*full/is', $diag_code)) {
540
                    $result['rule_cat'] = 'full';
541
                    $result['rule_no']  = '0145';
542
                } /* rule: full
543
         * sample:
544
         * Diagnostic-Code: SMTP; 452 Insufficient system storage
545
         */ elseif (preg_match('/Insufficient system storage/is', $diag_code)) {
546
                    $result['rule_cat'] = 'full';
547
                    $result['rule_no']  = '0134';
548
                } /* rule: full
549
         * sample 1:
550
         * Diagnostic-Code: X-Postfix; cannot append message to destination file^M
551
         *   /var/mail/dale.me89g: error writing message: File too large^M
552
         * sample 2:
553
         * Diagnostic-Code: X-Postfix; cannot access mailbox /var/spool/mail/b8843022 for^M
554
         *   user xxxxx. error writing message: File too large
555
         */ elseif (preg_match('/File too large/is', $diag_code)) {
556
                    $result['rule_cat'] = 'full';
557
                    $result['rule_no']  = '0192';
558
                } /* rule: oversize
559
         * sample:
560
         * Diagnostic-Code: smtp;552 5.2.2 This message is larger than the current system limit or the recipient's mailbox is full. Create a shorter message body or remove attachments and try sending it again.
561
         */ elseif (preg_match('/larger than.*limit/is', $diag_code)) {
562
                    $result['rule_cat'] = 'oversize';
563
                    $result['rule_no']  = '0146';
564
                } /* rule: unknown
565
         * sample:
566
         * Diagnostic-Code: X-Notes; User xxxxx ([email protected]) not listed in public Name & Address Book
567
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user)(.*)not(.*)list/is', $diag_code)) {
568
                    $result['rule_cat'] = 'unknown';
569
                    $result['rule_no']  = '0103';
570
                } /* rule: unknown
571
         * sample:
572
         * Diagnostic-Code: smtp; 450 user path no exist
573
         */ elseif (preg_match('/user path no exist/is', $diag_code)) {
574
                    $result['rule_cat'] = 'unknown';
575
                    $result['rule_no']  = '0106';
576
                } /* rule: unknown
577
         * sample 1:
578
         * Diagnostic-Code: SMTP; 550 Relaying denied.
579
         * sample 2:
580
         * Diagnostic-Code: SMTP; 554 <[email protected]>: Relay access denied
581
         * sample 3:
582
         * Diagnostic-Code: SMTP; 550 relaying to <[email protected]> prohibited by administrator
583
         */ elseif (preg_match('/Relay.*(?:denied|prohibited)/is', $diag_code)) {
584
                    $result['rule_cat'] = 'unknown';
585
                    $result['rule_no']  = '0108';
586
                } /* rule: unknown
587
         * sample:
588
         * Diagnostic-Code: SMTP; 554 qq Sorry, no valid recipients (#5.1.3)
589
         */ elseif (preg_match('/no.*valid.*(?:alias|account|recipient|address|email|mailbox|user)/is', $diag_code)) {
590
                    $result['rule_cat'] = 'unknown';
591
                    $result['rule_no']  = '0185';
592
                } /* rule: unknown
593
         * sample 1:
594
         * Diagnostic-Code: SMTP; 550 «Dªk¦a§} - invalid address (#5.5.0)
595
         * sample 2:
596
         * Diagnostic-Code: SMTP; 550 Invalid recipient: <[email protected]>
597
         * sample 3:
598
         * Diagnostic-Code: SMTP; 550 <[email protected]>: Invalid User
599
         */ elseif (preg_match('/Invalid.*(?:alias|account|recipient|address|email|mailbox|user)/is', $diag_code)) {
600
                    $result['rule_cat'] = 'unknown';
601
                    $result['rule_no']  = '0111';
602
                } /* rule: unknown
603
         * sample:
604
         * Diagnostic-Code: SMTP; 554 delivery error: dd Sorry your message to [email protected] cannot be delivered. This account has been disabled or discontinued [#102]. - mta173.mail.tpe.domain.com
605
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*(?:disabled|discontinued)/is', $diag_code)) {
606
                    $result['rule_cat'] = 'unknown';
607
                    $result['rule_no']  = '0114';
608
                } /* rule: unknown
609
         * sample:
610
         * Diagnostic-Code: SMTP; 554 delivery error: dd This user doesn't have a domain.com account ([email protected]) [0] - mta134.mail.tpe.domain.com
611
         */ elseif (preg_match("/user doesn't have.*account/is", $diag_code)) {
612
                    $result['rule_cat'] = 'unknown';
613
                    $result['rule_no']  = '0127';
614
                } /* rule: unknown
615
         * sample:
616
         * Diagnostic-Code: SMTP; 550 5.1.1 unknown or illegal alias: [email protected]
617
         */ elseif (preg_match('/(?:unknown|illegal).*(?:alias|account|recipient|address|email|mailbox|user)/is', $diag_code)) {
618
                    $result['rule_cat'] = 'unknown';
619
                    $result['rule_no']  = '0128';
620
                } /* rule: unknown
621
         * sample 1:
622
         * Diagnostic-Code: SMTP; 450 mailbox unavailable.
623
         * sample 2:
624
         * Diagnostic-Code: SMTP; 550 5.7.1 Requested action not taken: mailbox not available
625
         */ elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*(?:un|not\s+)available/is", $diag_code)) {
626
                    $result['rule_cat'] = 'unknown';
627
                    $result['rule_no']  = '0122';
628
                } /* rule: unknown
629
         * sample:
630
         * Diagnostic-Code: SMTP; 553 sorry, no mailbox here by that name (#5.7.1)
631
         */ elseif (preg_match('/no (?:alias|account|recipient|address|email|mailbox|user)/is', $diag_code)) {
632
                    $result['rule_cat'] = 'unknown';
633
                    $result['rule_no']  = '0123';
634
                } /* rule: unknown
635
         * sample 1:
636
         * Diagnostic-Code: SMTP; 550 User ([email protected]) unknown.
637
         * sample 2:
638
         * Diagnostic-Code: SMTP; 553 5.3.0 <[email protected]>... Addressee unknown, relay=[111.111.111.000]
639
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*unknown/is', $diag_code)) {
640
                    $result['rule_cat'] = 'unknown';
641
                    $result['rule_no']  = '0125';
642
                } /* rule: unknown
643
         * sample 1:
644
         * Diagnostic-Code: SMTP; 550 user disabled
645
         * sample 2:
646
         * Diagnostic-Code: SMTP; 452 4.2.1 mailbox temporarily disabled: [email protected]
647
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*disabled/is', $diag_code)) {
648
                    $result['rule_cat'] = 'unknown';
649
                    $result['rule_no']  = '0133';
650
                } /* rule: unknown
651
         * sample:
652
         * Diagnostic-Code: SMTP; 550 <[email protected]>: Recipient address rejected: No such user ([email protected])
653
         */ elseif (preg_match('/No such (?:alias|account|recipient|address|email|mailbox|user)/is', $diag_code)) {
654
                    $result['rule_cat'] = 'unknown';
655
                    $result['rule_no']  = '0143';
656
                } /* rule: unknown
657
         * sample 1:
658
         * Diagnostic-Code: SMTP; 550 MAILBOX NOT FOUND
659
         * sample 2:
660
         * Diagnostic-Code: SMTP; 550 Mailbox ( [email protected] ) not found or inactivated
661
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*NOT FOUND/is', $diag_code)) {
662
                    $result['rule_cat'] = 'unknown';
663
                    $result['rule_no']  = '0136';
664
                } /* rule: unknown
665
         * sample:
666
         * Diagnostic-Code: X-Postfix; host m2w-in1.domain.com[111.111.111.000] said: 551
667
         * <[email protected]> is a deactivated mailbox (in reply to RCPT TO
668
         * command)
669
         */ elseif (preg_match('/deactivated (?:alias|account|recipient|address|email|mailbox|user)/is', $diag_code)) {
670
                    $result['rule_cat'] = 'unknown';
671
                    $result['rule_no']  = '0138';
672
                } /* rule: unknown
673
         * sample:
674
         * Diagnostic-Code: SMTP; 550 <[email protected]> recipient rejected
675
         * ...
676
         * <<< 550 <[email protected]> recipient rejected
677
         * 550 5.1.1 [email protected]... User unknown
678
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*reject/is', $diag_code)) {
679
                    $result['rule_cat'] = 'unknown';
680
                    $result['rule_no']  = '0148';
681
                } /* rule: unknown
682
         * sample:
683
         * Diagnostic-Code: smtp; 5.x.0 - Message bounced by administrator  (delivery attempts: 0)
684
         */ elseif (preg_match('/bounce.*administrator/is', $diag_code)) {
685
                    $result['rule_cat'] = 'unknown';
686
                    $result['rule_no']  = '0151';
687
                } /* rule: unknown
688
         * sample:
689
         * Diagnostic-Code: SMTP; 550 <maxqin> is now disabled with MTA service.
690
         */ elseif (preg_match('/<.*>.*disabled/is', $diag_code)) {
691
                    $result['rule_cat'] = 'unknown';
692
                    $result['rule_no']  = '0152';
693
                } /* rule: unknown
694
         * sample:
695
         * Diagnostic-Code: SMTP; 551 not our customer
696
         */ elseif (preg_match('/not our customer/is', $diag_code)) {
697
                    $result['rule_cat'] = 'unknown';
698
                    $result['rule_no']  = '0154';
699
                } /* rule: unknown
700
         * sample:
701
         * Diagnostic-Code: smtp; 5.1.0 - Unknown address error 540-'Error: Wrong recipients' (delivery attempts: 0)
702
         */ elseif (preg_match('/Wrong (?:alias|account|recipient|address|email|mailbox|user)/is', $diag_code)) {
703
                    $result['rule_cat'] = 'unknown';
704
                    $result['rule_no']  = '0159';
705
                } /* rule: unknown
706
         * sample:
707
         * Diagnostic-Code: smtp; 5.1.0 - Unknown address error 540-'Error: Wrong recipients' (delivery attempts: 0)
708
         * sample 2:
709
         * Diagnostic-Code: SMTP; 501 #5.1.1 bad address [email protected]
710
         */ elseif (preg_match('/(?:unknown|bad).*(?:alias|account|recipient|address|email|mailbox|user)/is', $diag_code)) {
711
                    $result['rule_cat'] = 'unknown';
712
                    $result['rule_no']  = '0160';
713
                } /* rule: unknown
714
         * sample:
715
         * Diagnostic-Code: SMTP; 550 Command RCPT User <[email protected]> not OK
716
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*not OK/is', $diag_code)) {
717
                    $result['rule_cat'] = 'unknown';
718
                    $result['rule_no']  = '0186';
719
                } /* rule: unknown
720
         * sample:
721
         * Diagnostic-Code: SMTP; 550 5.7.1 Access-Denied-XM.SSR-001
722
         */ elseif (preg_match('/Access.*Denied/is', $diag_code)) {
723
                    $result['rule_cat'] = 'unknown';
724
                    $result['rule_no']  = '0189';
725
                } /* rule: unknown
726
         * sample:
727
         * Diagnostic-Code: SMTP; 550 5.1.1 <[email protected]>... email address lookup in domain map failed^M
728
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*lookup.*fail/is', $diag_code)) {
729
                    $result['rule_cat'] = 'unknown';
730
                    $result['rule_no']  = '0195';
731
                } /* rule: unknown
732
         * sample:
733
         * Diagnostic-Code: SMTP; 550 User not a member of domain: <[email protected]>^M
734
         */ elseif (preg_match('/(?:recipient|address|email|mailbox|user).*not.*member of domain/is', $diag_code)) {
735
                    $result['rule_cat'] = 'unknown';
736
                    $result['rule_no']  = '0198';
737
                } /* rule: unknown
738
         * sample:
739
         * Diagnostic-Code: SMTP; 550-"The recipient cannot be verified.  Please check all recipients of this^M
740
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*cannot be verified/is', $diag_code)) {
741
                    $result['rule_cat'] = 'unknown';
742
                    $result['rule_no']  = '0202';
743
                } /* rule: unknown
744
         * sample:
745
         * Diagnostic-Code: SMTP; 550 Unable to relay for [email protected]
746
         */ elseif (preg_match('/Unable to relay/is', $diag_code)) {
747
                    $result['rule_cat'] = 'unknown';
748
                    $result['rule_no']  = '0203';
749
                } /* rule: unknown
750
         * sample 1:
751
         * Diagnostic-Code: SMTP; 550 [email protected]:user not exist
752
         * sample 2:
753
         * Diagnostic-Code: SMTP; 550 sorry, that recipient doesn't exist (#5.7.1)
754
         */ elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*(?:n't|not) exist/is", $diag_code)) {
755
                    $result['rule_cat'] = 'unknown';
756
                    $result['rule_no']  = '0205';
757
                } /* rule: unknown
758
         * sample:
759
         * Diagnostic-Code: SMTP; 550-I'm sorry but [email protected] does not have an account here. I will not
760
         */ elseif (preg_match('/not have an account/is', $diag_code)) {
761
                    $result['rule_cat'] = 'unknown';
762
                    $result['rule_no']  = '0207';
763
                } /* rule: unknown
764
         * sample:
765
         * Diagnostic-Code: SMTP; 550 This account is not [email protected]
766
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*is not allowed/is', $diag_code)) {
767
                    $result['rule_cat'] = 'unknown';
768
                    $result['rule_no']  = '0220';
769
                } /* rule: inactive
770
         * sample:
771
         * Diagnostic-Code: SMTP; 550 <[email protected]>: inactive user
772
         */ elseif (preg_match('/inactive.*(?:alias|account|recipient|address|email|mailbox|user)/is', $diag_code)) {
773
                    $result['rule_cat'] = 'inactive';
774
                    $result['rule_no']  = '0135';
775
                } /* rule: inactive
776
         * sample:
777
         * Diagnostic-Code: SMTP; 550 [email protected] Account Inactive
778
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*Inactive/is', $diag_code)) {
779
                    $result['rule_cat'] = 'inactive';
780
                    $result['rule_no']  = '0155';
781
                } /* rule: inactive
782
         * sample:
783
         * Diagnostic-Code: SMTP; 550 <[email protected]>: Recipient address rejected: Account closed due to inactivity. No forwarding information is available.
784
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user) closed due to inactivity/is', $diag_code)) {
785
                    $result['rule_cat'] = 'inactive';
786
                    $result['rule_no']  = '0170';
787
                } /* rule: inactive
788
         * sample:
789
         * Diagnostic-Code: SMTP; 550 <[email protected]>... User account not activated
790
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user) not activated/is', $diag_code)) {
791
                    $result['rule_cat'] = 'inactive';
792
                    $result['rule_no']  = '0177';
793
                } /* rule: inactive
794
         * sample 1:
795
         * Diagnostic-Code: SMTP; 550 User suspended
796
         * sample 2:
797
         * Diagnostic-Code: SMTP; 550 account expired
798
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*(?:suspend|expire)/is', $diag_code)) {
799
                    $result['rule_cat'] = 'inactive';
800
                    $result['rule_no']  = '0183';
801
                } /* rule: inactive
802
         * sample:
803
         * Diagnostic-Code: SMTP; 553 5.3.0 <[email protected]>... Recipient address no longer exists
804
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*no longer exist/is', $diag_code)) {
805
                    $result['rule_cat'] = 'inactive';
806
                    $result['rule_no']  = '0184';
807
                } /* rule: inactive
808
         * sample:
809
         * Diagnostic-Code: SMTP; 553 VS10-RT Possible forgery or deactivated due to abuse (#5.1.1) 111.111.111.211^M
810
         */ elseif (preg_match('/(?:forgery|abuse)/is', $diag_code)) {
811
                    $result['rule_cat'] = 'inactive';
812
                    $result['rule_no']  = '0196';
813
                } /* rule: inactive
814
         * sample:
815
         * Diagnostic-Code: SMTP; 553 mailbox [email protected] is restricted
816
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*restrict/is', $diag_code)) {
817
                    $result['rule_cat'] = 'inactive';
818
                    $result['rule_no']  = '0209';
819
                } /* rule: inactive
820
         * sample:
821
         * Diagnostic-Code: SMTP; 550 <[email protected]>: User status is locked.
822
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*locked/is', $diag_code)) {
823
                    $result['rule_cat'] = 'inactive';
824
                    $result['rule_no']  = '0228';
825
                } /* rule: user_reject
826
         * sample:
827
         * Diagnostic-Code: SMTP; 553 User refused to receive this mail.
828
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user) refused/is', $diag_code)) {
829
                    $result['rule_cat'] = 'user_reject';
830
                    $result['rule_no']  = '0156';
831
                } /* rule: user_reject
832
         * sample:
833
         * Diagnostic-Code: SMTP; 501 [email protected] Sender email is not in my domain
834
         */ elseif (preg_match('/sender.*not/is', $diag_code)) {
835
                    $result['rule_cat'] = 'user_reject';
836
                    $result['rule_no']  = '0206';
837
                } /* rule: command_reject
838
         * sample:
839
         * Diagnostic-Code: SMTP; 554 Message refused
840
         */ elseif (preg_match('/Message refused/is', $diag_code)) {
841
                    $result['rule_cat'] = 'command_reject';
842
                    $result['rule_no']  = '0175';
843
                } /* rule: command_reject
844
         * sample:
845
         * Diagnostic-Code: SMTP; 550 5.0.0 <[email protected]>... No permit
846
         */ elseif (preg_match('/No permit/is', $diag_code)) {
847
                    $result['rule_cat'] = 'command_reject';
848
                    $result['rule_no']  = '0190';
849
                } /* rule: command_reject
850
         * sample:
851
         * Diagnostic-Code: SMTP; 553 sorry, that domain isn't in my list of allowed rcpthosts (#5.5.3 - chkuser)
852
         */ elseif (preg_match("/domain isn't in.*allowed rcpthost/is", $diag_code)) {
853
                    $result['rule_cat'] = 'command_reject';
854
                    $result['rule_no']  = '0191';
855
                } /* rule: command_reject
856
         * sample:
857
         * Diagnostic-Code: SMTP; 553 AUTH FAILED - [email protected]^M
858
         */ elseif (preg_match('/AUTH FAILED/is', $diag_code)) {
859
                    $result['rule_cat'] = 'command_reject';
860
                    $result['rule_no']  = '0197';
861
                } /* rule: command_reject
862
         * sample 1:
863
         * Diagnostic-Code: SMTP; 550 relay not permitted^M
864
         * sample 2:
865
         * Diagnostic-Code: SMTP; 530 5.7.1 Relaying not allowed: [email protected]
866
         */ elseif (preg_match('/relay.*not.*(?:permit|allow)/is', $diag_code)) {
867
                    $result['rule_cat'] = 'command_reject';
868
                    $result['rule_no']  = '0201';
869
                } /* rule: command_reject
870
         * sample:
871
         *
872
         * Diagnostic-Code: SMTP; 550 not local host domain.com, not a gateway
873
         */ elseif (preg_match('/not local host/is', $diag_code)) {
874
                    $result['rule_cat'] = 'command_reject';
875
                    $result['rule_no']  = '0204';
876
                } /* rule: command_reject
877
         * sample:
878
         * Diagnostic-Code: SMTP; 500 Unauthorized relay msg rejected
879
         */ elseif (preg_match('/Unauthorized relay/is', $diag_code)) {
880
                    $result['rule_cat'] = 'command_reject';
881
                    $result['rule_no']  = '0215';
882
                } /* rule: command_reject
883
         * sample:
884
         * Diagnostic-Code: SMTP; 554 Transaction failed
885
         */ elseif (preg_match('/Transaction.*fail/is', $diag_code)) {
886
                    $result['rule_cat'] = 'command_reject';
887
                    $result['rule_no']  = '0221';
888
                } /* rule: command_reject
889
         * sample:
890
         * Diagnostic-Code: smtp;554 5.5.2 Invalid data in message
891
         */ elseif (preg_match('/Invalid data/is', $diag_code)) {
892
                    $result['rule_cat'] = 'command_reject';
893
                    $result['rule_no']  = '0223';
894
                } /* rule: command_reject
895
         * sample:
896
         * Diagnostic-Code: SMTP; 550 Local user only or Authentication mechanism
897
         */ elseif (preg_match('/Local user only/is', $diag_code)) {
898
                    $result['rule_cat'] = 'command_reject';
899
                    $result['rule_no']  = '0224';
900
                } /* rule: command_reject
901
         * sample:
902
         * Diagnostic-Code: SMTP; 550-ds176.domain.com [111.111.111.211] is currently not permitted to
903
         * relay through this server. Perhaps you have not logged into the pop/imap
904
         * server in the last 30 minutes or do not have SMTP Authentication turned on
905
         * in your email client.
906
         */ elseif (preg_match('/not.*permit.*to/is', $diag_code)) {
907
                    $result['rule_cat'] = 'command_reject';
908
                    $result['rule_no']  = '0225';
909
                } /* rule: content_reject
910
         * sample:
911
         * Diagnostic-Code: SMTP; 550 Content reject. FAAAANsG60M9BmDT.1
912
         */ elseif (preg_match('/Content reject/is', $diag_code)) {
913
                    $result['rule_cat'] = 'content_reject';
914
                    $result['rule_no']  = '0165';
915
                } /* rule: content_reject
916
         * sample:
917
         * Diagnostic-Code: SMTP; 552 MessageWall: MIME/REJECT: Invalid structure
918
         */ elseif (preg_match("/MIME\/REJECT/is", $diag_code)) {
919
                    $result['rule_cat'] = 'content_reject';
920
                    $result['rule_no']  = '0212';
921
                } /* rule: content_reject
922
         * sample:
923
         * Diagnostic-Code: smtp; 554 5.6.0 Message with invalid header rejected, id=13462-01 - MIME error: error: UnexpectedBound: part didn't end with expected boundary [in multipart message]; EOSToken: EOF; EOSType: EOF
924
         */ elseif (preg_match('/MIME error/is', $diag_code)) {
925
                    $result['rule_cat'] = 'content_reject';
926
                    $result['rule_no']  = '0217';
927
                } /* rule: content_reject
928
         * sample:
929
         * Diagnostic-Code: SMTP; 553 Mail data refused by AISP, rule [169648].
930
         */ elseif (preg_match('/Mail data refused.*AISP/is', $diag_code)) {
931
                    $result['rule_cat'] = 'content_reject';
932
                    $result['rule_no']  = '0218';
933
                } /* rule: dns_unknown
934
         * sample:
935
         * Diagnostic-Code: SMTP; 550 Host unknown
936
         */ elseif (preg_match('/Host unknown/is', $diag_code)) {
937
                    $result['rule_cat'] = 'dns_unknown';
938
                    $result['rule_no']  = '0130';
939
                } /* rule: dns_unknown
940
         * sample:
941
         * Diagnostic-Code: SMTP; 553 Specified domain is not allowed.
942
         */ elseif (preg_match('/Specified domain.*not.*allow/is', $diag_code)) {
943
                    $result['rule_cat'] = 'dns_unknown';
944
                    $result['rule_no']  = '0180';
945
                } /* rule: dns_unknown
946
         * sample:
947
         * Diagnostic-Code: X-Postfix; delivery temporarily suspended: connect to
948
         * 111.111.11.112[111.111.11.112]: No route to host
949
         */ elseif (preg_match('/No route to host/is', $diag_code)) {
950
                    $result['rule_cat'] = 'dns_unknown';
951
                    $result['rule_no']  = '0188';
952
                } /* rule: dns_unknown
953
         * sample:
954
         * Diagnostic-Code: SMTP; 550 unrouteable address
955
         */ elseif (preg_match('/unrouteable address/is', $diag_code)) {
956
                    $result['rule_cat'] = 'dns_unknown';
957
                    $result['rule_no']  = '0208';
958
                } /* rule: defer
959
         * sample:
960
         * Diagnostic-Code: SMTP; 451 System(u) busy, try again later.
961
         */ elseif (preg_match('/System.*busy/is', $diag_code)) {
962
                    $result['rule_cat'] = 'defer';
963
                    $result['rule_no']  = '0112';
964
                } /* rule: defer
965
         * sample:
966
         * Diagnostic-Code: SMTP; 451 mta172.mail.tpe.domain.com Resources temporarily unavailable. Please try again later.  [#4.16.4:70].
967
         */ elseif (preg_match('/Resources temporarily unavailable/is', $diag_code)) {
968
                    $result['rule_cat'] = 'defer';
969
                    $result['rule_no']  = '0116';
970
                } /* rule: antispam, deny ip
971
         * sample:
972
         * Diagnostic-Code: SMTP; 554 sender is rejected: 0,mx20,wKjR5bDrnoM2yNtEZVAkBg==.32467S2
973
         */ elseif (preg_match('/sender is rejected/is', $diag_code)) {
974
                    $result['rule_cat'] = 'antispam';
975
                    $result['rule_no']  = '0101';
976
                } /* rule: antispam, deny ip
977
         * sample:
978
         * Diagnostic-Code: SMTP; 554 <unknown[111.111.111.000]>: Client host rejected: Access denied
979
         */ elseif (preg_match('/Client host rejected/is', $diag_code)) {
980
                    $result['rule_cat'] = 'antispam';
981
                    $result['rule_no']  = '0102';
982
                } /* rule: antispam, mismatch ip
983
         * sample:
984
         * Diagnostic-Code: SMTP; 554 Connection refused(mx). MAIL FROM [[email protected]] mismatches client IP [111.111.111.000].
985
         */ elseif (preg_match('/MAIL FROM(.*)mismatches client IP/is', $diag_code)) {
986
                    $result['rule_cat'] = 'antispam';
987
                    $result['rule_no']  = '0104';
988
                } /* rule: antispam, deny ip
989
         * sample:
990
         * Diagnostic-Code: SMTP; 554 Please visit http:// antispam.domain.com/denyip.php?IP=111.111.111.000 (#5.7.1)
991
         */ elseif (preg_match('/denyip/is', $diag_code)) {
992
                    $result['rule_cat'] = 'antispam';
993
                    $result['rule_no']  = '0144';
994
                } /* rule: antispam, deny ip
995
         * sample:
996
         * Diagnostic-Code: SMTP; 554 Service unavailable; Client host [111.111.111.211] blocked using dynablock.domain.com; Your message could not be delivered due to complaints we received regarding the IP address you're using or your ISP. See http:// blackholes.domain.com/ Error: WS-02^M
997
         */ elseif (preg_match('/client host.*blocked/is', $diag_code)) {
998
                    $result['rule_cat'] = 'antispam';
999
                    $result['rule_no']  = '0201';
1000
                } /* rule: antispam, reject
1001
         * sample:
1002
         * Diagnostic-Code: SMTP; 550 Requested action not taken: mail IsCNAPF76kMDARUY.56621S2 is rejected,mx3,BM
1003
         */ elseif (preg_match('/mail.*reject/is', $diag_code)) {
1004
                    $result['rule_cat'] = 'antispam';
1005
                    $result['rule_no']  = '0147';
1006
                } /* rule: antispam
1007
         * sample:
1008
         * Diagnostic-Code: SMTP; 552 sorry, the spam message is detected (#5.6.0)
1009
         */ elseif (preg_match('/spam.*detect/is', $diag_code)) {
1010
                    $result['rule_cat'] = 'antispam';
1011
                    $result['rule_no']  = '0162';
1012
                } /* rule: antispam
1013
         * sample:
1014
         * Diagnostic-Code: SMTP; 554 5.7.1 Rejected as Spam see: http:// rejected.domain.com/help/spam/rejected.html
1015
         */ elseif (preg_match('/reject.*spam/is', $diag_code)) {
1016
                    $result['rule_cat'] = 'antispam';
1017
                    $result['rule_no']  = '0216';
1018
                } /* rule: antispam
1019
         * sample:
1020
         * Diagnostic-Code: SMTP; 553 5.7.1 <[email protected]>... SpamTrap=reject mode, dsn=5.7.1, Message blocked by BOX Solutions (www.domain.com) SpamTrap Technology, please contact the domain.com site manager for help: (ctlusr8012).^M
1021
         */ elseif (preg_match('/SpamTrap/is', $diag_code)) {
1022
                    $result['rule_cat'] = 'antispam';
1023
                    $result['rule_no']  = '0200';
1024
                } /* rule: antispam, mailfrom mismatch
1025
         * sample:
1026
         * Diagnostic-Code: SMTP; 550 Verify mailfrom failed,blocked
1027
         */ elseif (preg_match('/Verify mailfrom failed/is', $diag_code)) {
1028
                    $result['rule_cat'] = 'antispam';
1029
                    $result['rule_no']  = '0210';
1030
                } /* rule: antispam, mailfrom mismatch
1031
         * sample:
1032
         * Diagnostic-Code: SMTP; 550 Error: MAIL FROM is mismatched with message header from address!
1033
         */ elseif (preg_match('/MAIL.*FROM.*mismatch/is', $diag_code)) {
1034
                    $result['rule_cat'] = 'antispam';
1035
                    $result['rule_no']  = '0226';
1036
                } /* rule: antispam
1037
         * sample:
1038
         * Diagnostic-Code: SMTP; 554 5.7.1 Message scored too high on spam scale.  For help, please quote incident ID 22492290.
1039
         */ elseif (preg_match('/spam scale/is', $diag_code)) {
1040
                    $result['rule_cat'] = 'antispam';
1041
                    $result['rule_no']  = '0211';
1042
                } /* rule: antispam
1043
         * sample:
1044
         * Diagnostic-Code: SMTP; 554 5.7.1 reject: Client host bypassing service provider's mail relay: ds176.domain.com
1045
         8?
1046
        elseif (preg_match ("/Client host bypass/is",$diag_code)) {
1047
          $result['rule_cat']    = 'antispam';
1048
          $result['rule_no']     = '0229';
1049
        }
1050
        /* rule: antispam
1051
         * sample:
1052
         * Diagnostic-Code: SMTP; 550 sorry, it seems as a junk mail
1053
         */ elseif (preg_match('/junk mail/is', $diag_code)) {
1054
                    $result['rule_cat'] = 'antispam';
1055
                    $result['rule_no']  = '0230';
1056
                } /* rule: antispam
1057
         * sample:
1058
         * Diagnostic-Code: SMTP; 553-Message filtered. Please see the FAQs section on spam
1059
         */ elseif (preg_match('/message filtered/is', $diag_code)) {
1060
                    $result['rule_cat'] = 'antispam';
1061
                    $result['rule_no']  = '0227';
1062
                } /* rule: antispam, subject filter
1063
         * sample:
1064
         * Diagnostic-Code: SMTP; 554 5.7.1 The message from (<[email protected]>) with the subject of ( *(ca2639) 7|-{%2E* : {2"(%EJ;y} (SBI$#$@<K*:7s1!=l~) matches a profile the Internet community may consider spam. Please revise your message before resending.
1065
         */ elseif (preg_match('/subject.*consider.*spam/is', $diag_code)) {
1066
                    $result['rule_cat'] = 'antispam';
1067
                    $result['rule_no']  = '0222';
1068
                } /* rule: internal_error
1069
         * sample:
1070
         * Diagnostic-Code: SMTP; 451 Temporary local problem - please try later
1071
         */ elseif (preg_match('/Temporary local problem/is', $diag_code)) {
1072
                    $result['rule_cat'] = 'internal_error';
1073
                    $result['rule_no']  = '0142';
1074
                } /* rule: internal_error
1075
         * sample:
1076
         * Diagnostic-Code: SMTP; 553 5.3.5 system config error
1077
         */ elseif (preg_match('/system config error/is', $diag_code)) {
1078
                    $result['rule_cat'] = 'internal_error';
1079
                    $result['rule_no']  = '0153';
1080
                } /* rule: delayed
1081
         * sample:
1082
         * Diagnostic-Code: X-Postfix; delivery temporarily suspended: conversation with^M
1083
         * 111.111.111.11[111.111.111.11] timed out while sending end of data -- message may be^M
1084
         * sent more than once
1085
         */ elseif (preg_match('/delivery.*suspend/is', $diag_code)) {
1086
                    $result['rule_cat'] = 'delayed';
1087
                    $result['rule_no']  = '0213';
1088
                }
1089
1090
                // =========== rules based on the dsn_msg ===============
1091
                /* rule: unknown
1092
                 * sample:
1093
                 * ----- The following addresses had permanent fatal errors -----
1094
                 * <[email protected]>
1095
                 * ----- Transcript of session follows -----
1096
                 * ... while talking to mta1.domain.com.:
1097
                 * >>> DATA
1098
                 * <<< 503 All recipients are invalid
1099
                 * 554 5.0.0 Service unavailable
1100
                 */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user)(.*)invalid/i', $dsn_msg)) {
1101
                    $result['rule_cat'] = 'unknown';
1102
                    $result['rule_no']  = '0107';
1103
                } /* rule: unknown
1104
         * sample:
1105
         * ----- Transcript of session follows -----
1106
         * [email protected]... Deferred: No such file or directory
1107
         */ elseif (preg_match('/Deferred.*No such.*(?:file|directory)/i', $dsn_msg)) {
1108
                    $result['rule_cat'] = 'unknown';
1109
                    $result['rule_no']  = '0141';
1110
                } /* rule: unknown
1111
         * sample:
1112
         * Failed to deliver to '<[email protected]>'^M
1113
         * LOCAL module(account xxxx) reports:^M
1114
         * mail receiving disabled^M
1115
         */ elseif (preg_match('/mail receiving disabled/i', $dsn_msg)) {
1116
                    $result['rule_cat'] = 'unknown';
1117
                    $result['rule_no']  = '0194';
1118
                } /* rule: unknown
1119
         * sample:
1120
         * - These recipients of your message have been processed by the mail server:^M
1121
         * [email protected]; Failed; 5.1.1 (bad destination mailbox address)
1122
         */ elseif (preg_match('/bad.*(?:alias|account|recipient|address|email|mailbox|user)/i', $dsn_msg)) {
1123
                    $result['rule_cat'] = 'unknown';
1124
                    $result['rule_no']  = '227';
1125
                } /* rule: full
1126
         * sample 1:
1127
         * This Message was undeliverable due to the following reason:
1128
         * The user(s) account is temporarily over quota.
1129
         * <[email protected]>
1130
         * sample 2:
1131
         *  Recipient address: [email protected]
1132
         *  Reason: Over quota
1133
         */ elseif (preg_match('/over.*quota/i', $dsn_msg)) {
1134
                    $result['rule_cat'] = 'full';
1135
                    $result['rule_no']  = '0131';
1136
                } /* rule: full
1137
         * sample:
1138
         * Sorry the recipient quota limit is exceeded.
1139
         * This message is returned as an error.
1140
         */ elseif (preg_match('/quota.*exceeded/i', $dsn_msg)) {
1141
                    $result['rule_cat'] = 'full';
1142
                    $result['rule_no']  = '0150';
1143
                } /* rule: full
1144
         * sample:
1145
         * The user to whom this message was addressed has exceeded the allowed mailbox
1146
         * quota. Please resend the message at a later time.
1147
         */ elseif (preg_match("/exceed.*\n?.*quota/i", $dsn_msg)) {
1148
                    $result['rule_cat'] = 'full';
1149
                    $result['rule_no']  = '0187';
1150
                } /* rule: full
1151
         * sample 1:
1152
         * Failed to deliver to '<[email protected]>'
1153
         * LOCAL module(account xxxxxx) reports:
1154
         * account is full (quota exceeded)
1155
         * sample 2:
1156
         * Error in fabiomod_sql_glob_init: no data source specified - database access disabled
1157
         * [Fri Feb 17 23:29:38 PST 2006] full error for caltsmy:
1158
         * that member's mailbox is full
1159
         * 550 5.0.0 <[email protected]>... Can't create output
1160
         */ elseif (preg_match('/(?:alias|account|recipient|address|email|mailbox|user).*full/i', $dsn_msg)) {
1161
                    $result['rule_cat'] = 'full';
1162
                    $result['rule_no']  = '0132';
1163
                } /* rule: full
1164
         * sample:
1165
         * gaosong "(0), ErrMsg=Mailbox space not enough (space limit is 10240KB)
1166
         */ elseif (preg_match('/space.*not.*enough/i', $dsn_msg)) {
1167
                    $result['rule_cat'] = 'full';
1168
                    $result['rule_no']  = '0219';
1169
                } /* rule: defer
1170
         * sample 1:
1171
         * ----- Transcript of session follows -----
1172
         * [email protected]... Deferred: Connection refused by nomail.tpe.domain.com.
1173
         * Message could not be delivered for 5 days
1174
         * Message will be deleted from queue
1175
         * sample 2:
1176
         * 451 4.4.1 reply: read error from www.domain.com.
1177
         * [email protected]... Deferred: Connection reset by www.domain.com.
1178
         */ elseif (preg_match('/Deferred.*Connection (?:refused|reset)/i', $dsn_msg)) {
1179
                    $result['rule_cat'] = 'defer';
1180
                    $result['rule_no']  = '0115';
1181
                } /* rule: dns_unknown
1182
         * sample:
1183
         * ----- The following addresses had permanent fatal errors -----
1184
         * Tan XXXX SSSS <[email protected]>
1185
         * ----- Transcript of session follows -----
1186
         * 553 5.1.2 XXXX SSSS <[email protected]>... Invalid host name
1187
         */ elseif (preg_match('/Invalid host name/i', $dsn_msg)) {
1188
                    $result['rule_cat'] = 'dns_unknown';
1189
                    $result['rule_no']  = '0109';
1190
                } /* rule: dns_unknown
1191
         * sample:
1192
         * ----- Transcript of session follows -----
1193
         * [email protected]... Deferred: mail.domain.com.: No route to host
1194
         */ elseif (preg_match('/Deferred.*No route to host/i', $dsn_msg)) {
1195
                    $result['rule_cat'] = 'dns_unknown';
1196
                    $result['rule_no']  = '0109';
1197
                } /* rule: dns_unknown
1198
         * sample:
1199
         * ----- Transcript of session follows -----
1200
         * 550 5.1.2 [email protected]... Host unknown (Name server: .: no data known)
1201
         */ elseif (preg_match('/Host unknown/i', $dsn_msg)) {
1202
                    $result['rule_cat'] = 'dns_unknown';
1203
                    $result['rule_no']  = '0140';
1204
                } /* rule: dns_unknown
1205
         * sample:
1206
         * ----- Transcript of session follows -----
1207
         * 451 HOTMAIL.com.tw: Name server timeout
1208
         * Message could not be delivered for 5 days
1209
         * Message will be deleted from queue
1210
         */ elseif (preg_match('/Name server timeout/i', $dsn_msg)) {
1211
                    $result['rule_cat'] = 'dns_unknown';
1212
                    $result['rule_no']  = '0118';
1213
                } /* rule: dns_unknown
1214
         * sample:
1215
         * ----- Transcript of session follows -----
1216
         * [email protected]... Deferred: Connection timed out with hkfight.com.
1217
         * Message could not be delivered for 5 days
1218
         * Message will be deleted from queue
1219
         */ elseif (preg_match('/Deferred.*Connection.*tim(?:e|ed).*out/i', $dsn_msg)) {
1220
                    $result['rule_cat'] = 'dns_unknown';
1221
                    $result['rule_no']  = '0119';
1222
                } /* rule: dns_unknown
1223
         * sample:
1224
         * ----- Transcript of session follows -----
1225
         * [email protected]... Deferred: Name server: domain.com.: host name lookup failure
1226
         */ elseif (preg_match('/Deferred.*host name lookup failure/i', $dsn_msg)) {
1227
                    $result['rule_cat'] = 'dns_unknown';
1228
                    $result['rule_no']  = '0121';
1229
                } /* rule: dns_loop
1230
         * sample:
1231
         * ----- Transcript of session follows -----^M
1232
         * 554 5.0.0 MX list for znet.ws. points back to mail01.domain.com^M
1233
         * 554 5.3.5 Local configuration error^M
1234
         */ elseif (preg_match('/MX list.*point.*back/i', $dsn_msg)) {
1235
                    $result['rule_cat'] = 'dns_loop';
1236
                    $result['rule_no']  = '0199';
1237
                } /* rule: internal_error
1238
         * sample:
1239
         * ----- Transcript of session follows -----
1240
         * 451 4.0.0 I/O error
1241
         */ elseif (preg_match("/I\/O error/i", $dsn_msg)) {
1242
                    $result['rule_cat'] = 'internal_error';
1243
                    $result['rule_no']  = '0120';
1244
                } /* rule: internal_error
1245
         * sample:
1246
         * Failed to deliver to '[email protected]'^M
1247
         * SMTP module(domain domain.com) reports:^M
1248
         * connection with mx1.mail.domain.com is broken^M
1249
         */ elseif (preg_match('/connection.*broken/i', $dsn_msg)) {
1250
                    $result['rule_cat'] = 'internal_error';
1251
                    $result['rule_no']  = '0231';
1252
                } /* rule: other
1253
         * sample:
1254
         * Delivery to the following recipients failed.
1255
         * [email protected]
1256
         */ elseif (preg_match("/Delivery to the following recipients failed.*\n.*\n.*" . $result['email'] . '/i', $dsn_msg)) {
1257
                    $result['rule_cat'] = 'other';
1258
                    $result['rule_no']  = '0176';
1259
                }
1260
1261
                // Followings are wind-up rule: must be the last one
1262
                //   many other rules msg end up with "550 5.1.1 ... User unknown"
1263
                //   many other rules msg end up with "554 5.0.0 Service unavailable"
1264
1265
                /* rule: unknown
1266
                 * sample 1:
1267
                 * ----- The following addresses had permanent fatal errors -----^M
1268
                 * <[email protected]>^M
1269
                 * (reason: User unknown)^M
1270
                 * sample 2:
1271
                 * 550 5.1.1 [email protected]... User unknown^M
1272
                 */ elseif (preg_match('/User unknown/i', $dsn_msg)) {
1273
                    $result['rule_cat'] = 'unknown';
1274
                    $result['rule_no']  = '0193';
1275
                } /* rule: unknown
1276
         * sample:
1277
         * 554 5.0.0 Service unavailable
1278
         */ elseif (preg_match('/Service unavailable/i', $dsn_msg)) {
1279
                    $result['rule_cat'] = 'unknown';
1280
                    $result['rule_no']  = '0214';
1281
                }
1282
                break;
1283
            case 'delayed':
1284
                $result['rule_cat'] = 'delayed';
1285
                $result['rule_no']  = '0110';
1286
                break;
1287
            case 'delivered':
1288
            case 'relayed':
1289
            case 'expanded': // unhandled cases
1290
                break;
1291
            default:
1292
                break;
1293
        }
1294
    }
1295
1296
    global $rule_categories, $bmh_newline;
1297
    if ('0000' == $result['rule_no']) {
1298
        if ($debug_mode) {
1299
            echo 'email: ' . $result['email'] . $bmh_newline;
1300
            echo 'Action: ' . $action . $bmh_newline;
1301
            echo 'Status: ' . $status_code . $bmh_newline;
1302
            echo 'Diagnostic-Code: ' . $diag_code . $bmh_newline;
1303
            echo "DSN Message:<br>\n" . $dsn_msg . $bmh_newline;
1304
            echo $bmh_newline;
1305
        }
1306 View Code Duplication
    } else {
1307
        if (false === $result['bounce_type']) {
1308
            $result['bounce_type'] = $rule_categories[$result['rule_cat']]['bounce_type'];
1309
            $result['remove']      = $rule_categories[$result['rule_cat']]['remove'];
1310
        }
1311
    }
1312
1313
    return $result;
1314
}
1315