Haraka 2.8.28 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.yaml +2 -10
- package/Changes.md +84 -2
- package/Dockerfile +1 -1
- package/Plugins.md +9 -4
- package/README.md +2 -6
- package/bin/haraka +5 -4
- package/config/outbound.ini +0 -7
- package/config/plugins +1 -1
- package/config/smtp.ini +1 -1
- package/config/smtp_forward.ini +2 -8
- package/config/smtp_proxy.ini +0 -6
- package/connection.js +178 -204
- package/coverage/lcov.info +13863 -0
- package/coverage/tmp/coverage-42958-1658373250585-0.json +1 -0
- package/coverage/tmp/coverage-42961-1658373250529-0.json +1 -0
- package/dkim.js +66 -73
- package/docs/Body.md +1 -22
- package/docs/CoreConfig.md +2 -2
- package/docs/Header.md +1 -47
- package/docs/Outbound.md +8 -36
- package/endpoint.js +1 -1
- package/haraka.js +1 -1
- package/host_pool.js +8 -12
- package/logger.js +25 -32
- package/outbound/client_pool.js +11 -153
- package/outbound/config.js +5 -11
- package/outbound/hmail.js +109 -143
- package/outbound/index.js +13 -25
- package/outbound/mx_lookup.js +10 -7
- package/outbound/queue.js +8 -12
- package/outbound/timer_queue.js +2 -4
- package/outbound/tls.js +17 -18
- package/outbound/todo.js +1 -0
- package/package.json +57 -55
- package/plugins/auth/auth_base.js +39 -63
- package/plugins/auth/auth_bridge.js +3 -4
- package/plugins/auth/auth_proxy.js +16 -16
- package/plugins/auth/auth_vpopmaild.js +30 -37
- package/plugins/auth/flat_file.js +9 -13
- package/plugins/avg.js +9 -11
- package/plugins/backscatterer.js +1 -1
- package/plugins/block_me.js +2 -6
- package/plugins/bounce.js +106 -124
- package/plugins/clamd.js +59 -63
- package/plugins/data.signatures.js +6 -6
- package/plugins/data.uribl.js +1 -415
- package/plugins/delay_deny.js +19 -20
- package/plugins/dkim_sign.js +56 -62
- package/plugins/dkim_verify.js +9 -8
- package/plugins/dns_list_base.js +43 -42
- package/plugins/dnsbl.js +41 -46
- package/plugins/dnswl.js +23 -26
- package/plugins/early_talker.js +24 -28
- package/plugins/esets.js +8 -11
- package/plugins/greylist.js +161 -190
- package/plugins/helo.checks.js +175 -197
- package/plugins/mail_from.is_resolvable.js +38 -38
- package/plugins/messagesniffer.js +33 -40
- package/plugins/prevent_credential_leaks.js +7 -5
- package/plugins/process_title.js +16 -17
- package/plugins/queue/deliver.js +2 -2
- package/plugins/queue/lmtp.js +5 -6
- package/plugins/queue/qmail-queue.js +11 -13
- package/plugins/queue/quarantine.js +25 -34
- package/plugins/queue/rabbitmq.js +3 -2
- package/plugins/queue/rabbitmq_amqplib.js +9 -9
- package/plugins/queue/smtp_bridge.js +5 -4
- package/plugins/queue/smtp_forward.js +81 -89
- package/plugins/queue/smtp_proxy.js +21 -22
- package/plugins/queue/test.js +2 -1
- package/plugins/rcpt_to.host_list_base.js +20 -30
- package/plugins/rcpt_to.in_host_list.js +12 -14
- package/plugins/rcpt_to.max_count.js +7 -5
- package/plugins/record_envelope_addresses.js +4 -6
- package/plugins/relay.js +64 -74
- package/plugins/reseed_rng.js +1 -2
- package/plugins/spamassassin.js +56 -68
- package/plugins/status.js +2 -3
- package/plugins/tarpit.js +8 -11
- package/plugins/tls.js +14 -17
- package/plugins/toobusy.js +6 -8
- package/plugins/xclient.js +14 -25
- package/plugins.js +24 -29
- package/rfc1869.js +2 -2
- package/server.js +3 -13
- package/smtp_client.js +138 -215
- package/tests/config/smtp_forward.ini +0 -6
- package/tests/fixtures/line_socket.js +1 -1
- package/tests/fixtures/util_hmailitem.js +5 -7
- package/tests/fixtures/vm_harness.js +2 -2
- package/tests/host_pool.js +13 -14
- package/tests/installation/plugins/inherits.js +1 -2
- package/tests/logger.js +2 -2
- package/tests/plugins/bounce.js +6 -8
- package/tests/plugins/dkim_signer.js +7 -7
- package/tests/plugins/dns_list_base.js +7 -7
- package/tests/plugins/helo.checks.js +1 -1
- package/tests/plugins/mail_from.is_resolvable.js +10 -54
- package/tests/plugins/queue/smtp_forward.js +11 -11
- package/tests/plugins/rcpt_to.host_list_base.js +1 -1
- package/tests/plugins/rcpt_to.in_host_list.js +1 -1
- package/tests/plugins/spamassassin.js +1 -1
- package/tests/queue/multibyte +0 -0
- package/tests/queue/plain +0 -0
- package/tests/rfc1869.js +4 -1
- package/tests/server.js +15 -9
- package/tests/smtp_client/auth.js +4 -14
- package/tests/smtp_client/basic.js +5 -15
- package/tests/smtp_client.js +7 -3
- package/tests/transaction.js +72 -19
- package/tls_socket.js +75 -85
- package/transaction.js +7 -9
- package/attachment_stream.js +0 -118
- package/bin/spf +0 -48
- package/chunkemitter.js +0 -75
- package/config/data.uribl.excludes +0 -202
- package/config/data.uribl.ini +0 -37
- package/config/spf.ini +0 -1
- package/docs/plugins/attachment.md +0 -92
- package/docs/plugins/data.uribl.md +0 -120
- package/docs/plugins/spf.md +0 -142
- package/mailbody.js +0 -502
- package/mailheader.js +0 -304
- package/messagestream.js +0 -441
- package/plugins/aliases.js +0 -120
- package/plugins/attachment.js +0 -503
- package/plugins/connect.p0f.js +0 -5
- package/plugins/spf.js +0 -327
- package/spf.js +0 -689
- package/tests/mailbody.js +0 -348
- package/tests/mailheader.js +0 -138
- package/tests/messagestream.js +0 -34
- package/tests/plugins/aliases.js +0 -376
- package/tests/plugins/spf.js +0 -251
- package/tests/spf.js +0 -96
package/connection.js
CHANGED
|
@@ -15,7 +15,7 @@ const constants = require('haraka-constants');
|
|
|
15
15
|
const net_utils = require('haraka-net-utils');
|
|
16
16
|
const Notes = require('haraka-notes');
|
|
17
17
|
const utils = require('haraka-utils');
|
|
18
|
-
const Address = require('address-rfc2821')
|
|
18
|
+
const { Address } = require('address-rfc2821');
|
|
19
19
|
const ResultStore = require('haraka-results');
|
|
20
20
|
|
|
21
21
|
// Haraka libs
|
|
@@ -187,6 +187,12 @@ class Connection {
|
|
|
187
187
|
});
|
|
188
188
|
|
|
189
189
|
self.client.on('timeout', () => {
|
|
190
|
+
// FIN has sent, when timeout just destroy socket
|
|
191
|
+
if (self.state >= states.DISCONNECTED) {
|
|
192
|
+
self.client.destroy();
|
|
193
|
+
self.loginfo(`timeout, destroy socket (state:${self.state})`)
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
190
196
|
if (self.state >= states.DISCONNECTING) return;
|
|
191
197
|
self.respond(421, 'timeout', () => {
|
|
192
198
|
self.fail('client connection timed out', log_data);
|
|
@@ -243,6 +249,7 @@ class Connection {
|
|
|
243
249
|
let loc = this;
|
|
244
250
|
for (let i=0; i < path_parts.length; i++) {
|
|
245
251
|
const part = path_parts[i];
|
|
252
|
+
if (part === "__proto__" || part === "constructor") continue;
|
|
246
253
|
|
|
247
254
|
// while another part remains
|
|
248
255
|
if (i < (path_parts.length - 1)) {
|
|
@@ -300,7 +307,6 @@ class Connection {
|
|
|
300
307
|
return this._relaying;
|
|
301
308
|
}
|
|
302
309
|
process_line (line) {
|
|
303
|
-
const self = this;
|
|
304
310
|
|
|
305
311
|
if (this.state >= states.DISCONNECTING) {
|
|
306
312
|
if (logger.would_log(logger.LOGPROTOCOL)) {
|
|
@@ -358,15 +364,14 @@ class Connection {
|
|
|
358
364
|
}
|
|
359
365
|
catch (err) {
|
|
360
366
|
if (err.stack) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
err.stack.split("\n").forEach(c.logerror);
|
|
367
|
+
this.logerror(`${method} failed: ${err}`);
|
|
368
|
+
err.stack.split("\n").forEach(this.logerror);
|
|
364
369
|
}
|
|
365
370
|
else {
|
|
366
371
|
this.logerror(`${method} failed: ${err}`);
|
|
367
372
|
}
|
|
368
373
|
this.respond(421, "Internal Server Error", () => {
|
|
369
|
-
|
|
374
|
+
this.disconnect();
|
|
370
375
|
});
|
|
371
376
|
}
|
|
372
377
|
}
|
|
@@ -409,7 +414,6 @@ class Connection {
|
|
|
409
414
|
this._process_data();
|
|
410
415
|
}
|
|
411
416
|
_process_data () {
|
|
412
|
-
const self = this;
|
|
413
417
|
// We *must* detect disconnected connections here as the state
|
|
414
418
|
// only transitions to states.CMD in the respond function below.
|
|
415
419
|
// Otherwise if multiple commands are pipelined and then the
|
|
@@ -447,7 +451,7 @@ class Connection {
|
|
|
447
451
|
this.logdebug('[early_talker]', { state: this.state, esmtp: this.esmtp, line: this_line });
|
|
448
452
|
}
|
|
449
453
|
this.early_talker = true;
|
|
450
|
-
setImmediate(() => {
|
|
454
|
+
setImmediate(() => { this._process_data() });
|
|
451
455
|
break;
|
|
452
456
|
}
|
|
453
457
|
else if ((this.state === states.PAUSE || this.state === states.PAUSE_SMTP) && this.esmtp) {
|
|
@@ -487,7 +491,7 @@ class Connection {
|
|
|
487
491
|
this.logdebug('[early_talker]', { state: this.state, esmtp: this.esmtp, line: this_line });
|
|
488
492
|
}
|
|
489
493
|
this.early_talker = true;
|
|
490
|
-
setImmediate(() => {
|
|
494
|
+
setImmediate(() => { this._process_data() });
|
|
491
495
|
}
|
|
492
496
|
break;
|
|
493
497
|
}
|
|
@@ -504,7 +508,7 @@ class Connection {
|
|
|
504
508
|
this.client.pause();
|
|
505
509
|
this.current_data = null;
|
|
506
510
|
return this.respond(521, "Command line too long", () => {
|
|
507
|
-
|
|
511
|
+
this.disconnect();
|
|
508
512
|
});
|
|
509
513
|
}
|
|
510
514
|
else {
|
|
@@ -598,11 +602,10 @@ class Connection {
|
|
|
598
602
|
}
|
|
599
603
|
disconnect () {
|
|
600
604
|
if (this.state >= states.DISCONNECTING) return;
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
self.current_data = null; // don't process any more data we have already received
|
|
605
|
+
this.state = states.DISCONNECTING;
|
|
606
|
+
this.current_data = null; // don't process any more data we have already received
|
|
604
607
|
this.reset_transaction(() => {
|
|
605
|
-
plugins.run_hooks('disconnect',
|
|
608
|
+
plugins.run_hooks('disconnect', this);
|
|
606
609
|
});
|
|
607
610
|
}
|
|
608
611
|
disconnect_respond () {
|
|
@@ -632,9 +635,8 @@ class Connection {
|
|
|
632
635
|
this.client.end();
|
|
633
636
|
}
|
|
634
637
|
get_capabilities () {
|
|
635
|
-
const capabilities = [];
|
|
636
638
|
|
|
637
|
-
return
|
|
639
|
+
return [];
|
|
638
640
|
}
|
|
639
641
|
tran_uuid () {
|
|
640
642
|
this.tran_count++;
|
|
@@ -665,17 +667,16 @@ class Connection {
|
|
|
665
667
|
this.resume();
|
|
666
668
|
}
|
|
667
669
|
init_transaction (cb) {
|
|
668
|
-
const self = this;
|
|
669
670
|
this.reset_transaction(() => {
|
|
670
|
-
|
|
671
|
+
this.transaction = trans.createTransaction(this.tran_uuid(), this.cfg);
|
|
671
672
|
// Catch any errors from the message_stream
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
673
|
+
this.transaction.message_stream.on('error', (err) => {
|
|
674
|
+
this.logcrit(`message_stream error: ${err.message}`);
|
|
675
|
+
this.respond('421', 'Internal Server Error', () => {
|
|
676
|
+
this.disconnect();
|
|
676
677
|
});
|
|
677
678
|
});
|
|
678
|
-
|
|
679
|
+
this.transaction.results = new ResultStore(this);
|
|
679
680
|
if (cb) cb();
|
|
680
681
|
});
|
|
681
682
|
}
|
|
@@ -687,21 +688,19 @@ class Connection {
|
|
|
687
688
|
this.respond(code, msg);
|
|
688
689
|
}
|
|
689
690
|
pause () {
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
self.state = states.PAUSE_DATA;
|
|
691
|
+
if (this.state >= states.DISCONNECTING) return;
|
|
692
|
+
this.client.pause();
|
|
693
|
+
if (this.state !== states.PAUSE_DATA) this.prev_state = this.state;
|
|
694
|
+
this.state = states.PAUSE_DATA;
|
|
695
695
|
}
|
|
696
696
|
resume () {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
self.prev_state = null;
|
|
697
|
+
if (this.state >= states.DISCONNECTING) return;
|
|
698
|
+
this.client.resume();
|
|
699
|
+
if (this.prev_state) {
|
|
700
|
+
this.state = this.prev_state;
|
|
701
|
+
this.prev_state = null;
|
|
703
702
|
}
|
|
704
|
-
setImmediate(() =>
|
|
703
|
+
setImmediate(() => this._process_data());
|
|
705
704
|
}
|
|
706
705
|
/////////////////////////////////////////////////////////////////////////////
|
|
707
706
|
// SMTP Responses
|
|
@@ -711,7 +710,6 @@ class Connection {
|
|
|
711
710
|
plugins.run_hooks('lookup_rdns', this);
|
|
712
711
|
}
|
|
713
712
|
lookup_rdns_respond (retval, msg) {
|
|
714
|
-
const self = this;
|
|
715
713
|
switch (retval) {
|
|
716
714
|
case constants.ok:
|
|
717
715
|
this.set('remote', 'host', (msg || 'Unknown'));
|
|
@@ -724,7 +722,7 @@ class Connection {
|
|
|
724
722
|
case constants.denydisconnect:
|
|
725
723
|
case constants.disconnect:
|
|
726
724
|
this.respond(554, msg || "rDNS Lookup Failed", () => {
|
|
727
|
-
|
|
725
|
+
this.disconnect();
|
|
728
726
|
});
|
|
729
727
|
break;
|
|
730
728
|
case constants.denysoft:
|
|
@@ -732,12 +730,12 @@ class Connection {
|
|
|
732
730
|
break;
|
|
733
731
|
case constants.denysoftdisconnect:
|
|
734
732
|
this.respond(421, msg || "rDNS Temporary Failure", () => {
|
|
735
|
-
|
|
733
|
+
this.disconnect();
|
|
736
734
|
});
|
|
737
735
|
break;
|
|
738
736
|
default:
|
|
739
737
|
dns.reverse(this.remote.ip, (err, domains) => {
|
|
740
|
-
|
|
738
|
+
this.rdns_response(err, domains);
|
|
741
739
|
});
|
|
742
740
|
}
|
|
743
741
|
}
|
|
@@ -761,7 +759,6 @@ class Connection {
|
|
|
761
759
|
plugins.run_hooks('connect', this);
|
|
762
760
|
}
|
|
763
761
|
unrecognized_command_respond (retval, msg) {
|
|
764
|
-
const self = this;
|
|
765
762
|
switch (retval) {
|
|
766
763
|
case constants.ok:
|
|
767
764
|
// response already sent, cool...
|
|
@@ -775,7 +772,7 @@ class Connection {
|
|
|
775
772
|
case constants.denydisconnect:
|
|
776
773
|
case constants.denysoftdisconnect:
|
|
777
774
|
this.respond(retval === constants.denydisconnect ? 521 : 421, msg || "Unrecognized command", () => {
|
|
778
|
-
|
|
775
|
+
this.disconnect();
|
|
779
776
|
});
|
|
780
777
|
break;
|
|
781
778
|
default:
|
|
@@ -784,7 +781,6 @@ class Connection {
|
|
|
784
781
|
}
|
|
785
782
|
}
|
|
786
783
|
connect_respond (retval, msg) {
|
|
787
|
-
const self = this;
|
|
788
784
|
// RFC 5321 Section 4.3.2 states that the only valid SMTP codes here are:
|
|
789
785
|
// 220 = Service ready
|
|
790
786
|
// 554 = Transaction failed (no SMTP service here)
|
|
@@ -796,7 +792,7 @@ class Connection {
|
|
|
796
792
|
case constants.denydisconnect:
|
|
797
793
|
case constants.disconnect:
|
|
798
794
|
this.respond(554, msg || "Your mail is not welcome here", () => {
|
|
799
|
-
|
|
795
|
+
this.disconnect();
|
|
800
796
|
});
|
|
801
797
|
break;
|
|
802
798
|
case constants.denysoft:
|
|
@@ -804,7 +800,7 @@ class Connection {
|
|
|
804
800
|
break;
|
|
805
801
|
case constants.denysoftdisconnect:
|
|
806
802
|
this.respond(421, msg || "Come back later", () => {
|
|
807
|
-
|
|
803
|
+
this.disconnect();
|
|
808
804
|
});
|
|
809
805
|
break;
|
|
810
806
|
default: {
|
|
@@ -840,28 +836,27 @@ class Connection {
|
|
|
840
836
|
}
|
|
841
837
|
}
|
|
842
838
|
helo_respond (retval, msg) {
|
|
843
|
-
const self = this;
|
|
844
839
|
switch (retval) {
|
|
845
840
|
case constants.deny:
|
|
846
841
|
this.respond(550, msg || "HELO denied", () => {
|
|
847
|
-
|
|
848
|
-
|
|
842
|
+
this.set('hello', 'verb', null);
|
|
843
|
+
this.set('hello', 'host', null);
|
|
849
844
|
});
|
|
850
845
|
break;
|
|
851
846
|
case constants.denydisconnect:
|
|
852
847
|
this.respond(550, msg || "HELO denied", () => {
|
|
853
|
-
|
|
848
|
+
this.disconnect();
|
|
854
849
|
});
|
|
855
850
|
break;
|
|
856
851
|
case constants.denysoft:
|
|
857
852
|
this.respond(450, msg || "HELO denied", () => {
|
|
858
|
-
|
|
859
|
-
|
|
853
|
+
this.set('hello', 'verb', null);
|
|
854
|
+
this.set('hello', 'host', null);
|
|
860
855
|
});
|
|
861
856
|
break;
|
|
862
857
|
case constants.denysoftdisconnect:
|
|
863
858
|
this.respond(450, msg || "HELO denied", () => {
|
|
864
|
-
|
|
859
|
+
this.disconnect();
|
|
865
860
|
});
|
|
866
861
|
break;
|
|
867
862
|
default:
|
|
@@ -871,29 +866,28 @@ class Connection {
|
|
|
871
866
|
}
|
|
872
867
|
}
|
|
873
868
|
ehlo_respond (retval, msg) {
|
|
874
|
-
const self = this;
|
|
875
869
|
|
|
876
870
|
switch (retval) {
|
|
877
871
|
case constants.deny:
|
|
878
872
|
this.respond(550, msg || "EHLO denied", () => {
|
|
879
|
-
|
|
880
|
-
|
|
873
|
+
this.set('hello', 'verb', null);
|
|
874
|
+
this.set('hello', 'host', null);
|
|
881
875
|
});
|
|
882
876
|
break;
|
|
883
877
|
case constants.denydisconnect:
|
|
884
878
|
this.respond(550, msg || "EHLO denied", () => {
|
|
885
|
-
|
|
879
|
+
this.disconnect();
|
|
886
880
|
});
|
|
887
881
|
break;
|
|
888
882
|
case constants.denysoft:
|
|
889
883
|
this.respond(450, msg || "EHLO denied", () => {
|
|
890
|
-
|
|
891
|
-
|
|
884
|
+
this.set('hello', 'verb', null);
|
|
885
|
+
this.set('hello', 'host', null);
|
|
892
886
|
});
|
|
893
887
|
break;
|
|
894
888
|
case constants.denysoftdisconnect:
|
|
895
889
|
this.respond(450, msg || "EHLO denied", () => {
|
|
896
|
-
|
|
890
|
+
this.disconnect();
|
|
897
891
|
});
|
|
898
892
|
break;
|
|
899
893
|
default: {
|
|
@@ -923,32 +917,30 @@ class Connection {
|
|
|
923
917
|
this.respond(250, this.capabilities);
|
|
924
918
|
}
|
|
925
919
|
quit_respond (retval, msg) {
|
|
926
|
-
const self = this;
|
|
927
920
|
this.respond(221, msg || `${this.local.host} ${this.connection_close_message}`, () => {
|
|
928
|
-
|
|
921
|
+
this.disconnect();
|
|
929
922
|
});
|
|
930
923
|
}
|
|
931
924
|
vrfy_respond (retval, msg) {
|
|
932
|
-
const self = this;
|
|
933
925
|
switch (retval) {
|
|
934
926
|
case constants.deny:
|
|
935
927
|
this.respond(550, msg || "Access Denied", () => {
|
|
936
|
-
|
|
928
|
+
this.reset_transaction();
|
|
937
929
|
});
|
|
938
930
|
break;
|
|
939
931
|
case constants.denydisconnect:
|
|
940
932
|
this.respond(550, msg || "Access Denied", () => {
|
|
941
|
-
|
|
933
|
+
this.disconnect();
|
|
942
934
|
});
|
|
943
935
|
break;
|
|
944
936
|
case constants.denysoft:
|
|
945
937
|
this.respond(450, msg || "Lookup Failed", () => {
|
|
946
|
-
|
|
938
|
+
this.reset_transaction();
|
|
947
939
|
});
|
|
948
940
|
break;
|
|
949
941
|
case constants.denysoftdisconnect:
|
|
950
942
|
this.respond(450, msg || "Lookup Failed", () => {
|
|
951
|
-
|
|
943
|
+
this.disconnect();
|
|
952
944
|
});
|
|
953
945
|
break;
|
|
954
946
|
case constants.ok:
|
|
@@ -959,14 +951,13 @@ class Connection {
|
|
|
959
951
|
}
|
|
960
952
|
}
|
|
961
953
|
noop_respond (retval, msg) {
|
|
962
|
-
const self = this;
|
|
963
954
|
switch (retval) {
|
|
964
955
|
case constants.deny:
|
|
965
956
|
this.respond(500, msg || "Stop wasting my time");
|
|
966
957
|
break;
|
|
967
958
|
case constants.denydisconnect:
|
|
968
959
|
this.respond(500, msg || "Stop wasting my time", () => {
|
|
969
|
-
|
|
960
|
+
this.disconnect();
|
|
970
961
|
});
|
|
971
962
|
break;
|
|
972
963
|
default:
|
|
@@ -974,10 +965,8 @@ class Connection {
|
|
|
974
965
|
}
|
|
975
966
|
}
|
|
976
967
|
rset_respond (retval, msg) {
|
|
977
|
-
// We ignore any plugin responses
|
|
978
|
-
const self = this;
|
|
979
968
|
this.respond(250, "OK", () => {
|
|
980
|
-
|
|
969
|
+
this.reset_transaction();
|
|
981
970
|
})
|
|
982
971
|
}
|
|
983
972
|
mail_respond (retval, msg) {
|
|
@@ -1062,9 +1051,8 @@ class Connection {
|
|
|
1062
1051
|
this.transaction.results.push({name: 'rcpt_to'}, { recipient });
|
|
1063
1052
|
}
|
|
1064
1053
|
rcpt_ok_respond (retval, msg) {
|
|
1065
|
-
const self = this;
|
|
1066
1054
|
if (!this.transaction) {
|
|
1067
|
-
|
|
1055
|
+
this.results.add(this, {err: 'rcpt_ok_respond found no transaction'});
|
|
1068
1056
|
return;
|
|
1069
1057
|
}
|
|
1070
1058
|
if (!msg) msg = this.last_rcpt_msg;
|
|
@@ -1082,31 +1070,31 @@ class Connection {
|
|
|
1082
1070
|
switch (retval) {
|
|
1083
1071
|
case constants.deny:
|
|
1084
1072
|
this.respond(550, msg || `${dmsg} denied`, () => {
|
|
1085
|
-
|
|
1086
|
-
|
|
1073
|
+
this.rcpt_incr(rcpt, 'reject', msg, retval);
|
|
1074
|
+
this.transaction.rcpt_to.pop();
|
|
1087
1075
|
});
|
|
1088
1076
|
break;
|
|
1089
1077
|
case constants.denydisconnect:
|
|
1090
1078
|
this.respond(550, msg || `${dmsg} denied`, () => {
|
|
1091
|
-
|
|
1092
|
-
|
|
1079
|
+
this.rcpt_incr(rcpt, 'reject', msg, retval);
|
|
1080
|
+
this.disconnect();
|
|
1093
1081
|
});
|
|
1094
1082
|
break;
|
|
1095
1083
|
case constants.denysoft:
|
|
1096
1084
|
this.respond(450, msg || `${dmsg} denied`, () => {
|
|
1097
|
-
|
|
1098
|
-
|
|
1085
|
+
this.rcpt_incr(rcpt, 'tempfail', msg, retval);
|
|
1086
|
+
this.transaction.rcpt_to.pop();
|
|
1099
1087
|
});
|
|
1100
1088
|
break;
|
|
1101
1089
|
case constants.denysoftdisconnect:
|
|
1102
1090
|
this.respond(450, msg || `${dmsg} denied`, () => {
|
|
1103
|
-
|
|
1104
|
-
|
|
1091
|
+
this.rcpt_incr(rcpt, 'tempfail', msg, retval);
|
|
1092
|
+
this.disconnect();
|
|
1105
1093
|
});
|
|
1106
1094
|
break;
|
|
1107
1095
|
default:
|
|
1108
1096
|
this.respond(250, msg || `${dmsg} OK`, () => {
|
|
1109
|
-
|
|
1097
|
+
this.rcpt_incr(rcpt, 'accept', msg, retval);
|
|
1110
1098
|
});
|
|
1111
1099
|
}
|
|
1112
1100
|
}
|
|
@@ -1115,7 +1103,6 @@ class Connection {
|
|
|
1115
1103
|
retval = constants.ok;
|
|
1116
1104
|
}
|
|
1117
1105
|
|
|
1118
|
-
const self = this;
|
|
1119
1106
|
if (!this.transaction) {
|
|
1120
1107
|
this.results.add(this, {err: 'rcpt_respond found no transaction'});
|
|
1121
1108
|
return;
|
|
@@ -1135,26 +1122,26 @@ class Connection {
|
|
|
1135
1122
|
switch (retval) {
|
|
1136
1123
|
case constants.deny:
|
|
1137
1124
|
this.respond(550, msg || `${dmsg} denied`, () => {
|
|
1138
|
-
|
|
1139
|
-
|
|
1125
|
+
this.rcpt_incr(rcpt, 'reject', msg, retval);
|
|
1126
|
+
this.transaction.rcpt_to.pop();
|
|
1140
1127
|
});
|
|
1141
1128
|
break;
|
|
1142
1129
|
case constants.denydisconnect:
|
|
1143
1130
|
this.respond(550, msg || `${dmsg} denied`, () => {
|
|
1144
|
-
|
|
1145
|
-
|
|
1131
|
+
this.rcpt_incr(rcpt, 'reject', msg, retval);
|
|
1132
|
+
this.disconnect();
|
|
1146
1133
|
});
|
|
1147
1134
|
break;
|
|
1148
1135
|
case constants.denysoft:
|
|
1149
1136
|
this.respond(450, msg || `${dmsg} denied`, () => {
|
|
1150
|
-
|
|
1151
|
-
|
|
1137
|
+
this.rcpt_incr(rcpt, 'tempfail', msg, retval);
|
|
1138
|
+
this.transaction.rcpt_to.pop();
|
|
1152
1139
|
});
|
|
1153
1140
|
break;
|
|
1154
1141
|
case constants.denysoftdisconnect:
|
|
1155
1142
|
this.respond(450, msg || `${dmsg} denied`, () => {
|
|
1156
|
-
|
|
1157
|
-
|
|
1143
|
+
this.rcpt_incr(rcpt, 'tempfail', msg, retval);
|
|
1144
|
+
this.disconnect();
|
|
1158
1145
|
});
|
|
1159
1146
|
break;
|
|
1160
1147
|
case constants.ok:
|
|
@@ -1168,8 +1155,8 @@ class Connection {
|
|
|
1168
1155
|
}
|
|
1169
1156
|
const rej_msg = `I cannot deliver mail for ${rcpt.format()}`;
|
|
1170
1157
|
this.respond(550, rej_msg, () => {
|
|
1171
|
-
|
|
1172
|
-
|
|
1158
|
+
this.rcpt_incr(rcpt, 'reject', rej_msg, retval);
|
|
1159
|
+
this.transaction.rcpt_to.pop();
|
|
1173
1160
|
});
|
|
1174
1161
|
}
|
|
1175
1162
|
}
|
|
@@ -1178,7 +1165,6 @@ class Connection {
|
|
|
1178
1165
|
// HAProxy support
|
|
1179
1166
|
|
|
1180
1167
|
cmd_proxy (line) {
|
|
1181
|
-
const self = this;
|
|
1182
1168
|
|
|
1183
1169
|
if (!this.proxy.allowed) {
|
|
1184
1170
|
this.respond(421, `PROXY not allowed from ${this.remote.ip}`);
|
|
@@ -1234,24 +1220,23 @@ class Connection {
|
|
|
1234
1220
|
};
|
|
1235
1221
|
|
|
1236
1222
|
this.reset_transaction(() => {
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
plugins.run_hooks('connect_init',
|
|
1223
|
+
this.set('proxy.ip', this.remote.ip);
|
|
1224
|
+
this.set('proxy.type', 'haproxy');
|
|
1225
|
+
this.relaying = false;
|
|
1226
|
+
this.set('local.ip', dst_ip);
|
|
1227
|
+
this.set('local.port', parseInt(dst_port, 10));
|
|
1228
|
+
this.set('remote.ip', src_ip);
|
|
1229
|
+
this.set('remote.port', parseInt(src_port, 10));
|
|
1230
|
+
this.set('remote.host', null);
|
|
1231
|
+
this.set('hello.host', null);
|
|
1232
|
+
plugins.run_hooks('connect_init', this);
|
|
1247
1233
|
});
|
|
1248
1234
|
}
|
|
1249
1235
|
/////////////////////////////////////////////////////////////////////////////
|
|
1250
1236
|
// SMTP Commands
|
|
1251
1237
|
|
|
1252
1238
|
cmd_internalcmd (line) {
|
|
1253
|
-
|
|
1254
|
-
if (!self.remote.is_local) {
|
|
1239
|
+
if (!this.remote.is_local) {
|
|
1255
1240
|
return this.respond(501, "INTERNALCMD not allowed remotely");
|
|
1256
1241
|
}
|
|
1257
1242
|
const results = (String(line)).split(/ +/);
|
|
@@ -1276,7 +1261,6 @@ class Connection {
|
|
|
1276
1261
|
return this.respond(250, "Command sent for execution. Check Haraka logs for results.");
|
|
1277
1262
|
}
|
|
1278
1263
|
cmd_helo (line) {
|
|
1279
|
-
const self = this;
|
|
1280
1264
|
const results = (String(line)).split(/ +/);
|
|
1281
1265
|
const host = results[0];
|
|
1282
1266
|
if (!host) {
|
|
@@ -1284,14 +1268,13 @@ class Connection {
|
|
|
1284
1268
|
}
|
|
1285
1269
|
|
|
1286
1270
|
this.reset_transaction(() => {
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
plugins.run_hooks('helo',
|
|
1271
|
+
this.set('hello', 'verb', 'HELO');
|
|
1272
|
+
this.set('hello', 'host', host);
|
|
1273
|
+
this.results.add({ name: 'helo' }, this.hello);
|
|
1274
|
+
plugins.run_hooks('helo', this, host);
|
|
1291
1275
|
});
|
|
1292
1276
|
}
|
|
1293
1277
|
cmd_ehlo (line) {
|
|
1294
|
-
const self = this;
|
|
1295
1278
|
const results = (String(line)).split(/ +/);
|
|
1296
1279
|
const host = results[0];
|
|
1297
1280
|
if (!host) {
|
|
@@ -1299,10 +1282,10 @@ class Connection {
|
|
|
1299
1282
|
}
|
|
1300
1283
|
|
|
1301
1284
|
this.reset_transaction(() => {
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
plugins.run_hooks('ehlo',
|
|
1285
|
+
this.set('hello', 'verb', 'EHLO');
|
|
1286
|
+
this.set('hello', 'host', host);
|
|
1287
|
+
this.results.add({ name: 'helo' }, this.hello);
|
|
1288
|
+
plugins.run_hooks('ehlo', this, host);
|
|
1306
1289
|
});
|
|
1307
1290
|
}
|
|
1308
1291
|
cmd_quit (args) {
|
|
@@ -1377,20 +1360,19 @@ class Connection {
|
|
|
1377
1360
|
}
|
|
1378
1361
|
|
|
1379
1362
|
// Handle SIZE extension
|
|
1380
|
-
if (params
|
|
1363
|
+
if (params?.SIZE && params.SIZE > 0) {
|
|
1381
1364
|
if (this.max_bytes > 0 && params.SIZE > this.max_bytes) {
|
|
1382
1365
|
return this.respond(550, 'Message too big!');
|
|
1383
1366
|
}
|
|
1384
1367
|
}
|
|
1385
1368
|
|
|
1386
|
-
const self = this;
|
|
1387
1369
|
this.init_transaction(() => {
|
|
1388
|
-
|
|
1389
|
-
if (
|
|
1390
|
-
|
|
1391
|
-
|
|
1370
|
+
this.transaction.mail_from = from;
|
|
1371
|
+
if (this.hello.verb == 'HELO') {
|
|
1372
|
+
this.transaction.encoding = 'binary';
|
|
1373
|
+
this.encoding = 'binary';
|
|
1392
1374
|
}
|
|
1393
|
-
plugins.run_hooks('mail',
|
|
1375
|
+
plugins.run_hooks('mail', this, [from, params]);
|
|
1394
1376
|
});
|
|
1395
1377
|
}
|
|
1396
1378
|
cmd_rcpt (line) {
|
|
@@ -1466,7 +1448,7 @@ class Connection {
|
|
|
1466
1448
|
}
|
|
1467
1449
|
auth_results (message) {
|
|
1468
1450
|
// http://tools.ietf.org/search/rfc7001
|
|
1469
|
-
const has_tran = !!((this.transaction
|
|
1451
|
+
const has_tran = !!((this.transaction?.notes));
|
|
1470
1452
|
|
|
1471
1453
|
// initialize connection note
|
|
1472
1454
|
if (!this.notes.authentication_results) {
|
|
@@ -1503,8 +1485,8 @@ class Connection {
|
|
|
1503
1485
|
const ars = this.transaction.header.get_all('Authentication-Results');
|
|
1504
1486
|
if (ars.length === 0) return;
|
|
1505
1487
|
|
|
1506
|
-
for (
|
|
1507
|
-
this.transaction.add_header('Original-Authentication-Results',
|
|
1488
|
+
for (const element of ars) {
|
|
1489
|
+
this.transaction.add_header('Original-Authentication-Results', element);
|
|
1508
1490
|
}
|
|
1509
1491
|
this.transaction.remove_header('Authentication-Results');
|
|
1510
1492
|
this.logdebug("Authentication-Results moved to Original-Authentication-Results");
|
|
@@ -1534,27 +1516,26 @@ class Connection {
|
|
|
1534
1516
|
plugins.run_hooks('data', this);
|
|
1535
1517
|
}
|
|
1536
1518
|
data_respond (retval, msg) {
|
|
1537
|
-
const self = this;
|
|
1538
1519
|
let cont = 0;
|
|
1539
1520
|
switch (retval) {
|
|
1540
1521
|
case constants.deny:
|
|
1541
1522
|
this.respond(554, msg || "Message denied", () => {
|
|
1542
|
-
|
|
1523
|
+
this.reset_transaction();
|
|
1543
1524
|
});
|
|
1544
1525
|
break;
|
|
1545
1526
|
case constants.denydisconnect:
|
|
1546
1527
|
this.respond(554, msg || "Message denied", () => {
|
|
1547
|
-
|
|
1528
|
+
this.disconnect();
|
|
1548
1529
|
});
|
|
1549
1530
|
break;
|
|
1550
1531
|
case constants.denysoft:
|
|
1551
1532
|
this.respond(451, msg || "Message denied", () => {
|
|
1552
|
-
|
|
1533
|
+
this.reset_transaction();
|
|
1553
1534
|
});
|
|
1554
1535
|
break;
|
|
1555
1536
|
case constants.denysoftdisconnect:
|
|
1556
1537
|
this.respond(451, msg || "Message denied", () => {
|
|
1557
|
-
|
|
1538
|
+
this.disconnect();
|
|
1558
1539
|
});
|
|
1559
1540
|
break;
|
|
1560
1541
|
default:
|
|
@@ -1565,12 +1546,11 @@ class Connection {
|
|
|
1565
1546
|
// We already checked for MAIL/RCPT in cmd_data
|
|
1566
1547
|
this.respond(354, "go ahead, make my day", () => {
|
|
1567
1548
|
// OK... now we get the data
|
|
1568
|
-
|
|
1569
|
-
|
|
1549
|
+
this.state = states.DATA;
|
|
1550
|
+
this.transaction.data_bytes = 0;
|
|
1570
1551
|
});
|
|
1571
1552
|
}
|
|
1572
1553
|
accumulate_data (line) {
|
|
1573
|
-
const self = this;
|
|
1574
1554
|
|
|
1575
1555
|
this.transaction.data_bytes += line.length;
|
|
1576
1556
|
|
|
@@ -1579,7 +1559,7 @@ class Connection {
|
|
|
1579
1559
|
line[0] === 0x2e &&
|
|
1580
1560
|
line[1] === 0x0d &&
|
|
1581
1561
|
line[2] === 0x0a) {
|
|
1582
|
-
|
|
1562
|
+
this.data_done();
|
|
1583
1563
|
return;
|
|
1584
1564
|
}
|
|
1585
1565
|
|
|
@@ -1589,7 +1569,7 @@ class Connection {
|
|
|
1589
1569
|
line[1] === 0x0a) {
|
|
1590
1570
|
this.lognotice('Client sent bare line-feed - .\\n rather than .\\r\\n');
|
|
1591
1571
|
this.respond(451, "Bare line-feed; see http://haraka.github.io/barelf/", () => {
|
|
1592
|
-
|
|
1572
|
+
this.reset_transaction();
|
|
1593
1573
|
});
|
|
1594
1574
|
return;
|
|
1595
1575
|
}
|
|
@@ -1602,7 +1582,7 @@ class Connection {
|
|
|
1602
1582
|
if (this.transaction.mime_part_count >= this.max_mime_parts) {
|
|
1603
1583
|
this.logcrit("Possible DoS attempt - too many MIME parts");
|
|
1604
1584
|
this.respond(554, "Transaction failed due to too many MIME parts", () => {
|
|
1605
|
-
|
|
1585
|
+
this.disconnect();
|
|
1606
1586
|
});
|
|
1607
1587
|
return;
|
|
1608
1588
|
}
|
|
@@ -1610,7 +1590,6 @@ class Connection {
|
|
|
1610
1590
|
this.transaction.add_data(line);
|
|
1611
1591
|
}
|
|
1612
1592
|
data_done () {
|
|
1613
|
-
const self = this;
|
|
1614
1593
|
this.pause();
|
|
1615
1594
|
this.totalbytes += this.transaction.data_bytes;
|
|
1616
1595
|
|
|
@@ -1624,7 +1603,7 @@ class Connection {
|
|
|
1624
1603
|
if (this.transaction.header.get_all('received').length > this.cfg.headers.max_received) {
|
|
1625
1604
|
this.logerror("Incoming message had too many Received headers");
|
|
1626
1605
|
this.respond(550, "Too many received headers - possible mail loop", () => {
|
|
1627
|
-
|
|
1606
|
+
this.reset_transaction();
|
|
1628
1607
|
});
|
|
1629
1608
|
return;
|
|
1630
1609
|
}
|
|
@@ -1645,12 +1624,12 @@ class Connection {
|
|
|
1645
1624
|
this.transaction.end_data(() => {
|
|
1646
1625
|
// As this will be called asynchronously,
|
|
1647
1626
|
// make sure we still have a transaction.
|
|
1648
|
-
if (!
|
|
1627
|
+
if (!this.transaction) return;
|
|
1649
1628
|
// Record the start time of this hook as we can't take too long
|
|
1650
1629
|
// as the client will typically hang up after 2 to 3 minutes
|
|
1651
1630
|
// despite the RFC mandating that 10 minutes should be allowed.
|
|
1652
|
-
|
|
1653
|
-
plugins.run_hooks('data_post',
|
|
1631
|
+
this.transaction.data_post_start = Date.now();
|
|
1632
|
+
plugins.run_hooks('data_post', this);
|
|
1654
1633
|
});
|
|
1655
1634
|
}
|
|
1656
1635
|
data_post_respond (retval, msg) {
|
|
@@ -1673,34 +1652,33 @@ class Connection {
|
|
|
1673
1652
|
this.transaction.remove_header('Authentication-Results');
|
|
1674
1653
|
this.transaction.add_leading_header('Authentication-Results', ar_field);
|
|
1675
1654
|
}
|
|
1676
|
-
const self = this;
|
|
1677
1655
|
switch (retval) {
|
|
1678
1656
|
case constants.deny:
|
|
1679
1657
|
this.respond(550, msg || "Message denied", () => {
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1658
|
+
this.msg_count.reject++;
|
|
1659
|
+
this.transaction.msg_status = 'rejected';
|
|
1660
|
+
this.reset_transaction(() => this.resume());
|
|
1683
1661
|
});
|
|
1684
1662
|
break;
|
|
1685
1663
|
case constants.denydisconnect:
|
|
1686
1664
|
this.respond(550, msg || "Message denied",() => {
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1665
|
+
this.msg_count.reject++;
|
|
1666
|
+
this.transaction.msg_status = 'rejected';
|
|
1667
|
+
this.disconnect();
|
|
1690
1668
|
});
|
|
1691
1669
|
break;
|
|
1692
1670
|
case constants.denysoft:
|
|
1693
1671
|
this.respond(450, msg || "Message denied temporarily", () => {
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1672
|
+
this.msg_count.tempfail++;
|
|
1673
|
+
this.transaction.msg_status = 'deferred';
|
|
1674
|
+
this.reset_transaction(() => this.resume());
|
|
1697
1675
|
});
|
|
1698
1676
|
break;
|
|
1699
1677
|
case constants.denysoftdisconnect:
|
|
1700
1678
|
this.respond(450, msg || "Message denied temporarily",() => {
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1679
|
+
this.msg_count.tempfail++;
|
|
1680
|
+
this.transaction.msg_status = 'deferred';
|
|
1681
|
+
this.disconnect();
|
|
1704
1682
|
});
|
|
1705
1683
|
break;
|
|
1706
1684
|
default:
|
|
@@ -1713,10 +1691,9 @@ class Connection {
|
|
|
1713
1691
|
}
|
|
1714
1692
|
}
|
|
1715
1693
|
max_data_exceeded_respond (retval, msg) {
|
|
1716
|
-
const self = this;
|
|
1717
1694
|
// TODO: Maybe figure out what to do with other return codes
|
|
1718
1695
|
this.respond(retval === constants.denysoft ? 450 : 550, "Message too big!", () => {
|
|
1719
|
-
|
|
1696
|
+
this.reset_transaction();
|
|
1720
1697
|
});
|
|
1721
1698
|
}
|
|
1722
1699
|
queue_msg (retval, msg) {
|
|
@@ -1755,7 +1732,6 @@ class Connection {
|
|
|
1755
1732
|
}
|
|
1756
1733
|
}
|
|
1757
1734
|
queue_outbound_respond (retval, msg) {
|
|
1758
|
-
const self = this;
|
|
1759
1735
|
if (!msg) msg = this.queue_msg(retval, msg) || 'Message Queued';
|
|
1760
1736
|
this.store_queue_result(retval, msg);
|
|
1761
1737
|
msg = `${msg} (${this.transaction.uuid})`;
|
|
@@ -1774,57 +1750,57 @@ class Connection {
|
|
|
1774
1750
|
break;
|
|
1775
1751
|
case constants.deny:
|
|
1776
1752
|
this.respond(550, msg, () => {
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1753
|
+
this.msg_count.reject++;
|
|
1754
|
+
this.transaction.msg_status = 'rejected';
|
|
1755
|
+
this.reset_transaction(() => this.resume());
|
|
1780
1756
|
});
|
|
1781
1757
|
break;
|
|
1782
1758
|
case constants.denydisconnect:
|
|
1783
1759
|
this.respond(550, msg, () => {
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1760
|
+
this.msg_count.reject++;
|
|
1761
|
+
this.transaction.msg_status = 'rejected';
|
|
1762
|
+
this.disconnect();
|
|
1787
1763
|
});
|
|
1788
1764
|
break;
|
|
1789
1765
|
case constants.denysoft:
|
|
1790
1766
|
this.respond(450, msg, () => {
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1767
|
+
this.msg_count.tempfail++;
|
|
1768
|
+
this.transaction.msg_status = 'deferred';
|
|
1769
|
+
this.reset_transaction(() => this.resume());
|
|
1794
1770
|
});
|
|
1795
1771
|
break;
|
|
1796
1772
|
case constants.denysoftdisconnect:
|
|
1797
1773
|
this.respond(450, msg, () => {
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1774
|
+
this.msg_count.tempfail++;
|
|
1775
|
+
this.transaction.msg_status = 'deferred';
|
|
1776
|
+
this.disconnect();
|
|
1801
1777
|
});
|
|
1802
1778
|
break;
|
|
1803
1779
|
default:
|
|
1804
1780
|
outbound.send_email(this.transaction, (retval2, msg2) => {
|
|
1805
|
-
if (!msg2) msg2 =
|
|
1781
|
+
if (!msg2) msg2 = this.queue_msg(retval2, msg);
|
|
1806
1782
|
switch (retval2) {
|
|
1807
1783
|
case constants.ok:
|
|
1808
|
-
if (!msg2) msg2 =
|
|
1809
|
-
plugins.run_hooks('queue_ok',
|
|
1784
|
+
if (!msg2) msg2 = this.queue_msg(retval2, msg2);
|
|
1785
|
+
plugins.run_hooks('queue_ok', this, msg2);
|
|
1810
1786
|
break;
|
|
1811
1787
|
case constants.deny:
|
|
1812
|
-
if (!msg2) msg2 =
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1788
|
+
if (!msg2) msg2 = this.queue_msg(retval2, msg2);
|
|
1789
|
+
this.respond(550, msg2, () => {
|
|
1790
|
+
this.msg_count.reject++;
|
|
1791
|
+
this.transaction.msg_status = 'rejected';
|
|
1792
|
+
this.reset_transaction(() => {
|
|
1793
|
+
this.resume();
|
|
1818
1794
|
});
|
|
1819
1795
|
});
|
|
1820
1796
|
break;
|
|
1821
1797
|
default:
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1798
|
+
this.logerror(`Unrecognized response from outbound layer: ${retval2} : ${msg2}`);
|
|
1799
|
+
this.respond(550, msg2 || "Internal Server Error", () => {
|
|
1800
|
+
this.msg_count.reject++;
|
|
1801
|
+
this.transaction.msg_status = 'rejected';
|
|
1802
|
+
this.reset_transaction(() => {
|
|
1803
|
+
this.resume();
|
|
1828
1804
|
});
|
|
1829
1805
|
});
|
|
1830
1806
|
}
|
|
@@ -1832,7 +1808,6 @@ class Connection {
|
|
|
1832
1808
|
}
|
|
1833
1809
|
}
|
|
1834
1810
|
queue_respond (retval, msg) {
|
|
1835
|
-
const self = this;
|
|
1836
1811
|
if (!msg) msg = this.queue_msg(retval, msg);
|
|
1837
1812
|
this.store_queue_result(retval, msg);
|
|
1838
1813
|
msg = `${msg} (${this.transaction.uuid})`;
|
|
@@ -1852,44 +1827,43 @@ class Connection {
|
|
|
1852
1827
|
break;
|
|
1853
1828
|
case constants.deny:
|
|
1854
1829
|
this.respond(550, msg, () => {
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1830
|
+
this.msg_count.reject++;
|
|
1831
|
+
this.transaction.msg_status = 'rejected';
|
|
1832
|
+
this.reset_transaction(() => this.resume());
|
|
1858
1833
|
});
|
|
1859
1834
|
break;
|
|
1860
1835
|
case constants.denydisconnect:
|
|
1861
1836
|
this.respond(550, msg, () => {
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1837
|
+
this.msg_count.reject++;
|
|
1838
|
+
this.transaction.msg_status = 'rejected';
|
|
1839
|
+
this.disconnect();
|
|
1865
1840
|
});
|
|
1866
1841
|
break;
|
|
1867
1842
|
case constants.denysoft:
|
|
1868
1843
|
this.respond(450, msg, () => {
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1844
|
+
this.msg_count.tempfail++;
|
|
1845
|
+
this.transaction.msg_status = 'deferred';
|
|
1846
|
+
this.reset_transaction(() => this.resume());
|
|
1872
1847
|
});
|
|
1873
1848
|
break;
|
|
1874
1849
|
case constants.denysoftdisconnect:
|
|
1875
1850
|
this.respond(450, msg, () => {
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1851
|
+
this.msg_count.tempfail++;
|
|
1852
|
+
this.transaction.msg_status = 'deferred';
|
|
1853
|
+
this.disconnect();
|
|
1879
1854
|
});
|
|
1880
1855
|
break;
|
|
1881
1856
|
default:
|
|
1882
1857
|
if (!msg) msg = 'Queuing declined or disabled, try later';
|
|
1883
1858
|
this.respond(451, msg, () => {
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1859
|
+
this.msg_count.tempfail++;
|
|
1860
|
+
this.transaction.msg_status = 'deferred';
|
|
1861
|
+
this.reset_transaction(() => this.resume());
|
|
1887
1862
|
});
|
|
1888
1863
|
break;
|
|
1889
1864
|
}
|
|
1890
1865
|
}
|
|
1891
1866
|
queue_ok_respond (retval, msg, params) {
|
|
1892
|
-
const self = this;
|
|
1893
1867
|
// This hook is common to both hook_queue and hook_queue_outbound
|
|
1894
1868
|
// retval and msg are ignored in this hook so we always log OK
|
|
1895
1869
|
this.lognotice(
|
|
@@ -1901,9 +1875,9 @@ class Connection {
|
|
|
1901
1875
|
);
|
|
1902
1876
|
|
|
1903
1877
|
this.respond(250, params, () => {
|
|
1904
|
-
|
|
1905
|
-
if (
|
|
1906
|
-
|
|
1878
|
+
this.msg_count.accept++;
|
|
1879
|
+
if (this.transaction) this.transaction.msg_status = 'accepted';
|
|
1880
|
+
this.reset_transaction(() => this.resume());
|
|
1907
1881
|
});
|
|
1908
1882
|
}
|
|
1909
1883
|
}
|