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.
Files changed (52) hide show
  1. data/.yardopts +1 -0
  2. data/Changelog.md +25 -1
  3. data/README.md +91 -10
  4. data/VERSION +1 -1
  5. data/doc/rfc-compliance.md +20 -20
  6. data/examples/example.rb +69 -11
  7. data/features/example/read_only.feature +63 -0
  8. data/features/ftp_server/append.feature +94 -0
  9. data/features/ftp_server/command_errors.feature +0 -2
  10. data/features/ftp_server/concurrent_sessions.feature +1 -1
  11. data/features/ftp_server/debug.feature +4 -2
  12. data/features/ftp_server/delete.feature +1 -1
  13. data/features/ftp_server/get.feature +1 -1
  14. data/features/ftp_server/get_tls.feature +2 -1
  15. data/features/ftp_server/implicit_tls.feature +2 -1
  16. data/features/ftp_server/invertability.feature +15 -0
  17. data/features/ftp_server/list.feature +1 -1
  18. data/features/ftp_server/list_tls.feature +2 -1
  19. data/features/ftp_server/login_auth_level_account.feature +51 -0
  20. data/features/ftp_server/{login.feature → login_auth_level_password.feature} +4 -8
  21. data/features/ftp_server/login_auth_level_user.feature +31 -0
  22. data/features/ftp_server/mkdir.feature +1 -1
  23. data/features/ftp_server/name_list.feature +1 -1
  24. data/features/ftp_server/name_list_tls.feature +2 -1
  25. data/features/ftp_server/put.feature +1 -1
  26. data/features/ftp_server/put_tls.feature +2 -1
  27. data/features/ftp_server/put_unique.feature +1 -1
  28. data/features/ftp_server/rename.feature +1 -1
  29. data/features/ftp_server/rmdir.feature +1 -1
  30. data/features/ftp_server/step_definitions/debug.rb +1 -1
  31. data/features/ftp_server/step_definitions/test_server.rb +16 -15
  32. data/features/ftp_server/type.feature +11 -8
  33. data/features/step_definitions/append.rb +15 -0
  34. data/features/step_definitions/client_and_server_files.rb +2 -2
  35. data/features/step_definitions/client_files.rb +5 -0
  36. data/features/step_definitions/connect.rb +1 -1
  37. data/features/step_definitions/error_replies.rb +0 -4
  38. data/features/step_definitions/login.rb +30 -20
  39. data/features/step_definitions/server_files.rb +20 -7
  40. data/features/support/example_server.rb +10 -2
  41. data/features/support/test_client.rb +18 -0
  42. data/features/support/test_file_templates.rb +1 -1
  43. data/features/support/test_server.rb +25 -4
  44. data/ftpd.gemspec +11 -3
  45. data/lib/ftpd.rb +2 -0
  46. data/lib/ftpd/auth_levels.rb +9 -0
  47. data/lib/ftpd/disk_file_system.rb +48 -19
  48. data/lib/ftpd/ftp_server.rb +13 -10
  49. data/lib/ftpd/read_only_disk_file_system.rb +22 -0
  50. data/lib/ftpd/session.rb +62 -29
  51. data/spec/disk_file_system_spec.rb +30 -0
  52. 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
@@ -19,8 +19,6 @@ Feature: Command Errors
19
19
  Examples:
20
20
  | command |
21
21
  | ABOR |
22
- | ACCT |
23
- | APPE |
24
22
  | REIN |
25
23
  | REST |
26
24
  | SITE |
@@ -1,4 +1,4 @@
1
- Feature: Mode
1
+ Feature: Concurrent Sessions
2
2
 
3
3
  As a client
4
4
  I want to start a session when there is another session
@@ -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 is started with debug
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 is started
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 is started without delete
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 is started without read
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 is started with explicit TLS
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 is started with implicit TLS
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 is started without list
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 is started with explicit TLS
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 is started
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 a bad user
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 a bad password
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 is started without mkdir
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 is started without list
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 is started with explicit TLS
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 is started without write
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 is started with explicit TLS
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 is started without write
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 is started without rename
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 is started without rmdir
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
@@ -4,5 +4,5 @@ Then /^the server should have written( no)? debug output$/ do |neg|
4
4
  else
5
5
  :should_not
6
6
  end
7
- @server.debug_output.send(method) == ''
7
+ server.debug_output.send(method) == ''
8
8
  end
@@ -1,23 +1,24 @@
1
+ def server
2
+ @server ||= TestServer.new
3
+ end
4
+
1
5
  Given /^the test server is started$/ do
2
- @server = TestServer.new
3
- @server.start
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 is started with(?: (\w+) TLS)?$/ do |mode|
7
- mode ||= 'explicit'
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 is started with debug$/ do
14
- @server = TestServer.new
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 is started without (\w+)$/ do |feature|
20
- @server = TestServer.new
21
- @server.send "#{feature}=", false
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