Skip to content

Commit

Permalink
add timeout to data sockets
Browse files Browse the repository at this point in the history
  • Loading branch information
mailsvb committed Mar 17, 2022
1 parent f70bcf7 commit e3196c1
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 3 deletions.
16 changes: 16 additions & 0 deletions lib/jsftpd.js
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,11 @@ class ftpd {
if (isSecure === true && protection === true) {
dataChannel = tls.Server(main._opt.tls)
dataChannel.on('secureConnection', (pasvSocket) => {
pasvSocket.on('error', main.ErrorHandler)
pasvSocket.setTimeout(5000)
pasvSocket.on('timeout', () => {
pasvSocket.destroy()
})
main.DebugHandler(`${connectionInfo} data connection established`)
dataObj.dataSocket = pasvSocket
if (dataObj.method) {
Expand All @@ -968,6 +973,12 @@ class ftpd {
} else {
dataChannel = net.Server()
dataChannel.on('connection', (pasvSocket) => {
pasvSocket.on('error', main.ErrorHandler)
pasvSocket.setTimeout(5000)
pasvSocket.on('timeout', () => {
pasvSocket.destroy()
})
pasvSocket.on('close', () => main.DebugHandler(`${connectionInfo} data connection has been closed`))
if (isSecure === true && protection === true) {
pasvSocket = new tls.TLSSocket(pasvSocket, { isServer: true, secureContext: tls.createSecureContext(main._opt.tls) })
pasvSocket.on('secure', () => {
Expand Down Expand Up @@ -1004,11 +1015,16 @@ class ftpd {
dataObj.dataSocket = activeSocket
dataObj.method(dataObj)
})
activeSocket.on('error', main.ErrorHandler)
} else {
obj.dataSocket = client
obj.method(obj)
}
})
client.setTimeout(5000)
client.on('timeout', () => {
client.destroy()
})
client.on('error', main.ErrorHandler)
} else {
obj.method(obj)
Expand Down
2 changes: 1 addition & 1 deletion test/LIST.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ test('test LIST message', async () => {

let promiseSocket = new PromiseSocket(new net.Socket())
let socket = promiseSocket.stream
await socket.connect(cmdPortTCP, 'localhost')
await socket.connect(cmdPortTCP, '127.0.0.1', 'localhost')
content = await promiseSocket.read()
expect(content.toString().trim()).toBe('220 Welcome')

Expand Down
2 changes: 1 addition & 1 deletion test/PASV.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ test('test PASV message takes next free port', async () => {

let promiseSocket = new PromiseSocket(new net.Socket())
let socket = promiseSocket.stream
await socket.connect(cmdPortTCP, 'localhost')
await socket.connect(cmdPortTCP, '127.0.0.1', 'localhost')
content = await promiseSocket.read()
expect(content.toString().trim()).toBe('220 Welcome')

Expand Down
40 changes: 39 additions & 1 deletion test/STOR.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const tls = require('tls')
const {PromiseSocket, TimeoutError} = require('promise-socket')
const { sleep, getCmdPortTCP, getDataPort } = require('./utils')

jest.setTimeout(5000)
jest.setTimeout(7500)
let server, content, dataContent = null
const cmdPortTCP = getCmdPortTCP()
const dataPort = getDataPort()
Expand Down Expand Up @@ -128,6 +128,44 @@ test('test STOR message', async () => {
await promiseSocket.end()
})

test('test STOR message failes due to socket timeout', async () => {
const users = [
{
username: 'john',
allowLoginWithoutPassword: true,
}
]
server = new ftpd({cnf: {port: 50021, user: users, minDataPort: dataPort}})
expect(server).toBeInstanceOf(ftpd)
server.start()

let promiseSocket = new PromiseSocket(new net.Socket())
let socket = promiseSocket.stream
await socket.connect(50021, 'localhost')
content = await promiseSocket.read()
expect(content.toString().trim()).toBe('220 Welcome')

await promiseSocket.write('USER john')
content = await promiseSocket.read()
expect(content.toString().trim()).toBe('232 User logged in')

await promiseSocket.write('STOR ../../mytestfile')
content = await promiseSocket.read()
expect(content.toString().trim()).toBe('550 Transfer failed "../../mytestfile"')

await promiseSocket.write('EPSV')
content = await promiseSocket.read()
expect(content.toString().trim()).toBe(`229 Entering extended passive mode (|||${dataPort}|)`)

let promiseDataSocket = new PromiseSocket(new net.Socket())
let dataSocket = promiseDataSocket.stream
await dataSocket.connect(dataPort, 'localhost')

await sleep(5500)
expect(dataSocket.destroyed).toBe(true)

await promiseSocket.end()
})

test('test STOR message with ASCII', async () => {
const users = [
Expand Down

0 comments on commit e3196c1

Please sign in to comment.