ftpd 1.1.1 → 2.0.0
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.
- 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
|