ftpd 1.1.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Changelog.md +15 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +57 -48
- data/README.md +8 -1
- data/VERSION +1 -1
- data/examples/example.rb +12 -0
- data/features/example/step_definitions/example_server.rb +2 -0
- data/features/ftp_server/eprt.feature +1 -0
- data/features/ftp_server/epsv.feature +1 -0
- data/features/ftp_server/get_ipv6.feature +3 -0
- data/features/ftp_server/pasv.feature +10 -3
- data/features/ftp_server/step_definitions/logging.rb +2 -0
- data/features/ftp_server/step_definitions/test_server.rb +6 -0
- data/features/step_definitions/append.rb +2 -0
- data/features/step_definitions/client.rb +3 -0
- data/features/step_definitions/client_and_server_files.rb +2 -0
- data/features/step_definitions/client_files.rb +2 -0
- data/features/step_definitions/command.rb +2 -0
- data/features/step_definitions/connect.rb +2 -0
- data/features/step_definitions/delete.rb +2 -0
- data/features/step_definitions/directory_navigation.rb +2 -0
- data/features/step_definitions/error_replies.rb +2 -0
- data/features/step_definitions/features.rb +2 -0
- data/features/step_definitions/file_structure.rb +2 -0
- data/features/step_definitions/generic_send.rb +2 -0
- data/features/step_definitions/get.rb +2 -0
- data/features/step_definitions/help.rb +2 -0
- data/features/step_definitions/invalid_commands.rb +2 -0
- data/features/step_definitions/ipv6.rb +11 -0
- data/features/step_definitions/line_endings.rb +2 -0
- data/features/step_definitions/list.rb +2 -0
- data/features/step_definitions/login.rb +2 -0
- data/features/step_definitions/mkdir.rb +2 -0
- data/features/step_definitions/mode.rb +2 -0
- data/features/step_definitions/mtime.rb +2 -0
- data/features/step_definitions/noop.rb +2 -0
- data/features/step_definitions/options.rb +2 -0
- data/features/step_definitions/passive.rb +7 -0
- data/features/step_definitions/pending.rb +2 -0
- data/features/step_definitions/port.rb +2 -0
- data/features/step_definitions/put.rb +2 -0
- data/features/step_definitions/quit.rb +2 -0
- data/features/step_definitions/rename.rb +2 -0
- data/features/step_definitions/rmdir.rb +2 -0
- data/features/step_definitions/server_files.rb +2 -0
- data/features/step_definitions/server_title.rb +2 -0
- data/features/step_definitions/size.rb +2 -0
- data/features/step_definitions/status.rb +2 -0
- data/features/step_definitions/success_replies.rb +2 -0
- data/features/step_definitions/system.rb +5 -0
- data/features/step_definitions/timing.rb +2 -0
- data/features/step_definitions/type.rb +2 -0
- data/features/support/env.rb +2 -0
- data/features/support/example_server.rb +3 -1
- data/features/support/test_client.rb +27 -19
- data/features/support/test_file_templates.rb +2 -0
- data/features/support/test_server.rb +31 -20
- data/features/support/test_server_files.rb +2 -0
- data/ftpd.gemspec +17 -11
- data/lib/ftpd.rb +2 -0
- data/lib/ftpd/auth_levels.rb +2 -0
- data/lib/ftpd/cmd_abor.rb +2 -0
- data/lib/ftpd/cmd_allo.rb +2 -0
- data/lib/ftpd/cmd_appe.rb +2 -0
- data/lib/ftpd/cmd_auth.rb +2 -0
- data/lib/ftpd/cmd_cdup.rb +2 -0
- data/lib/ftpd/cmd_cwd.rb +2 -0
- data/lib/ftpd/cmd_dele.rb +2 -0
- data/lib/ftpd/cmd_eprt.rb +2 -0
- data/lib/ftpd/cmd_epsv.rb +4 -2
- data/lib/ftpd/cmd_feat.rb +2 -0
- data/lib/ftpd/cmd_help.rb +2 -0
- data/lib/ftpd/cmd_list.rb +2 -0
- data/lib/ftpd/cmd_login.rb +2 -0
- data/lib/ftpd/cmd_mdtm.rb +2 -0
- data/lib/ftpd/cmd_mkd.rb +2 -0
- data/lib/ftpd/cmd_mode.rb +2 -0
- data/lib/ftpd/cmd_nlst.rb +2 -0
- data/lib/ftpd/cmd_noop.rb +2 -0
- data/lib/ftpd/cmd_opts.rb +2 -0
- data/lib/ftpd/cmd_pasv.rb +5 -3
- data/lib/ftpd/cmd_pbsz.rb +2 -0
- data/lib/ftpd/cmd_port.rb +2 -0
- data/lib/ftpd/cmd_prot.rb +2 -0
- data/lib/ftpd/cmd_pwd.rb +2 -0
- data/lib/ftpd/cmd_quit.rb +2 -0
- data/lib/ftpd/cmd_rein.rb +2 -0
- data/lib/ftpd/cmd_rename.rb +2 -0
- data/lib/ftpd/cmd_rest.rb +2 -0
- data/lib/ftpd/cmd_retr.rb +2 -0
- data/lib/ftpd/cmd_rmd.rb +2 -0
- data/lib/ftpd/cmd_site.rb +2 -0
- data/lib/ftpd/cmd_size.rb +2 -0
- data/lib/ftpd/cmd_smnt.rb +2 -0
- data/lib/ftpd/cmd_stat.rb +2 -0
- data/lib/ftpd/cmd_stor.rb +2 -0
- data/lib/ftpd/cmd_stou.rb +2 -0
- data/lib/ftpd/cmd_stru.rb +2 -0
- data/lib/ftpd/cmd_syst.rb +2 -0
- data/lib/ftpd/cmd_type.rb +2 -0
- data/lib/ftpd/command_handler.rb +3 -0
- data/lib/ftpd/command_handler_factory.rb +2 -0
- data/lib/ftpd/command_handlers.rb +2 -0
- data/lib/ftpd/command_loop.rb +2 -0
- data/lib/ftpd/command_sequence_checker.rb +2 -0
- data/lib/ftpd/config.rb +2 -0
- data/lib/ftpd/connection_throttle.rb +2 -0
- data/lib/ftpd/connection_tracker.rb +2 -0
- data/lib/ftpd/data_connection_helper.rb +2 -0
- data/lib/ftpd/data_server_factory.rb +44 -0
- data/lib/ftpd/data_server_factory/random_ephemeral_port.rb +26 -0
- data/lib/ftpd/data_server_factory/specific_port_range.rb +37 -0
- data/lib/ftpd/disk_file_system.rb +2 -0
- data/lib/ftpd/error.rb +2 -0
- data/lib/ftpd/exception_translator.rb +2 -0
- data/lib/ftpd/exceptions.rb +2 -0
- data/lib/ftpd/file_info.rb +2 -0
- data/lib/ftpd/file_system_helper.rb +2 -0
- data/lib/ftpd/ftp_server.rb +27 -0
- data/lib/ftpd/gets_peer_address.rb +2 -0
- data/lib/ftpd/insecure_certificate.rb +2 -0
- data/lib/ftpd/list_format/eplf.rb +2 -0
- data/lib/ftpd/list_format/ls.rb +2 -0
- data/lib/ftpd/list_path.rb +2 -0
- data/lib/ftpd/null_logger.rb +2 -0
- data/lib/ftpd/protocols.rb +2 -0
- data/lib/ftpd/read_only_disk_file_system.rb +2 -0
- data/lib/ftpd/server.rb +2 -0
- data/lib/ftpd/session.rb +7 -0
- data/lib/ftpd/session_config.rb +26 -2
- data/lib/ftpd/stream.rb +2 -0
- data/lib/ftpd/telnet.rb +3 -2
- data/lib/ftpd/temp_dir.rb +2 -0
- data/lib/ftpd/tls_server.rb +2 -0
- data/lib/ftpd/translate_exceptions.rb +2 -0
- data/spec/command_sequence_checker_spec.rb +2 -0
- data/spec/connection_throttle_spec.rb +2 -0
- data/spec/connection_tracker_spec.rb +2 -0
- data/spec/data_server_factory_spec.rb +104 -0
- data/spec/disk_file_system_spec.rb +2 -0
- data/spec/exception_translator_spec.rb +2 -0
- data/spec/file_info_spec.rb +2 -0
- data/spec/ftp_server_error_spec.rb +2 -0
- data/spec/list_format/eplf_spec.rb +2 -0
- data/spec/list_format/ls_spec.rb +2 -0
- data/spec/list_path_spec.rb +2 -0
- data/spec/null_logger_spec.rb +2 -0
- data/spec/protocols_spec.rb +58 -38
- data/spec/server_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/telnet_spec.rb +2 -0
- data/spec/translate_exceptions_spec.rb +2 -0
- data/testlib/network.rb +17 -0
- metadata +13 -7
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
module Ftpd
|
6
|
+
describe DataServerFactory do
|
7
|
+
|
8
|
+
it "creates a socket bound to 127.0.0.1" do
|
9
|
+
factory = DataServerFactory.make("127.0.0.1", nil)
|
10
|
+
tcp_server = factory.make_tcp_server
|
11
|
+
expect(tcp_server.addr[3]).to eq "127.0.0.1"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "creates a socket bound to 127.0.0.2" do
|
15
|
+
factory = DataServerFactory.make("127.0.0.2", nil)
|
16
|
+
tcp_server = factory.make_tcp_server
|
17
|
+
expect(tcp_server.addr[3]).to eq "127.0.0.2"
|
18
|
+
end
|
19
|
+
|
20
|
+
context "with no port range" do
|
21
|
+
|
22
|
+
it "creates a socket bound to an ephemeral port" do
|
23
|
+
interface = "0.0.0.0"
|
24
|
+
factory = DataServerFactory.make(interface, nil)
|
25
|
+
ports = (1..10).map do
|
26
|
+
tcp_server = factory.make_tcp_server
|
27
|
+
begin
|
28
|
+
tcp_server.addr[1]
|
29
|
+
ensure
|
30
|
+
tcp_server.close
|
31
|
+
end
|
32
|
+
end
|
33
|
+
expect(ports.uniq.size).to be > 1
|
34
|
+
ports.each do |port|
|
35
|
+
expect(port).to be_between(1024, 65535)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
context "with a port range" do
|
42
|
+
|
43
|
+
let(:interface) { "127.0.0.1" }
|
44
|
+
|
45
|
+
def get_unused_port
|
46
|
+
server = TCPServer.new(interface, 0)
|
47
|
+
port = server.addr[1]
|
48
|
+
server.close
|
49
|
+
port
|
50
|
+
end
|
51
|
+
|
52
|
+
def use_port(port)
|
53
|
+
server = TCPServer.new(interface, port)
|
54
|
+
begin
|
55
|
+
yield
|
56
|
+
ensure
|
57
|
+
server.close
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "creates a socket bound to an ephemeral port" do
|
62
|
+
ports = (1..10).map { get_unused_port }
|
63
|
+
factory = DataServerFactory.make(interface, ports)
|
64
|
+
10.times do
|
65
|
+
tcp_server = factory.make_tcp_server
|
66
|
+
begin
|
67
|
+
port = tcp_server.addr[1]
|
68
|
+
expect(ports).to include(port)
|
69
|
+
ensure
|
70
|
+
tcp_server.close
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it "skips a port that is already in use" do
|
76
|
+
ports = (1..2).map { get_unused_port }
|
77
|
+
use_port(ports[0]) do
|
78
|
+
factory = DataServerFactory.make(interface, ports)
|
79
|
+
10.times do
|
80
|
+
tcp_server = factory.make_tcp_server
|
81
|
+
begin
|
82
|
+
port = tcp_server.addr[1]
|
83
|
+
expect(port).to eq ports[1]
|
84
|
+
ensure
|
85
|
+
tcp_server.close
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "uses a random ephemeral port when all configured ports are in use" do
|
92
|
+
ports = [ get_unused_port ]
|
93
|
+
use_port(ports[0]) do
|
94
|
+
factory = DataServerFactory.make(interface, ports)
|
95
|
+
tcp_server = factory.make_tcp_server
|
96
|
+
port = tcp_server.addr[1]
|
97
|
+
expect(port).to_not eq ports[0]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
data/spec/file_info_spec.rb
CHANGED
data/spec/list_format/ls_spec.rb
CHANGED
data/spec/list_path_spec.rb
CHANGED
data/spec/null_logger_spec.rb
CHANGED
data/spec/protocols_spec.rb
CHANGED
@@ -1,10 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
4
|
|
5
|
+
require_relative "../testlib/network"
|
6
|
+
|
3
7
|
module Ftpd
|
4
8
|
describe Protocols do
|
5
9
|
|
6
|
-
|
10
|
+
extend TestLib::Network
|
11
|
+
|
12
|
+
def self.if_stack_supports_ipv6
|
13
|
+
if ipv6_supported?
|
14
|
+
return yield
|
15
|
+
else
|
16
|
+
if !@ipv6_warning_issued
|
17
|
+
warn "Stack does not support IPV6; skipping some tests"
|
18
|
+
@ipv6_warning_issued = true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
7
22
|
|
23
|
+
# A fake server that returns a connected server-side socket.
|
8
24
|
class TestServer
|
9
25
|
|
10
26
|
# The socket upon which the server is listening
|
@@ -58,29 +74,31 @@ module Ftpd
|
|
58
74
|
|
59
75
|
end
|
60
76
|
|
61
|
-
|
77
|
+
if_stack_supports_ipv6 do
|
78
|
+
context 'IPV6 server, IPV6 connection' do
|
62
79
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
80
|
+
let(:bind_address) {'::1'}
|
81
|
+
let(:connect_address) {'::1'}
|
82
|
+
let(:connected_socket) do
|
83
|
+
TestServer.new(bind_address, connect_address).connected_socket
|
84
|
+
end
|
85
|
+
subject(:protocols) {Protocols.new(connected_socket)}
|
69
86
|
|
70
|
-
|
71
|
-
|
72
|
-
|
87
|
+
it 'should not support IPV4' do
|
88
|
+
expect(protocols.supports_protocol?(Protocols::IPV4)).to be_falsey
|
89
|
+
end
|
73
90
|
|
74
|
-
|
75
|
-
|
76
|
-
|
91
|
+
it 'should support IPV6' do
|
92
|
+
expect(protocols.supports_protocol?(Protocols::IPV6)).to be_truthy
|
93
|
+
end
|
77
94
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
95
|
+
it 'should list the supported protocols' do
|
96
|
+
expect(protocols.protocol_codes).to eq [
|
97
|
+
Protocols::IPV6,
|
98
|
+
]
|
99
|
+
end
|
83
100
|
|
101
|
+
end
|
84
102
|
end
|
85
103
|
|
86
104
|
context 'wildcard server, IPV4 connection' do
|
@@ -109,30 +127,32 @@ module Ftpd
|
|
109
127
|
|
110
128
|
end
|
111
129
|
|
112
|
-
|
130
|
+
if_stack_supports_ipv6 do
|
131
|
+
context 'wildcard server, IPV6 connection' do
|
113
132
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
133
|
+
let(:bind_address) {'::'}
|
134
|
+
let(:connect_address) {'::1'}
|
135
|
+
let(:connected_socket) do
|
136
|
+
TestServer.new(bind_address, connect_address).connected_socket
|
137
|
+
end
|
138
|
+
subject(:protocols) {Protocols.new(connected_socket)}
|
120
139
|
|
121
|
-
|
122
|
-
|
123
|
-
|
140
|
+
it 'should support IPV4' do
|
141
|
+
expect(protocols.supports_protocol?(Protocols::IPV4)).to be_truthy
|
142
|
+
end
|
124
143
|
|
125
|
-
|
126
|
-
|
127
|
-
|
144
|
+
it 'should support IPV6' do
|
145
|
+
expect(protocols.supports_protocol?(Protocols::IPV6)).to be_truthy
|
146
|
+
end
|
128
147
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
148
|
+
it 'should list the supported protocols' do
|
149
|
+
expect(protocols.protocol_codes).to eq [
|
150
|
+
Protocols::IPV4,
|
151
|
+
Protocols::IPV6,
|
152
|
+
]
|
153
|
+
end
|
135
154
|
|
155
|
+
end
|
136
156
|
end
|
137
157
|
|
138
158
|
end
|
data/spec/server_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
data/spec/telnet_spec.rb
CHANGED
data/testlib/network.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ftpd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wayne Conrad
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: memoizer
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '2.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '2.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: double-bag-ftps
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '11.1'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '11.1'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: redcarpet
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -247,6 +247,7 @@ files:
|
|
247
247
|
- features/step_definitions/get.rb
|
248
248
|
- features/step_definitions/help.rb
|
249
249
|
- features/step_definitions/invalid_commands.rb
|
250
|
+
- features/step_definitions/ipv6.rb
|
250
251
|
- features/step_definitions/line_endings.rb
|
251
252
|
- features/step_definitions/list.rb
|
252
253
|
- features/step_definitions/login.rb
|
@@ -331,6 +332,9 @@ files:
|
|
331
332
|
- lib/ftpd/connection_throttle.rb
|
332
333
|
- lib/ftpd/connection_tracker.rb
|
333
334
|
- lib/ftpd/data_connection_helper.rb
|
335
|
+
- lib/ftpd/data_server_factory.rb
|
336
|
+
- lib/ftpd/data_server_factory/random_ephemeral_port.rb
|
337
|
+
- lib/ftpd/data_server_factory/specific_port_range.rb
|
334
338
|
- lib/ftpd/disk_file_system.rb
|
335
339
|
- lib/ftpd/error.rb
|
336
340
|
- lib/ftpd/exception_translator.rb
|
@@ -363,6 +367,7 @@ files:
|
|
363
367
|
- spec/command_sequence_checker_spec.rb
|
364
368
|
- spec/connection_throttle_spec.rb
|
365
369
|
- spec/connection_tracker_spec.rb
|
370
|
+
- spec/data_server_factory_spec.rb
|
366
371
|
- spec/disk_file_system_spec.rb
|
367
372
|
- spec/exception_translator_spec.rb
|
368
373
|
- spec/file_info_spec.rb
|
@@ -376,6 +381,7 @@ files:
|
|
376
381
|
- spec/spec_helper.rb
|
377
382
|
- spec/telnet_spec.rb
|
378
383
|
- spec/translate_exceptions_spec.rb
|
384
|
+
- testlib/network.rb
|
379
385
|
homepage: http://github.com/wconrad/ftpd
|
380
386
|
licenses:
|
381
387
|
- MIT
|
@@ -396,7 +402,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
396
402
|
version: '0'
|
397
403
|
requirements: []
|
398
404
|
rubyforge_project:
|
399
|
-
rubygems_version: 2.4.
|
405
|
+
rubygems_version: 2.4.8
|
400
406
|
signing_key:
|
401
407
|
specification_version: 4
|
402
408
|
summary: Pure Ruby FTP server library
|