ftpd 0.3.2 → 0.4.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.
- data/.yardopts +1 -0
- data/Changelog.md +25 -1
- data/README.md +91 -10
- data/VERSION +1 -1
- data/doc/rfc-compliance.md +20 -20
- data/examples/example.rb +69 -11
- data/features/example/read_only.feature +63 -0
- data/features/ftp_server/append.feature +94 -0
- data/features/ftp_server/command_errors.feature +0 -2
- data/features/ftp_server/concurrent_sessions.feature +1 -1
- data/features/ftp_server/debug.feature +4 -2
- data/features/ftp_server/delete.feature +1 -1
- data/features/ftp_server/get.feature +1 -1
- data/features/ftp_server/get_tls.feature +2 -1
- data/features/ftp_server/implicit_tls.feature +2 -1
- data/features/ftp_server/invertability.feature +15 -0
- data/features/ftp_server/list.feature +1 -1
- data/features/ftp_server/list_tls.feature +2 -1
- data/features/ftp_server/login_auth_level_account.feature +51 -0
- data/features/ftp_server/{login.feature → login_auth_level_password.feature} +4 -8
- data/features/ftp_server/login_auth_level_user.feature +31 -0
- data/features/ftp_server/mkdir.feature +1 -1
- data/features/ftp_server/name_list.feature +1 -1
- data/features/ftp_server/name_list_tls.feature +2 -1
- data/features/ftp_server/put.feature +1 -1
- data/features/ftp_server/put_tls.feature +2 -1
- data/features/ftp_server/put_unique.feature +1 -1
- data/features/ftp_server/rename.feature +1 -1
- data/features/ftp_server/rmdir.feature +1 -1
- data/features/ftp_server/step_definitions/debug.rb +1 -1
- data/features/ftp_server/step_definitions/test_server.rb +16 -15
- data/features/ftp_server/type.feature +11 -8
- data/features/step_definitions/append.rb +15 -0
- data/features/step_definitions/client_and_server_files.rb +2 -2
- data/features/step_definitions/client_files.rb +5 -0
- data/features/step_definitions/connect.rb +1 -1
- data/features/step_definitions/error_replies.rb +0 -4
- data/features/step_definitions/login.rb +30 -20
- data/features/step_definitions/server_files.rb +20 -7
- data/features/support/example_server.rb +10 -2
- data/features/support/test_client.rb +18 -0
- data/features/support/test_file_templates.rb +1 -1
- data/features/support/test_server.rb +25 -4
- data/ftpd.gemspec +11 -3
- data/lib/ftpd.rb +2 -0
- data/lib/ftpd/auth_levels.rb +9 -0
- data/lib/ftpd/disk_file_system.rb +48 -19
- data/lib/ftpd/ftp_server.rb +13 -10
- data/lib/ftpd/read_only_disk_file_system.rb +22 -0
- data/lib/ftpd/session.rb +62 -29
- data/spec/disk_file_system_spec.rb +30 -0
- metadata +12 -4
@@ -0,0 +1,94 @@
|
|
1
|
+
Feature: Append
|
2
|
+
|
3
|
+
As a client
|
4
|
+
I want to append to a file
|
5
|
+
Because it is a log
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given the test server is started
|
9
|
+
|
10
|
+
Scenario: ASCII file with *nix line endings
|
11
|
+
Given a successful login
|
12
|
+
And the server has file "foo"
|
13
|
+
And the client has file "ascii_unix"
|
14
|
+
When the client successfully appends text "ascii_unix" onto "foo"
|
15
|
+
Then the remote file "foo" should match "foo" + "ascii_unix"
|
16
|
+
|
17
|
+
Scenario: ASCII file with windows line endings
|
18
|
+
Given a successful login
|
19
|
+
And the server has file "foo"
|
20
|
+
And the client has file "ascii_windows"
|
21
|
+
When the client successfully appends text "ascii_windows" onto "foo"
|
22
|
+
Then the remote file "foo" should match "foo" + "ascii_unix"
|
23
|
+
|
24
|
+
Scenario: Binary file
|
25
|
+
Given a successful login
|
26
|
+
And the server has file "foo"
|
27
|
+
And the client has file "binary"
|
28
|
+
When the client successfully appends binary "binary" onto "foo"
|
29
|
+
Then the remote file "foo" should match "foo" + "binary"
|
30
|
+
|
31
|
+
Scenario: Passive
|
32
|
+
Given a successful login
|
33
|
+
And the server has file "foo"
|
34
|
+
And the client has file "binary"
|
35
|
+
And the client is in passive mode
|
36
|
+
When the client successfully appends binary "binary" onto "foo"
|
37
|
+
Then the remote file "foo" should match "foo" + "binary"
|
38
|
+
|
39
|
+
Scenario: Destination missing
|
40
|
+
Given a successful login
|
41
|
+
And the client has file "binary"
|
42
|
+
When the client successfully appends binary "binary" onto "foo"
|
43
|
+
Then the remote file "foo" should match "binary"
|
44
|
+
|
45
|
+
Scenario: Subdir
|
46
|
+
Given a successful login
|
47
|
+
And the server has file "subdir/foo"
|
48
|
+
And the client has file "binary"
|
49
|
+
When the client successfully appends binary "binary" onto "subdir/foo"
|
50
|
+
Then the remote file "subdir/foo" should match "foo" + "binary"
|
51
|
+
|
52
|
+
Scenario: Non-root working directory
|
53
|
+
Given a successful login
|
54
|
+
And the server has file "subdir/foo"
|
55
|
+
And the client has file "binary"
|
56
|
+
And the client successfully cd's to "subdir"
|
57
|
+
When the client successfully appends binary "binary" onto "foo"
|
58
|
+
Then the remote file "subdir/foo" should match "foo" + "binary"
|
59
|
+
|
60
|
+
Scenario: Access denied
|
61
|
+
Given a successful login
|
62
|
+
And the client has file "foo"
|
63
|
+
When the client appends binary "foo" onto "forbidden"
|
64
|
+
Then the server returns an access denied error
|
65
|
+
|
66
|
+
Scenario: Missing directory
|
67
|
+
Given a successful login
|
68
|
+
And the client has file "binary"
|
69
|
+
When the client appends binary "binary" onto "subdir/foo"
|
70
|
+
Then the server returns a not found error
|
71
|
+
|
72
|
+
Scenario: Not logged in
|
73
|
+
Given a successful connection
|
74
|
+
And the client has file "foo"
|
75
|
+
When the client appends binary "foo" onto "foo"
|
76
|
+
Then the server returns a not logged in error
|
77
|
+
|
78
|
+
Scenario: Missing path
|
79
|
+
Given a successful login
|
80
|
+
When the client sends "APPE"
|
81
|
+
Then the server returns a syntax error
|
82
|
+
|
83
|
+
Scenario: File system error
|
84
|
+
Given a successful login
|
85
|
+
And the client has file "foo"
|
86
|
+
When the client appends text "foo" onto "unable"
|
87
|
+
Then the server returns an action not taken error
|
88
|
+
|
89
|
+
Scenario: Append not enabled
|
90
|
+
Given the test server lacks append
|
91
|
+
And a successful login
|
92
|
+
And the client has file "foo"
|
93
|
+
When the client appends text "foo" onto "bar"
|
94
|
+
Then the server returns an unimplemented command error
|
@@ -5,11 +5,13 @@ Feature: Debug
|
|
5
5
|
So that I can fix FTP protocol problems
|
6
6
|
|
7
7
|
Scenario: Debug enabled
|
8
|
-
Given the test server
|
8
|
+
Given the test server has debug enabled
|
9
|
+
And the test server is started
|
9
10
|
And a successful login
|
10
11
|
Then the server should have written debug output
|
11
12
|
|
12
13
|
Scenario: Debug disabled
|
13
|
-
Given the test server
|
14
|
+
Given the test server has debug disabled
|
15
|
+
And the test server is started
|
14
16
|
And a successful login
|
15
17
|
Then the server should have written no debug output
|
@@ -53,7 +53,7 @@ Feature: Delete
|
|
53
53
|
Then the server returns a not logged in error
|
54
54
|
|
55
55
|
Scenario: Delete not enabled
|
56
|
-
Given the test server
|
56
|
+
Given the test server lacks delete
|
57
57
|
And a successful login
|
58
58
|
And the server has file "foo"
|
59
59
|
When the client deletes "foo"
|
@@ -73,7 +73,7 @@ Feature: Get
|
|
73
73
|
Then the server returns an action not taken error
|
74
74
|
|
75
75
|
Scenario: Read not enabled
|
76
|
-
Given the test server
|
76
|
+
Given the test server lacks read
|
77
77
|
And a successful login
|
78
78
|
And the server has file "foo"
|
79
79
|
When the client gets text "foo"
|
@@ -5,7 +5,8 @@ Feature: Get TLS
|
|
5
5
|
So that I have it on my computer
|
6
6
|
|
7
7
|
Background:
|
8
|
-
Given the test server
|
8
|
+
Given the test server has TLS mode "explicit"
|
9
|
+
And the test server is started
|
9
10
|
|
10
11
|
Scenario: TLS
|
11
12
|
pending "TLS not supported in active mode (see README)"
|
@@ -5,7 +5,8 @@ Feature: Put TLS
|
|
5
5
|
Because I must serve out-of-date clients
|
6
6
|
|
7
7
|
Background:
|
8
|
-
Given the test server
|
8
|
+
Given the test server has TLS mode "implicit"
|
9
|
+
And the test server is started
|
9
10
|
|
10
11
|
Scenario: Get
|
11
12
|
pending "TLS not supported in active mode (see README)"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Get
|
2
|
+
|
3
|
+
As a client
|
4
|
+
I want a file to be the same when I get it as it was when I put it
|
5
|
+
So that I can use the FTP server for storage
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given the test server is started
|
9
|
+
|
10
|
+
Scenario: Binary file
|
11
|
+
Given a successful login
|
12
|
+
And the client has file "binary"
|
13
|
+
When the client successfully puts binary "binary"
|
14
|
+
And the client successfully gets binary "binary"
|
15
|
+
Then the local file "binary" should match its template
|
@@ -79,7 +79,7 @@ Feature: List
|
|
79
79
|
Then the server returns a not logged in error
|
80
80
|
|
81
81
|
Scenario: List not enabled
|
82
|
-
Given the test server
|
82
|
+
Given the test server lacks list
|
83
83
|
And a successful login
|
84
84
|
When the client lists the directory
|
85
85
|
Then the server returns an unimplemented command error
|
@@ -5,7 +5,8 @@ Feature: List TLS
|
|
5
5
|
So that I can see what file to transfer
|
6
6
|
|
7
7
|
Background:
|
8
|
-
Given the test server
|
8
|
+
Given the test server has TLS mode "explicit"
|
9
|
+
And the test server is started
|
9
10
|
|
10
11
|
Scenario: TLS
|
11
12
|
pending "TLS not supported in active mode (see README)"
|
@@ -0,0 +1,51 @@
|
|
1
|
+
Feature: Login
|
2
|
+
|
3
|
+
As a client
|
4
|
+
I want to log in
|
5
|
+
So that I can transfer files
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given the test server has auth level "AUTH_ACCOUNT"
|
9
|
+
And the test server is started
|
10
|
+
|
11
|
+
Scenario: Normal connection
|
12
|
+
Given a successful login
|
13
|
+
Then the server returns no error
|
14
|
+
And the client should be logged in
|
15
|
+
|
16
|
+
Scenario: Bad user
|
17
|
+
Given the client connects
|
18
|
+
When the client logs in with bad user
|
19
|
+
Then the server returns a login incorrect error
|
20
|
+
And the client should not be logged in
|
21
|
+
|
22
|
+
Scenario: Bad password
|
23
|
+
Given a successful connection
|
24
|
+
When the client logs in with bad password
|
25
|
+
Then the server returns a login incorrect error
|
26
|
+
And the client should not be logged in
|
27
|
+
|
28
|
+
Scenario: Bad account
|
29
|
+
Given a successful connection
|
30
|
+
When the client logs in with bad account
|
31
|
+
Then the server returns a login incorrect error
|
32
|
+
And the client should not be logged in
|
33
|
+
|
34
|
+
Scenario: ACCT without parameter
|
35
|
+
Given a successful connection
|
36
|
+
And the client sends a user
|
37
|
+
And the client sends a password
|
38
|
+
When the client sends "ACCT"
|
39
|
+
Then the server returns a syntax error
|
40
|
+
|
41
|
+
Scenario: PASS not followed by ACCT
|
42
|
+
Given a successful connection
|
43
|
+
And the client sends a user
|
44
|
+
And the client sends a password
|
45
|
+
When the client sends "NOOP"
|
46
|
+
Then the server returns a bad sequence error
|
47
|
+
|
48
|
+
Scenario: ACCT out of sequence
|
49
|
+
Given a successful connection
|
50
|
+
When the client sends "ACCT"
|
51
|
+
Then the server returns a bad sequence error
|
@@ -5,7 +5,8 @@ Feature: Login
|
|
5
5
|
So that I can transfer files
|
6
6
|
|
7
7
|
Background:
|
8
|
-
Given the test server
|
8
|
+
Given the test server has auth level "AUTH_PASSWORD"
|
9
|
+
And the test server is started
|
9
10
|
|
10
11
|
Scenario: Normal connection
|
11
12
|
Given a successful login
|
@@ -14,13 +15,13 @@ Feature: Login
|
|
14
15
|
|
15
16
|
Scenario: Bad user
|
16
17
|
Given the client connects
|
17
|
-
When the client logs in with
|
18
|
+
When the client logs in with bad user
|
18
19
|
Then the server returns a login incorrect error
|
19
20
|
And the client should not be logged in
|
20
21
|
|
21
22
|
Scenario: Bad password
|
22
23
|
Given a successful connection
|
23
|
-
When the client logs in with
|
24
|
+
When the client logs in with bad password
|
24
25
|
Then the server returns a login incorrect error
|
25
26
|
And the client should not be logged in
|
26
27
|
|
@@ -51,11 +52,6 @@ Feature: Login
|
|
51
52
|
When the client sends a password with no parameter
|
52
53
|
Then the server returns a syntax error
|
53
54
|
|
54
|
-
Scenario: USER without parameter
|
55
|
-
Given a successful connection
|
56
|
-
And the client sends a user with no parameter
|
57
|
-
Then the server returns a syntax error
|
58
|
-
|
59
55
|
Scenario: USER not followed by PASS
|
60
56
|
Given a successful connection
|
61
57
|
And the client sends a user
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Feature: Login
|
2
|
+
|
3
|
+
As a client
|
4
|
+
I want to log in
|
5
|
+
So that I can transfer files
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given the test server has auth level "AUTH_USER"
|
9
|
+
And the test server is started
|
10
|
+
|
11
|
+
Scenario: Normal connection
|
12
|
+
Given a successful login
|
13
|
+
Then the server returns no error
|
14
|
+
And the client should be logged in
|
15
|
+
|
16
|
+
Scenario: Bad user
|
17
|
+
Given the client connects
|
18
|
+
When the client logs in with bad user
|
19
|
+
Then the server returns a login incorrect error
|
20
|
+
And the client should not be logged in
|
21
|
+
|
22
|
+
Scenario: Already logged in
|
23
|
+
Given a successful login
|
24
|
+
When the client logs in
|
25
|
+
Then the server returns a bad sequence error
|
26
|
+
And the client should be logged in
|
27
|
+
|
28
|
+
Scenario: USER without parameter
|
29
|
+
Given a successful connection
|
30
|
+
And the client sends a user with no parameter
|
31
|
+
Then the server returns a syntax error
|
@@ -53,7 +53,7 @@ Feature: Make directory
|
|
53
53
|
Then the server returns a not a directory error
|
54
54
|
|
55
55
|
Scenario: Mkdir not enabled
|
56
|
-
Given the test server
|
56
|
+
Given the test server lacks mkdir
|
57
57
|
And a successful login
|
58
58
|
When the client makes directory "foo"
|
59
59
|
Then the server returns an unimplemented command error
|
@@ -62,7 +62,7 @@ Feature: Name List
|
|
62
62
|
Then the server returns a not logged in error
|
63
63
|
|
64
64
|
Scenario: List not enabled
|
65
|
-
Given the test server
|
65
|
+
Given the test server lacks list
|
66
66
|
And a successful login
|
67
67
|
When the client name-lists the directory
|
68
68
|
Then the server returns an unimplemented command error
|
@@ -6,7 +6,8 @@ Feature: Name List TLS
|
|
6
6
|
And nobody else can
|
7
7
|
|
8
8
|
Background:
|
9
|
-
Given the test server
|
9
|
+
Given the test server has TLS mode "explicit"
|
10
|
+
And the test server is started
|
10
11
|
|
11
12
|
Scenario: TLS
|
12
13
|
pending "TLS not supported in active mode (see README)"
|
@@ -72,7 +72,7 @@ Feature: Put
|
|
72
72
|
Then the server returns an action not taken error
|
73
73
|
|
74
74
|
Scenario: Write not enabled
|
75
|
-
Given the test server
|
75
|
+
Given the test server lacks write
|
76
76
|
And a successful login
|
77
77
|
And the client has file "foo"
|
78
78
|
When the client puts text "foo"
|
@@ -5,7 +5,8 @@ Feature: Put TLS
|
|
5
5
|
So that nobody can intercept it
|
6
6
|
|
7
7
|
Background:
|
8
|
-
Given the test server
|
8
|
+
Given the test server has TLS mode "explicit"
|
9
|
+
And the test server is started
|
9
10
|
|
10
11
|
Scenario: TLS
|
11
12
|
pending "TLS not supported in active mode (see README)"
|
@@ -49,7 +49,7 @@ Feature: Put Unique
|
|
49
49
|
Then the server returns a not logged in error
|
50
50
|
|
51
51
|
Scenario: Write not enabled
|
52
|
-
Given the test server
|
52
|
+
Given the test server lacks write
|
53
53
|
And a successful login
|
54
54
|
And the client has file "foo"
|
55
55
|
When the client stores unique "foo"
|
@@ -78,7 +78,7 @@ Feature: Rename
|
|
78
78
|
Then the server returns a syntax error
|
79
79
|
|
80
80
|
Scenario: Rename not enabled
|
81
|
-
Given the test server
|
81
|
+
Given the test server lacks rename
|
82
82
|
And a successful login
|
83
83
|
And the server has file "foo"
|
84
84
|
When the client renames "foo" to "bar"
|
@@ -55,7 +55,7 @@ Feature: Remove directory
|
|
55
55
|
Then the server returns a not a directory error
|
56
56
|
|
57
57
|
Scenario: Rmdir not enabled
|
58
|
-
Given the test server
|
58
|
+
Given the test server lacks rmdir
|
59
59
|
And a successful login
|
60
60
|
When the client removes directory "foo"
|
61
61
|
Then the server returns an unimplemented command error
|
@@ -1,23 +1,24 @@
|
|
1
|
+
def server
|
2
|
+
@server ||= TestServer.new
|
3
|
+
end
|
4
|
+
|
1
5
|
Given /^the test server is started$/ do
|
2
|
-
|
3
|
-
|
6
|
+
server.start
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /^the test server has TLS mode "(\w+)"$/ do |mode|
|
10
|
+
server.tls = mode.to_sym
|
4
11
|
end
|
5
12
|
|
6
|
-
Given /^the test server
|
7
|
-
|
8
|
-
@server = TestServer.new
|
9
|
-
@server.tls = mode.to_sym
|
10
|
-
@server.start
|
13
|
+
Given /^the test server has debug (enabled|disabled)$/ do |state|
|
14
|
+
server.debug = state == 'enabled'
|
11
15
|
end
|
12
16
|
|
13
|
-
Given /^the test server
|
14
|
-
|
15
|
-
@server.debug = true
|
16
|
-
@server.start
|
17
|
+
Given /^the test server lacks (\w+)$/ do |feature|
|
18
|
+
server.send "#{feature}=", false
|
17
19
|
end
|
18
20
|
|
19
|
-
Given /^the test server
|
20
|
-
|
21
|
-
|
22
|
-
@server.start
|
21
|
+
Given /^the test server has auth level "(.*?)"$/ do |auth_level|
|
22
|
+
auth_level = Ftpd.const_get(auth_level)
|
23
|
+
server.auth_level = auth_level
|
23
24
|
end
|