Haraka 3.1.1 → 3.1.2
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/.prettierignore +4 -0
- package/CONTRIBUTORS.md +5 -5
- package/Changes.md +62 -50
- package/Plugins.md +3 -1
- package/README.md +1 -1
- package/bin/haraka +475 -479
- package/config/outbound.ini +3 -0
- package/connection.js +1072 -1108
- package/docs/Connection.md +29 -30
- package/docs/CoreConfig.md +38 -39
- package/docs/CustomReturnCodes.md +0 -1
- package/docs/HAProxy.md +2 -2
- package/docs/Header.md +1 -1
- package/docs/Logging.md +29 -5
- package/docs/Outbound.md +93 -78
- package/docs/Plugins.md +103 -108
- package/docs/Transaction.md +49 -51
- package/docs/Tutorial.md +127 -143
- package/docs/deprecated/access.md +0 -1
- package/docs/deprecated/backscatterer.md +2 -3
- package/docs/deprecated/connect.rdns_access.md +18 -27
- package/docs/deprecated/data.headers.md +0 -1
- package/docs/deprecated/data.nomsgid.md +1 -2
- package/docs/deprecated/data.noreceived.md +1 -2
- package/docs/deprecated/data.rfc5322_header_checks.md +1 -2
- package/docs/deprecated/dkim_sign.md +13 -17
- package/docs/deprecated/dkim_verify.md +9 -17
- package/docs/deprecated/dnsbl.md +36 -38
- package/docs/deprecated/dnswl.md +41 -43
- package/docs/deprecated/lookup_rdns.strict.md +21 -34
- package/docs/deprecated/mail_from.access.md +17 -25
- package/docs/deprecated/mail_from.blocklist.md +9 -12
- package/docs/deprecated/mail_from.nobounces.md +1 -2
- package/docs/deprecated/rcpt_to.access.md +20 -27
- package/docs/deprecated/rcpt_to.blocklist.md +10 -13
- package/docs/deprecated/rcpt_to.routes.md +0 -1
- package/docs/deprecated/rdns.regexp.md +13 -15
- package/docs/plugins/aliases.md +89 -89
- package/docs/plugins/auth/auth_bridge.md +5 -7
- package/docs/plugins/auth/auth_ldap.md +11 -14
- package/docs/plugins/auth/auth_proxy.md +10 -12
- package/docs/plugins/auth/auth_vpopmaild.md +5 -6
- package/docs/plugins/auth/flat_file.md +4 -4
- package/docs/plugins/block_me.md +3 -3
- package/docs/plugins/data.signatures.md +1 -2
- package/docs/plugins/delay_deny.md +3 -4
- package/docs/plugins/max_unrecognized_commands.md +4 -4
- package/docs/plugins/prevent_credential_leaks.md +6 -6
- package/docs/plugins/process_title.md +18 -18
- package/docs/plugins/queue/deliver.md +2 -3
- package/docs/plugins/queue/discard.md +4 -4
- package/docs/plugins/queue/lmtp.md +1 -3
- package/docs/plugins/queue/qmail-queue.md +7 -9
- package/docs/plugins/queue/quarantine.md +16 -21
- package/docs/plugins/queue/rabbitmq.md +8 -11
- package/docs/plugins/queue/rabbitmq_amqplib.md +43 -39
- package/docs/plugins/queue/smtp_bridge.md +7 -10
- package/docs/plugins/queue/smtp_forward.md +42 -34
- package/docs/plugins/queue/smtp_proxy.md +30 -29
- package/docs/plugins/queue/test.md +1 -3
- package/docs/plugins/rcpt_to.in_host_list.md +6 -6
- package/docs/plugins/rcpt_to.max_count.md +1 -1
- package/docs/plugins/record_envelope_addresses.md +3 -3
- package/docs/plugins/reseed_rng.md +6 -6
- package/docs/plugins/status.md +9 -8
- package/docs/plugins/tarpit.md +7 -11
- package/docs/plugins/tls.md +12 -17
- package/docs/plugins/toobusy.md +4 -4
- package/docs/plugins/xclient.md +3 -3
- package/docs/tutorials/Migrating_from_v1_to_v2.md +19 -41
- package/docs/tutorials/SettingUpOutbound.md +6 -9
- package/endpoint.js +35 -38
- package/eslint.config.mjs +22 -19
- package/haraka.js +42 -47
- package/host_pool.js +75 -79
- package/http/html/404.html +45 -49
- package/http/html/index.html +39 -28
- package/http/package.json +2 -4
- package/line_socket.js +27 -28
- package/logger.js +182 -201
- package/outbound/client_pool.js +33 -33
- package/outbound/config.js +64 -59
- package/outbound/fsync_writestream.js +24 -25
- package/outbound/hmail.js +888 -835
- package/outbound/index.js +194 -187
- package/outbound/qfile.js +49 -52
- package/outbound/queue.js +197 -190
- package/outbound/timer_queue.js +41 -43
- package/outbound/tls.js +68 -61
- package/outbound/todo.js +11 -11
- package/package.json +32 -32
- package/plugins/.eslintrc.yaml +0 -1
- package/plugins/auth/auth_base.js +123 -127
- package/plugins/auth/auth_bridge.js +7 -7
- package/plugins/auth/auth_proxy.js +121 -126
- package/plugins/auth/auth_vpopmaild.js +84 -85
- package/plugins/auth/flat_file.js +18 -17
- package/plugins/block_me.js +31 -31
- package/plugins/data.signatures.js +13 -13
- package/plugins/delay_deny.js +65 -61
- package/plugins/prevent_credential_leaks.js +23 -23
- package/plugins/process_title.js +125 -128
- package/plugins/profile.js +5 -5
- package/plugins/queue/deliver.js +3 -3
- package/plugins/queue/discard.js +13 -14
- package/plugins/queue/lmtp.js +16 -17
- package/plugins/queue/qmail-queue.js +54 -55
- package/plugins/queue/quarantine.js +68 -70
- package/plugins/queue/rabbitmq.js +80 -87
- package/plugins/queue/rabbitmq_amqplib.js +75 -54
- package/plugins/queue/smtp_bridge.js +16 -16
- package/plugins/queue/smtp_forward.js +175 -179
- package/plugins/queue/smtp_proxy.js +69 -71
- package/plugins/queue/test.js +9 -9
- package/plugins/rcpt_to.host_list_base.js +30 -34
- package/plugins/rcpt_to.in_host_list.js +19 -19
- package/plugins/record_envelope_addresses.js +4 -4
- package/plugins/reseed_rng.js +4 -4
- package/plugins/status.js +90 -97
- package/plugins/tarpit.js +25 -14
- package/plugins/tls.js +68 -68
- package/plugins/toobusy.js +21 -23
- package/plugins/xclient.js +51 -53
- package/plugins.js +276 -293
- package/rfc1869.js +30 -35
- package/server.js +308 -299
- package/smtp_client.js +244 -228
- package/test/.eslintrc.yaml +0 -1
- package/test/connection.js +127 -134
- package/test/endpoint.js +53 -47
- package/test/fixtures/line_socket.js +12 -12
- package/test/fixtures/util_hmailitem.js +89 -85
- package/test/host_pool.js +90 -92
- package/test/installation/plugins/base_plugin.js +2 -2
- package/test/installation/plugins/folder_plugin/index.js +2 -3
- package/test/installation/plugins/inherits.js +3 -3
- package/test/installation/plugins/load_first.js +2 -3
- package/test/installation/plugins/plugin.js +1 -3
- package/test/installation/plugins/tls.js +2 -4
- package/test/logger.js +135 -116
- package/test/outbound/hmail.js +49 -35
- package/test/outbound/index.js +118 -101
- package/test/outbound/qfile.js +51 -53
- package/test/outbound_bounce_net_errors.js +84 -69
- package/test/outbound_bounce_rfc3464.js +235 -165
- package/test/plugins/auth/auth_base.js +420 -279
- package/test/plugins/auth/auth_vpopmaild.js +38 -39
- package/test/plugins/queue/smtp_forward.js +126 -104
- package/test/plugins/rcpt_to.host_list_base.js +85 -67
- package/test/plugins/rcpt_to.in_host_list.js +159 -112
- package/test/plugins/status.js +71 -64
- package/test/plugins/tls.js +37 -34
- package/test/plugins.js +97 -92
- package/test/rfc1869.js +19 -26
- package/test/server.js +293 -272
- package/test/smtp_client.js +180 -176
- package/test/tls_socket.js +62 -66
- package/test/transaction.js +159 -160
- package/tls_socket.js +331 -333
- package/transaction.js +129 -137
package/test/smtp_client.js
CHANGED
|
@@ -1,299 +1,303 @@
|
|
|
1
1
|
const assert = require('node:assert')
|
|
2
|
-
const path = require('node:path')
|
|
2
|
+
const path = require('node:path')
|
|
3
3
|
|
|
4
|
-
const fixtures = require('haraka-test-fixtures')
|
|
4
|
+
const fixtures = require('haraka-test-fixtures')
|
|
5
5
|
const message = require('haraka-email-message')
|
|
6
6
|
|
|
7
|
-
const smtp_client = require('../smtp_client')
|
|
7
|
+
const smtp_client = require('../smtp_client')
|
|
8
8
|
const test_socket = require('./fixtures/line_socket')
|
|
9
9
|
|
|
10
|
-
function getClientOpts
|
|
11
|
-
return {
|
|
10
|
+
function getClientOpts(socket) {
|
|
11
|
+
return {
|
|
12
|
+
port: 25,
|
|
13
|
+
host: 'localhost',
|
|
14
|
+
connect_timeout: 30,
|
|
15
|
+
idle_timeout: 30,
|
|
16
|
+
socket,
|
|
17
|
+
}
|
|
12
18
|
}
|
|
13
19
|
|
|
14
20
|
describe('smtp_client', () => {
|
|
15
|
-
|
|
16
21
|
it('testUpgradeIsCalledOnSTARTTLS', () => {
|
|
17
|
-
|
|
18
|
-
const plugin = new fixtures.plugin('queue/smtp_forward');
|
|
22
|
+
const plugin = new fixtures.plugin('queue/smtp_forward')
|
|
19
23
|
|
|
20
24
|
// switch config directory to 'test/config'
|
|
21
|
-
plugin.config = plugin.config.module_config(path.resolve('test'))
|
|
25
|
+
plugin.config = plugin.config.module_config(path.resolve('test'))
|
|
22
26
|
|
|
23
|
-
plugin.register()
|
|
27
|
+
plugin.register()
|
|
24
28
|
|
|
25
|
-
const cmds = {}
|
|
26
|
-
let upgradeArgs = {}
|
|
29
|
+
const cmds = {}
|
|
30
|
+
let upgradeArgs = {}
|
|
27
31
|
|
|
28
32
|
const socket = {
|
|
29
|
-
setTimeout: arg => {
|
|
30
|
-
setKeepAlive: arg => {
|
|
33
|
+
setTimeout: (arg) => {},
|
|
34
|
+
setKeepAlive: (arg) => {},
|
|
31
35
|
on: (eventName, callback) => {
|
|
32
|
-
cmds[eventName] = callback
|
|
36
|
+
cmds[eventName] = callback
|
|
37
|
+
},
|
|
38
|
+
upgrade: (arg) => {
|
|
39
|
+
upgradeArgs = arg
|
|
33
40
|
},
|
|
34
|
-
upgrade: arg => {
|
|
35
|
-
upgradeArgs = arg;
|
|
36
|
-
}
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
const client = new smtp_client.smtp_client(getClientOpts(socket))
|
|
40
|
-
client.load_tls_config({ key: Buffer.from('OutboundTlsKeyLoaded')})
|
|
43
|
+
const client = new smtp_client.smtp_client(getClientOpts(socket))
|
|
44
|
+
client.load_tls_config({ key: Buffer.from('OutboundTlsKeyLoaded') })
|
|
41
45
|
|
|
42
|
-
client.command = 'starttls'
|
|
43
|
-
cmds.line('250 Hello client.example.com\r\n')
|
|
46
|
+
client.command = 'starttls'
|
|
47
|
+
cmds.line('250 Hello client.example.com\r\n')
|
|
44
48
|
|
|
45
|
-
const { StringDecoder } = require('string_decoder')
|
|
46
|
-
const decoder = new StringDecoder('utf8')
|
|
49
|
+
const { StringDecoder } = require('string_decoder')
|
|
50
|
+
const decoder = new StringDecoder('utf8')
|
|
47
51
|
|
|
48
|
-
const cent = Buffer.from(upgradeArgs.key)
|
|
49
|
-
assert.equal(decoder.write(cent), 'OutboundTlsKeyLoaded')
|
|
52
|
+
const cent = Buffer.from(upgradeArgs.key)
|
|
53
|
+
assert.equal(decoder.write(cent), 'OutboundTlsKeyLoaded')
|
|
50
54
|
})
|
|
51
55
|
|
|
52
56
|
it('startTLS', () => {
|
|
53
|
-
|
|
54
|
-
let cmd = '';
|
|
57
|
+
let cmd = ''
|
|
55
58
|
|
|
56
59
|
const socket = {
|
|
57
|
-
setTimeout: arg => {
|
|
58
|
-
setKeepAlive: arg => {
|
|
59
|
-
on: (eventName, callback) => {
|
|
60
|
-
upgrade: arg => {
|
|
61
|
-
write: arg => {
|
|
62
|
-
|
|
60
|
+
setTimeout: (arg) => {},
|
|
61
|
+
setKeepAlive: (arg) => {},
|
|
62
|
+
on: (eventName, callback) => {},
|
|
63
|
+
upgrade: (arg) => {},
|
|
64
|
+
write: (arg) => {
|
|
65
|
+
cmd = arg
|
|
66
|
+
},
|
|
67
|
+
}
|
|
63
68
|
|
|
64
|
-
const client = new smtp_client.smtp_client(getClientOpts(socket))
|
|
65
|
-
client.tls_options = {}
|
|
69
|
+
const client = new smtp_client.smtp_client(getClientOpts(socket))
|
|
70
|
+
client.tls_options = {}
|
|
66
71
|
|
|
67
|
-
client.secured = false
|
|
68
|
-
client.response = [
|
|
72
|
+
client.secured = false
|
|
73
|
+
client.response = ['STARTTLS']
|
|
69
74
|
|
|
70
|
-
smtp_client.onCapabilitiesOutbound(client, false, undefined, {
|
|
75
|
+
smtp_client.onCapabilitiesOutbound(client, false, undefined, {
|
|
76
|
+
enable_tls: true,
|
|
77
|
+
})
|
|
71
78
|
|
|
72
|
-
assert.equal(cmd, 'STARTTLS\r\n')
|
|
79
|
+
assert.equal(cmd, 'STARTTLS\r\n')
|
|
73
80
|
})
|
|
74
81
|
|
|
75
82
|
describe('auth', () => {
|
|
76
|
-
|
|
77
83
|
beforeEach((done) => {
|
|
78
|
-
smtp_client.get_client(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
smtp_client.get_client(
|
|
85
|
+
{ notes: {} },
|
|
86
|
+
(client) => {
|
|
87
|
+
this.client = client
|
|
88
|
+
done()
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
socket: test_socket.connect(),
|
|
92
|
+
},
|
|
85
93
|
)
|
|
86
94
|
})
|
|
87
95
|
|
|
88
96
|
it('authenticates during SMTP conversation', (done) => {
|
|
97
|
+
const message_stream = new message.stream({ main: { spool_after: 1024 } }, '123456789')
|
|
89
98
|
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
)
|
|
99
|
+
const data = []
|
|
100
|
+
let reading_body = false
|
|
101
|
+
data.push('220 hi')
|
|
93
102
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
assert.equal(this.client.response[0], 'hi');
|
|
100
|
-
assert.equal('EHLO', command);
|
|
101
|
-
this.client.send_command(command, 'example.com');
|
|
102
|
-
});
|
|
103
|
+
this.client.on('greeting', (command) => {
|
|
104
|
+
assert.equal(this.client.response[0], 'hi')
|
|
105
|
+
assert.equal('EHLO', command)
|
|
106
|
+
this.client.send_command(command, 'example.com')
|
|
107
|
+
})
|
|
103
108
|
|
|
104
|
-
data.push('EHLO example.com')
|
|
105
|
-
data.push('250 hello')
|
|
109
|
+
data.push('EHLO example.com')
|
|
110
|
+
data.push('250 hello')
|
|
106
111
|
|
|
107
112
|
this.client.on('helo', () => {
|
|
108
|
-
assert.equal(this.client.response[0], 'hello')
|
|
109
|
-
this.client.send_command('AUTH', 'PLAIN AHRlc3QAdGVzdHBhc3M=')
|
|
110
|
-
this.client.send_command('MAIL', 'FROM: me@example.com')
|
|
111
|
-
})
|
|
113
|
+
assert.equal(this.client.response[0], 'hello')
|
|
114
|
+
this.client.send_command('AUTH', 'PLAIN AHRlc3QAdGVzdHBhc3M=')
|
|
115
|
+
this.client.send_command('MAIL', 'FROM: me@example.com')
|
|
116
|
+
})
|
|
112
117
|
|
|
113
|
-
data.push('AUTH PLAIN AHRlc3QAdGVzdHBhc3M=')
|
|
114
|
-
data.push('235 Authentication successful.')
|
|
118
|
+
data.push('AUTH PLAIN AHRlc3QAdGVzdHBhc3M=') // test/testpass
|
|
119
|
+
data.push('235 Authentication successful.')
|
|
115
120
|
|
|
116
|
-
data.push('MAIL FROM: me@example.com')
|
|
117
|
-
data.push('250 sender ok')
|
|
121
|
+
data.push('MAIL FROM: me@example.com')
|
|
122
|
+
data.push('250 sender ok')
|
|
118
123
|
|
|
119
124
|
this.client.on('mail', () => {
|
|
120
|
-
assert.equal(this.client.response[0], 'sender ok')
|
|
121
|
-
this.client.send_command('RCPT', 'TO: you@example.com')
|
|
122
|
-
})
|
|
125
|
+
assert.equal(this.client.response[0], 'sender ok')
|
|
126
|
+
this.client.send_command('RCPT', 'TO: you@example.com')
|
|
127
|
+
})
|
|
123
128
|
|
|
124
|
-
data.push('RCPT TO: you@example.com')
|
|
125
|
-
data.push('250 recipient ok')
|
|
129
|
+
data.push('RCPT TO: you@example.com')
|
|
130
|
+
data.push('250 recipient ok')
|
|
126
131
|
|
|
127
132
|
this.client.on('rcpt', () => {
|
|
128
|
-
assert.equal(this.client.response[0], 'recipient ok')
|
|
129
|
-
this.client.send_command('DATA')
|
|
130
|
-
})
|
|
133
|
+
assert.equal(this.client.response[0], 'recipient ok')
|
|
134
|
+
this.client.send_command('DATA')
|
|
135
|
+
})
|
|
131
136
|
|
|
132
|
-
data.push('DATA')
|
|
133
|
-
data.push('354 go ahead')
|
|
137
|
+
data.push('DATA')
|
|
138
|
+
data.push('354 go ahead')
|
|
134
139
|
|
|
135
140
|
this.client.on('data', () => {
|
|
136
|
-
assert.equal(this.client.response[0], 'go ahead')
|
|
137
|
-
this.client.start_data(message_stream)
|
|
141
|
+
assert.equal(this.client.response[0], 'go ahead')
|
|
142
|
+
this.client.start_data(message_stream)
|
|
138
143
|
message_stream.on('end', () => {
|
|
139
|
-
this.client.socket.write('.\r\n')
|
|
140
|
-
})
|
|
141
|
-
message_stream.add_line('Header: test\r\n')
|
|
142
|
-
message_stream.add_line('\r\n')
|
|
143
|
-
message_stream.add_line('hi\r\n')
|
|
144
|
-
message_stream.add_line_end()
|
|
145
|
-
})
|
|
144
|
+
this.client.socket.write('.\r\n')
|
|
145
|
+
})
|
|
146
|
+
message_stream.add_line('Header: test\r\n')
|
|
147
|
+
message_stream.add_line('\r\n')
|
|
148
|
+
message_stream.add_line('hi\r\n')
|
|
149
|
+
message_stream.add_line_end()
|
|
150
|
+
})
|
|
146
151
|
|
|
147
|
-
data.push('.')
|
|
148
|
-
data.push('250 message queued')
|
|
152
|
+
data.push('.')
|
|
153
|
+
data.push('250 message queued')
|
|
149
154
|
|
|
150
155
|
this.client.on('dot', () => {
|
|
151
|
-
assert.equal(this.client.response[0], 'message queued')
|
|
152
|
-
this.client.send_command('QUIT')
|
|
153
|
-
})
|
|
156
|
+
assert.equal(this.client.response[0], 'message queued')
|
|
157
|
+
this.client.send_command('QUIT')
|
|
158
|
+
})
|
|
154
159
|
|
|
155
|
-
data.push('QUIT')
|
|
156
|
-
data.push('221 goodbye')
|
|
160
|
+
data.push('QUIT')
|
|
161
|
+
data.push('221 goodbye')
|
|
157
162
|
|
|
158
163
|
this.client.on('quit', () => {
|
|
159
|
-
assert.equal(this.client.response[0], 'goodbye')
|
|
164
|
+
assert.equal(this.client.response[0], 'goodbye')
|
|
160
165
|
done()
|
|
161
|
-
})
|
|
166
|
+
})
|
|
162
167
|
|
|
163
168
|
this.client.socket.write = function (line) {
|
|
164
169
|
if (data.length == 0) {
|
|
165
|
-
assert.ok(false)
|
|
166
|
-
return
|
|
170
|
+
assert.ok(false)
|
|
171
|
+
return
|
|
167
172
|
}
|
|
168
|
-
assert.equal(`${data.shift()}\r\n`, line)
|
|
173
|
+
assert.equal(`${data.shift()}\r\n`, line)
|
|
169
174
|
if (reading_body && line == '.\r\n') {
|
|
170
|
-
reading_body = false
|
|
175
|
+
reading_body = false
|
|
171
176
|
}
|
|
172
177
|
if (!reading_body) {
|
|
173
178
|
if (line == 'DATA\r\n') {
|
|
174
|
-
reading_body = true
|
|
179
|
+
reading_body = true
|
|
175
180
|
}
|
|
176
181
|
while (true) {
|
|
177
|
-
const line2 = data.shift()
|
|
178
|
-
this.emit('line', `${line2}\r\n`)
|
|
179
|
-
if (line2[3] == ' ') break
|
|
182
|
+
const line2 = data.shift()
|
|
183
|
+
this.emit('line', `${line2}\r\n`)
|
|
184
|
+
if (line2[3] == ' ') break
|
|
180
185
|
}
|
|
181
186
|
}
|
|
182
187
|
|
|
183
|
-
return true
|
|
184
|
-
}
|
|
188
|
+
return true
|
|
189
|
+
}
|
|
185
190
|
|
|
186
|
-
this.client.socket.emit('line', data.shift())
|
|
191
|
+
this.client.socket.emit('line', data.shift())
|
|
187
192
|
})
|
|
188
193
|
})
|
|
189
194
|
|
|
190
195
|
describe('basic', () => {
|
|
191
|
-
|
|
192
196
|
beforeEach((done) => {
|
|
193
|
-
smtp_client.get_client(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
smtp_client.get_client(
|
|
198
|
+
{ notes: {} },
|
|
199
|
+
(client) => {
|
|
200
|
+
this.client = client
|
|
201
|
+
done()
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
socket: test_socket.connect(),
|
|
205
|
+
},
|
|
206
|
+
)
|
|
200
207
|
})
|
|
201
208
|
|
|
202
209
|
it('conducts a SMTP session', (done) => {
|
|
210
|
+
const message_stream = new message.stream({ main: { spool_after: 1024 } }, '123456789')
|
|
203
211
|
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
const data = [];
|
|
209
|
-
let reading_body = false;
|
|
210
|
-
data.push('220 hi');
|
|
212
|
+
const data = []
|
|
213
|
+
let reading_body = false
|
|
214
|
+
data.push('220 hi')
|
|
211
215
|
|
|
212
|
-
this.client.on('greeting', command => {
|
|
213
|
-
assert.equal(this.client.response[0], 'hi')
|
|
214
|
-
assert.equal('EHLO', command)
|
|
215
|
-
this.client.send_command(command, 'example.com')
|
|
216
|
-
})
|
|
216
|
+
this.client.on('greeting', (command) => {
|
|
217
|
+
assert.equal(this.client.response[0], 'hi')
|
|
218
|
+
assert.equal('EHLO', command)
|
|
219
|
+
this.client.send_command(command, 'example.com')
|
|
220
|
+
})
|
|
217
221
|
|
|
218
|
-
data.push('EHLO example.com')
|
|
219
|
-
data.push('250 hello')
|
|
222
|
+
data.push('EHLO example.com')
|
|
223
|
+
data.push('250 hello')
|
|
220
224
|
|
|
221
225
|
this.client.on('helo', () => {
|
|
222
|
-
assert.equal(this.client.response[0], 'hello')
|
|
223
|
-
this.client.send_command('MAIL', 'FROM: me@example.com')
|
|
224
|
-
})
|
|
226
|
+
assert.equal(this.client.response[0], 'hello')
|
|
227
|
+
this.client.send_command('MAIL', 'FROM: me@example.com')
|
|
228
|
+
})
|
|
225
229
|
|
|
226
|
-
data.push('MAIL FROM: me@example.com')
|
|
227
|
-
data.push('250 sender ok')
|
|
230
|
+
data.push('MAIL FROM: me@example.com')
|
|
231
|
+
data.push('250 sender ok')
|
|
228
232
|
|
|
229
233
|
this.client.on('mail', () => {
|
|
230
|
-
assert.equal(this.client.response[0], 'sender ok')
|
|
231
|
-
this.client.send_command('RCPT', 'TO: you@example.com')
|
|
232
|
-
})
|
|
234
|
+
assert.equal(this.client.response[0], 'sender ok')
|
|
235
|
+
this.client.send_command('RCPT', 'TO: you@example.com')
|
|
236
|
+
})
|
|
233
237
|
|
|
234
|
-
data.push('RCPT TO: you@example.com')
|
|
235
|
-
data.push('250 recipient ok')
|
|
238
|
+
data.push('RCPT TO: you@example.com')
|
|
239
|
+
data.push('250 recipient ok')
|
|
236
240
|
|
|
237
241
|
this.client.on('rcpt', () => {
|
|
238
|
-
assert.equal(this.client.response[0], 'recipient ok')
|
|
239
|
-
this.client.send_command('DATA')
|
|
240
|
-
})
|
|
242
|
+
assert.equal(this.client.response[0], 'recipient ok')
|
|
243
|
+
this.client.send_command('DATA')
|
|
244
|
+
})
|
|
241
245
|
|
|
242
|
-
data.push('DATA')
|
|
243
|
-
data.push('354 go ahead')
|
|
246
|
+
data.push('DATA')
|
|
247
|
+
data.push('354 go ahead')
|
|
244
248
|
|
|
245
249
|
this.client.on('data', () => {
|
|
246
|
-
assert.equal(this.client.response[0], 'go ahead')
|
|
247
|
-
this.client.start_data(message_stream)
|
|
250
|
+
assert.equal(this.client.response[0], 'go ahead')
|
|
251
|
+
this.client.start_data(message_stream)
|
|
248
252
|
message_stream.on('end', () => {
|
|
249
|
-
this.client.socket.write('.\r\n')
|
|
250
|
-
})
|
|
251
|
-
message_stream.add_line('Header: test\r\n')
|
|
252
|
-
message_stream.add_line('\r\n')
|
|
253
|
-
message_stream.add_line('hi\r\n')
|
|
254
|
-
message_stream.add_line_end()
|
|
255
|
-
})
|
|
253
|
+
this.client.socket.write('.\r\n')
|
|
254
|
+
})
|
|
255
|
+
message_stream.add_line('Header: test\r\n')
|
|
256
|
+
message_stream.add_line('\r\n')
|
|
257
|
+
message_stream.add_line('hi\r\n')
|
|
258
|
+
message_stream.add_line_end()
|
|
259
|
+
})
|
|
256
260
|
|
|
257
|
-
data.push('.')
|
|
258
|
-
data.push('250 message queued')
|
|
261
|
+
data.push('.')
|
|
262
|
+
data.push('250 message queued')
|
|
259
263
|
|
|
260
264
|
this.client.on('dot', () => {
|
|
261
|
-
assert.equal(this.client.response[0], 'message queued')
|
|
262
|
-
this.client.send_command('QUIT')
|
|
263
|
-
})
|
|
265
|
+
assert.equal(this.client.response[0], 'message queued')
|
|
266
|
+
this.client.send_command('QUIT')
|
|
267
|
+
})
|
|
264
268
|
|
|
265
|
-
data.push('QUIT')
|
|
266
|
-
data.push('221 goodbye')
|
|
269
|
+
data.push('QUIT')
|
|
270
|
+
data.push('221 goodbye')
|
|
267
271
|
|
|
268
272
|
this.client.on('quit', () => {
|
|
269
|
-
assert.equal(this.client.response[0], 'goodbye')
|
|
273
|
+
assert.equal(this.client.response[0], 'goodbye')
|
|
270
274
|
done()
|
|
271
|
-
})
|
|
275
|
+
})
|
|
272
276
|
|
|
273
277
|
this.client.socket.write = function (line) {
|
|
274
278
|
if (data.length == 0) {
|
|
275
|
-
assert.ok(false)
|
|
276
|
-
return
|
|
279
|
+
assert.ok(false)
|
|
280
|
+
return
|
|
277
281
|
}
|
|
278
|
-
assert.equal(`${data.shift()
|
|
282
|
+
assert.equal(`${data.shift()}\r\n`, line)
|
|
279
283
|
if (reading_body && line == '.\r\n') {
|
|
280
|
-
reading_body = false
|
|
284
|
+
reading_body = false
|
|
281
285
|
}
|
|
282
|
-
if (reading_body) return true
|
|
286
|
+
if (reading_body) return true
|
|
283
287
|
|
|
284
288
|
if (line == 'DATA\r\n') {
|
|
285
|
-
reading_body = true
|
|
289
|
+
reading_body = true
|
|
286
290
|
}
|
|
287
291
|
while (true) {
|
|
288
|
-
const line2 = data.shift()
|
|
289
|
-
this.emit('line', `${line2
|
|
290
|
-
if (line2[3] == ' ') break
|
|
292
|
+
const line2 = data.shift()
|
|
293
|
+
this.emit('line', `${line2}\r\n`)
|
|
294
|
+
if (line2[3] == ' ') break
|
|
291
295
|
}
|
|
292
296
|
|
|
293
|
-
return true
|
|
294
|
-
}
|
|
297
|
+
return true
|
|
298
|
+
}
|
|
295
299
|
|
|
296
|
-
this.client.socket.emit('line', data.shift())
|
|
300
|
+
this.client.socket.emit('line', data.shift())
|
|
297
301
|
})
|
|
298
302
|
})
|
|
299
303
|
})
|