ftpd 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/Changelog.md +25 -3
  2. data/Gemfile +0 -1
  3. data/Gemfile.lock +0 -5
  4. data/README.md +109 -51
  5. data/VERSION +1 -1
  6. data/doc/benchmarks.md +4 -3
  7. data/doc/references.md +1 -1
  8. data/doc/rfc-compliance.md +18 -18
  9. data/examples/example.rb +1 -0
  10. data/features/ftp_server/abort.feature +13 -0
  11. data/features/ftp_server/command_errors.feature +0 -12
  12. data/features/ftp_server/delay_after_failed_login.feature +23 -0
  13. data/features/ftp_server/disconnect_after_failed_logins.feature +25 -0
  14. data/features/ftp_server/features.feature +26 -0
  15. data/features/ftp_server/max_connections.feature +39 -0
  16. data/features/ftp_server/options.feature +17 -0
  17. data/features/ftp_server/put_tls.feature +1 -1
  18. data/features/ftp_server/reinitialize.feature +13 -0
  19. data/features/ftp_server/site.feature +13 -0
  20. data/features/ftp_server/status.feature +1 -2
  21. data/features/ftp_server/step_definitions/test_server.rb +20 -0
  22. data/features/ftp_server/structure_mount.feature +13 -0
  23. data/features/ftp_server/timeout.feature +3 -3
  24. data/features/step_definitions/append.rb +2 -2
  25. data/features/step_definitions/client.rb +19 -9
  26. data/features/step_definitions/client_and_server_files.rb +2 -2
  27. data/features/step_definitions/client_files.rb +4 -4
  28. data/features/step_definitions/command.rb +1 -1
  29. data/features/step_definitions/connect.rb +28 -5
  30. data/features/step_definitions/delete.rb +2 -2
  31. data/features/step_definitions/directory_navigation.rb +4 -4
  32. data/features/step_definitions/error_replies.rb +12 -0
  33. data/features/step_definitions/features.rb +21 -0
  34. data/features/step_definitions/file_structure.rb +2 -2
  35. data/features/step_definitions/generic_send.rb +1 -1
  36. data/features/step_definitions/get.rb +2 -2
  37. data/features/step_definitions/help.rb +1 -1
  38. data/features/step_definitions/invalid_commands.rb +2 -2
  39. data/features/step_definitions/list.rb +2 -2
  40. data/features/step_definitions/login.rb +3 -3
  41. data/features/step_definitions/mkdir.rb +1 -1
  42. data/features/step_definitions/mode.rb +2 -2
  43. data/features/step_definitions/options.rb +9 -0
  44. data/features/step_definitions/passive.rb +1 -1
  45. data/features/step_definitions/port.rb +1 -1
  46. data/features/step_definitions/put.rb +3 -3
  47. data/features/step_definitions/quit.rb +2 -2
  48. data/features/step_definitions/rename.rb +1 -1
  49. data/features/step_definitions/rmdir.rb +1 -1
  50. data/features/step_definitions/server_title.rb +12 -0
  51. data/features/step_definitions/status.rb +1 -9
  52. data/features/step_definitions/system.rb +1 -1
  53. data/features/step_definitions/timing.rb +19 -0
  54. data/features/step_definitions/type.rb +2 -2
  55. data/features/support/test_client.rb +62 -7
  56. data/features/support/test_server.rb +4 -0
  57. data/ftpd.gemspec +21 -9
  58. data/lib/ftpd.rb +4 -0
  59. data/lib/ftpd/command_sequence_checker.rb +4 -2
  60. data/lib/ftpd/config.rb +13 -0
  61. data/lib/ftpd/connection_throttle.rb +56 -0
  62. data/lib/ftpd/connection_tracker.rb +110 -0
  63. data/lib/ftpd/disk_file_system.rb +2 -2
  64. data/lib/ftpd/ftp_server.rb +118 -35
  65. data/lib/ftpd/server.rb +27 -3
  66. data/lib/ftpd/session.rb +84 -25
  67. data/lib/ftpd/tls_server.rb +11 -5
  68. data/rake_tasks/cucumber.rake +1 -0
  69. data/rake_tasks/jeweler.rake +1 -1
  70. data/spec/connection_throttle_spec.rb +96 -0
  71. data/spec/connection_tracker_spec.rb +126 -0
  72. data/spec/spec_helper.rb +1 -0
  73. metadata +22 -23
  74. data/config/cucumber.yml +0 -2
  75. data/features/step_definitions/stop_server.rb +0 -3
  76. data/features/step_definitions/timeout.rb +0 -11
@@ -1,3 +1,25 @@
1
+ ### 0.6.0
2
+
3
+ Enhancements
4
+
5
+ * Configurable maximum connections (defaults to unlimited).
6
+ * Configurable maximum connections per IP (defaults to unlimited).
7
+ * Configurable disconnect after too many failed login attempts
8
+ (defaults to unlimited)
9
+ * Delay after failed login (configurable).
10
+
11
+ API Changes
12
+
13
+ * Changes to {Ftpd::FtpServer} attributes should now only be made
14
+ before calling #start. The effect of setting these attributes
15
+ after #start is undefined.
16
+ * Added {Ftpd::FtpServer#max_connections}
17
+ * Added {Ftpd::FtpServer#max_connections_per_ip}
18
+ * Added {Ftpd::FtpServer#max_failed_logins}
19
+ * Added {Ftpd::FtpServer#failed_login_delay}
20
+ * Support FEAT (feature list)
21
+ * Support OPTS (set options)
22
+
1
23
  ### 0.5.0
2
24
 
3
25
  Bug fixes
@@ -70,10 +92,10 @@ rewritten. It no longer shells out to ls, which removes potential
70
92
  command injection security holes, and improves prospects for
71
93
  portability.
72
94
 
73
- * Removed {Ftpd::DiskFileSystem::Ls}
74
- * Removed {Ftpd::DiskFileSystem::NameList}. NLIST now uses the
95
+ * Removed Ftpd::DiskFileSystem::Ls
96
+ * Removed Ftpd::DiskFileSystem::NameList. NLIST now uses the
75
97
  functions in {Ftpd::DiskFileSystem::List}.
76
- * Removed {Ftpd::DiskFileSystem::List#list}. The formatting of
98
+ * Removed Ftpd::DiskFileSystem::List#list. The formatting of
77
99
  directory output is now done by ftpd, not by the file system driver.
78
100
  * Added {Ftpd::DiskFileSystem::List#file_info}, used by LIST.
79
101
  * Added {Ftpd::DiskFileSystem::List#dir}, used by LIST and NLST.
data/Gemfile CHANGED
@@ -5,7 +5,6 @@ gem 'memoizer', '~> 1.0.1'
5
5
  group :development do
6
6
  gem 'cucumber'
7
7
  gem 'double-bag-ftps', :git => 'git@github.com:wconrad/double-bag-ftps.git'
8
- gem 'fuubar-cucumber'
9
8
  gem 'jeweler'
10
9
  gem 'rake'
11
10
  gem 'redcarpet'
@@ -14,9 +14,6 @@ GEM
14
14
  gherkin (~> 2.11.0)
15
15
  json (>= 1.4.6)
16
16
  diff-lcs (1.2.1)
17
- fuubar-cucumber (0.0.18)
18
- cucumber (~> 1.2.0)
19
- ruby-progressbar (~> 1.0.0)
20
17
  gherkin (2.11.6)
21
18
  json (>= 1.7.6)
22
19
  git (1.2.5)
@@ -39,7 +36,6 @@ GEM
39
36
  rspec-expectations (2.13.0)
40
37
  diff-lcs (>= 1.1.3, < 2.0)
41
38
  rspec-mocks (2.13.0)
42
- ruby-progressbar (1.0.2)
43
39
  timecop (0.5.9.2)
44
40
  yard (0.8.5.2)
45
41
 
@@ -49,7 +45,6 @@ PLATFORMS
49
45
  DEPENDENCIES
50
46
  cucumber
51
47
  double-bag-ftps!
52
- fuubar-cucumber
53
48
  jeweler
54
49
  memoizer (~> 1.0.1)
55
50
  rake
data/README.md CHANGED
@@ -1,18 +1,34 @@
1
- # FTPD
1
+ # Ftpd
2
2
 
3
3
  ftpd is a pure Ruby FTP server library. It supports implicit and
4
4
  explicit TLS, passive and active mode, and is unconditionally
5
- complaint per RFC-1123. It an be used as part of a test fixture or
5
+ compliant per [RFC-1123][1]. It an be used as part of a test fixture or
6
6
  embedded in a program.
7
7
 
8
8
  ## A note about this README
9
9
 
10
- This readme, and the other files, contains Yardoc markup, especially
11
- for links to the API docs; those links don't display properly on
12
- github. You'll find a properly rendered version
13
- [on rubydoc.info](http://rubydoc.info/gems/ftpd)
10
+ This readme, and other files, contains Yardoc markup, especially for
11
+ links to the API docs; those links don't display properly on github.
12
+ You'll find a properly rendered version [on
13
+ rubydoc.info](http://rubydoc.info/gems/ftpd)
14
14
 
15
- ## HELLO WORLD
15
+ ## The state of this library
16
+
17
+ Ftpd has been used for many years to test FTP clients, and is stable
18
+ and reliable for that purpose. However, it was not originally
19
+ intended to be part of a publically accessible FTP server. I would be
20
+ cautious in using it in an untrusted environment due to the
21
+ probability that it contains critical flaws (or even security
22
+ vulnarabilities) that have not been discovered in its use as a test
23
+ harness.
24
+
25
+ In this 0.X.X release, the API is changing at least a little with
26
+ almost every release. If you need to keep those changes from
27
+ impacting you (or at least want to let many of them build up before
28
+ you have to deal with them), then lock your Gemfile down to a minor
29
+ release (e.g. :version => '~> 0.5.0').
30
+
31
+ ## Hello World
16
32
 
17
33
  This is examples/hello_world.rb, a bare minimum FTP server. It allows
18
34
  any user/password, and serves files in a temporary directory. It
@@ -48,7 +64,7 @@ binds to an ephemeral port on the local interface:
48
64
  A more full-featured example that allows TLS and takes options is in
49
65
  examples/example.rb
50
66
 
51
- ## DRIVER
67
+ ## Driver
52
68
 
53
69
  Ftpd's dynamic behavior such as authentication and file retrieval is
54
70
  controlled by a driver that you supply. The Driver class in the
@@ -63,7 +79,7 @@ driver will do. Here are the methods your driver needs:
63
79
  * {Example::Driver#authenticate authenticate}
64
80
  * {Example::Driver#file_system file_system}
65
81
 
66
- ## FILE SYSTEM
82
+ ## File System
67
83
 
68
84
  The file system object that the driver supplies to Ftpd is Ftpd's
69
85
  gateway to the logical file system. Ftpd doesn't know or care whether
@@ -109,7 +125,7 @@ Ftpd includes a disk based file system:
109
125
 
110
126
  end
111
127
 
112
- *Warning*: The DiskFileSystem allows file and directory modification
128
+ **Warning**: The DiskFileSystem allows file and directory modification
113
129
  including writing, renaming, deleting, etc. If you want a read-only
114
130
  file system, then use {Ftpd::ReadOnlyDiskFileSystem} instead.
115
131
 
@@ -125,35 +141,62 @@ The DiskFileSystem is composed out of modules:
125
141
  * {Ftpd::DiskFileSystem::Rmdir Rmdir} - Directory removal
126
142
  * {Ftpd::DiskFileSystem::Write Write} - File writing
127
143
 
128
- For example, to create a custom file system that allows reading and
129
- writing only, then:
144
+ You can use these modules to create a custom disk file system that
145
+ allows only the operations you want, or which mixes the predefined
146
+ modules with your customizations, as in this silly example that allows
147
+ uploads but then throws them away.
148
+
149
+ class BlackHole
150
+ def write(ftp_path, contents)
151
+ end
152
+ end
130
153
 
131
154
  class CustomDiskFileSystem
132
155
  include DiskFileSystem::Base
133
- include DiskFileSystem::List
134
156
  include DiskFileSystem::Read
135
- include DiskFileSystem::Write
157
+ include BlackHole
136
158
  end
137
159
 
138
- class Driver
139
-
140
- ...
160
+ ## Configuration
141
161
 
142
- def file_system(user)
143
- CustomDiskFileSystem('/var/lib/ftp')
144
- end
162
+ Configuration is done via accessors on {Ftpd::FtpServer}. For
163
+ example, to set the session timeout to 10 minutes:
145
164
 
146
- end
165
+ server = Ftpd::FtpServer.new(driver)
166
+ server.session_timeout = 10 * 60
167
+ server.start
147
168
 
148
- ## LIST output format
169
+ You can set any of these attributes before starting the server:
170
+
171
+ * {Ftpd::FtpServer#allow_low_data_ports}
172
+ * {Ftpd::FtpServer#auth_level}
173
+ * {Ftpd::FtpServer#failed_login_delay}
174
+ * {Ftpd::FtpServer#list_formatter}
175
+ * {Ftpd::FtpServer#log}
176
+ * {Ftpd::FtpServer#max_connections_per_ip}
177
+ * {Ftpd::FtpServer#max_connections}
178
+ * {Ftpd::FtpServer#max_failed_logins}
179
+ * {Ftpd::FtpServer#response_delay}
180
+ * {Ftpd::FtpServer#server_name}
181
+ * {Ftpd::FtpServer#server_version}
182
+ * {Ftpd::FtpServer#session_timeout}
183
+ * {Ftpd::Server#interface}
184
+ * {Ftpd::Server#port}
185
+ * {Ftpd::TlsServer#certfile_path}
186
+ * {Ftpd::TlsServer#tls}
187
+
188
+ ### LIST output format
149
189
 
150
190
  By default, the LIST command uses Unix "ls -l" formatting:
151
191
 
152
192
  -rw-r--r-- 1 user group 1234 Mar 3 08:38 foo
153
193
 
154
- To switch to
155
- [Easily Parsed LIST format (EPLF)](http://cr.yp.to/ftp/list/eplf.html)
156
- format:
194
+ An alternative to "ls -l" formatting is [Easily Parsed LIST format
195
+ (EPLF)](http://cr.yp.to/ftp/list/eplf.html) format:
196
+
197
+ +r,s1234,m1362325080\tfoo
198
+
199
+ to configure Ftpd for EPLF formatting:
157
200
 
158
201
  ftp_server.list_formatter = Ftpd::ListFormat::Eplf
159
202
 
@@ -167,35 +210,36 @@ And register your class with the ftp_server before starting it:
167
210
 
168
211
  ftp_server.list_formatter = MyListFormatter
169
212
 
170
- ## DEBUGGING
213
+ ### Logging
214
+
215
+ Ftpd can write to an instance of {Logger} that you provide. To log to
216
+ standard out:
171
217
 
172
- Ftpd can write debugging information (essentially a transcript of its
173
- conversation with a client) to a file. If you turn the debug flag on,
174
- the server will write debug information to stdout:
218
+ server.log = Logger.new($stdout)
175
219
 
176
- server = Ftpd::FtpServer.new(driver)
177
- server.debug = true
220
+ To log to a file:
178
221
 
179
- If you want to send the debug output to somewhere else, set
180
- debug_path:
222
+ server.log = Logger.new('/tmp/ftpd.log')
181
223
 
182
- server.debug_path = '/tmp/ftp_session'
224
+ ## Standards Compliance
183
225
 
184
- Debug output can also be enabled by setting the environment variable
185
- FTPD_DEBUG to a non-zero value. This is a convenient way to get debug
186
- output without having to change any code.
226
+ * Unconditionally compliant per [RFC-1123][1] (Requirements for
227
+ Internet Hosts).
187
228
 
188
- ## STANDARDS COMPLIANCE
229
+ * Implements all of the security recommendations in
230
+ [RFC-2577](http://tools.ietf.org/rfc/rfc2577.txt) (FTP Security
231
+ Considerations).
189
232
 
190
- Ftpd is fully unconditionally compliant per [RFC-1123 Requirements for
191
- Internet Hosts](http://tools.ietf.org/rfc/rfc1123.txt).
233
+ * Implements [RFC-2389](http://tools.ietf.org/rfc/rfc2389.txt)
234
+ (Feature negotiation mechanism for the File Transfer Protocol)
192
235
 
193
- Ftpd implements enough of [RFC-4217 Securing FTP with
194
- TLS](http://tools.ietf.org/rfc/rfc4217.txt) to get by.
236
+ * Implements enough of
237
+ [RFC-4217](http://tools.ietf.org/rfc/rfc4217.txt) (Securing FTP with
238
+ TLS) to get by.
195
239
 
196
240
  See [RFC Compliance](doc/rfc-compliance.md) for details
197
241
 
198
- ## RUBY COMPATABILITY
242
+ ## Ruby Compatability
199
243
 
200
244
  The tests pass with these Rubies:
201
245
 
@@ -203,9 +247,9 @@ The tests pass with these Rubies:
203
247
  * ruby-1.9.3-p392
204
248
  * ruby-2.0.0-p0
205
249
 
206
- ## DEVELOPMENT
250
+ ## Development
207
251
 
208
- ### TESTS
252
+ ### Tests
209
253
 
210
254
  To run the cucumber (functional) tests:
211
255
 
@@ -229,25 +273,37 @@ To force features to write the server log to stdout:
229
273
 
230
274
  ### Example
231
275
 
232
- To run the stand-alone example:
276
+ The stand-alone example is good for manually testing Ftpd with any FTP
277
+ client. To run the stand-alone example:
233
278
 
234
279
  $ examples/example.rb
235
280
 
236
281
  The example prints its port, username and password to the console.
237
- You can connect to the stand-alone example with any FTP client. This
238
- is useful when testing how the server responds to a given FTP client.
282
+ You can connect to the stand-alone example with any FTP client.
239
283
 
240
- ## ORIGIN
284
+ example.rb has many options. To see them:
285
+
286
+ $ examples/example.rb -h
287
+
288
+ ### Contributing
289
+
290
+ 1. Fork it
291
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
292
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
293
+ 4. Push to the branch (`git push origin my-new-feature`)
294
+ 5. Create new Pull Request
295
+
296
+ ## Origin
241
297
 
242
298
  I created ftpd to support the test framework I wrote for Databill,
243
299
  LLC, which has given its kind permission to donate it to the
244
300
  community.
245
301
 
246
- ## WHOAMI
302
+ ## Whoami
247
303
 
248
304
  Wayne Conrad <wconrad@yagni.com>
249
305
 
250
- ## CREDITS
306
+ ## Credits
251
307
 
252
308
  Thanks to Databill, LLC, which supported the creation of this library,
253
309
  and granted permission to donate it to the community.
@@ -258,3 +314,5 @@ and granted permission to donate it to the community.
258
314
  * [RFC compliance](doc/rfc-compliance.md)
259
315
  * [References](doc/references.md)
260
316
  * [Benchmarks](doc/benchmarks.md)
317
+
318
+ [1]: http://tools.ietf.org/rfc/rfc1123.txt
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.6.0
@@ -1,7 +1,6 @@
1
1
  # Benchmarks
2
2
 
3
- Benchmarks using pyftpd's [benchmark
4
- script](http://pyftpdlib.googlecode.com/svn/trunk/test/bench.py) and
3
+ Benchmarks using pyftpd's benchmark script and
5
4
  [procedures](http://code.google.com/p/pyftpdlib/wiki/Benchmarks).
6
5
 
7
6
  ## Results
@@ -75,7 +74,9 @@ proftpd or pyftpdlib.
75
74
 
76
75
  ### Benchmark command
77
76
 
78
- $ python bench.py -u <USER> -p <PASS> -H localhost -p <PORT> -b all -n 200 -k <PID>
77
+ bench.py needs psutil. Under Debian, install _python-psutil_.
78
+
79
+ pyftpdlib-1.0.1/test$ python bench.py -u <USER> -p <PASS> -H localhost -P <PORT> -b all -n 200 -k <PID>
79
80
 
80
81
  ### Proftpd
81
82
 
@@ -40,7 +40,7 @@ chronological order, the more useful ones are:
40
40
  FTP
41
41
 
42
42
  * [RFC-4217](http://tools.ietf.org/rfc/rfc4217.txt) -
43
- Internationalization of the File Transfer Protocol
43
+ Securing FTP with TLS
44
44
 
45
45
  For an english summary that's somewhat more legible than the RFCs, and
46
46
  provides some commentary on what features are actually useful or
@@ -104,10 +104,10 @@ Server-FTP handle Telnet options |4.1.2.12 |x| | | | | C
104
104
  Handle "Experimental" directory cmds |4.1.3.1 | |x| | | | C
105
105
  Idle timeout in server-FTP |4.1.3.2 | |x| | | | C
106
106
  Configurable idle timeout |4.1.3.2 | |x| | | | C
107
- Receiver checkpoint data at Restart Marker |4.1.3.4 | |x| | | |
108
- Sender assume 110 replies are synchronous |4.1.3.4 | | | | |x|
109
- | | | | | | |
110
- Support TYPE: | | | | | | |
107
+ Receiver checkpoint data at Restart Marker |4.1.3.4 | |x| | | | E
108
+ Sender assume 110 replies are synchronous |4.1.3.4 | | | | |x| E
109
+ | | | | | | | -
110
+ Support TYPE: | | | | | | | -
111
111
  ASCII - Non-Print (AN) |4.1.2.13 |x| | | | | C
112
112
  ASCII - Telnet (AT) -- if same as AN |4.1.2.2 | |x| | | | C
113
113
  ASCII - Carriage Control (AC) |959 3.1.1.5.2 | | |x| | | E
@@ -115,17 +115,17 @@ Support TYPE: | | | | | | |
115
115
  IMAGE |4.1.2.1 |x| | | | | C
116
116
  LOCAL 8 |4.1.2.1 |x| | | | | C
117
117
  LOCAL m |4.1.2.1 | | |x| | |2 E
118
- | | | | | | |
119
- Support MODE: | | | | | | |
118
+ | | | | | | | -
119
+ Support MODE: | | | | | | | -
120
120
  Stream |4.1.2.13 |x| | | | | C
121
121
  Block |959 3.4.2 | | |x| | | E
122
- | | | | | | |
123
- Support STRUCTURE: | | | | | | |
122
+ | | | | | | | -
123
+ Support STRUCTURE: | | | | | | | -
124
124
  File |4.1.2.13 |x| | | | | C
125
125
  Record |4.1.2.13 |x| | | | |3 E
126
126
  Page |4.1.2.3 | | | |x| | E
127
- | | | | | | |
128
- Support commands: | | | | | | |
127
+ | | | | | | | -
128
+ Support commands: | | | | | | | -
129
129
  USER |4.1.2.13 |x| | | | | C
130
130
  PASS |4.1.2.13 |x| | | | | C
131
131
  ACCT |4.1.2.13 |x| | | | | C
@@ -134,13 +134,13 @@ Support commands: | | | | | | |
134
134
  SMNT |959 5.3.1 | | |x| | | E
135
135
  REIN |959 5.3.1 | | |x| | | E
136
136
  QUIT |4.1.2.13 |x| | | | | C
137
- | | | | | | |
137
+ | | | | | | | -
138
138
  PORT |4.1.2.13 |x| | | | | C
139
139
  PASV |4.1.2.6 |x| | | | | C
140
140
  TYPE |4.1.2.13 |x| | | | |1 C
141
141
  STRU |4.1.2.13 |x| | | | |1 C
142
142
  MODE |4.1.2.13 |x| | | | |1 C
143
- | | | | | | |
143
+ | | | | | | | -
144
144
  RETR |4.1.2.13 |x| | | | | C
145
145
  STOR |4.1.2.13 |x| | | | | C
146
146
  STOU |959 5.3.1 | | |x| | | C
@@ -198,8 +198,8 @@ Introduces the new FEAT and OPTS commands.
198
198
  * [link](http://tools.ietf.org/rfc/rfc2389.txt)
199
199
 
200
200
  <pre>
201
- FEAT No --- List new supported commands
202
- OPTS No --- Set options for certain commands
201
+ FEAT Yes 0.6.0 List new supported commands
202
+ OPTS Yes 0.6.0 Set options for certain commands
203
203
  </pre>
204
204
 
205
205
  ## RFC-2428 - FTP Extensions for IPv6 and NATs
@@ -231,11 +231,11 @@ attempts and third-party "proxy FTP" transfers, which can be used in
231
231
  <pre>
232
232
  FTP bounce protection
233
233
  Restrict PASV/PORT to non-priv. ports Yes 0.5.0
234
- Disconnect after so many wrong auths. No ---
235
- Delay on invalid password No ---
236
- Per-source IP limit No ---
234
+ Disconnect after so many wrong auths. Yes 0.6.0
235
+ Delay on invalid password Yes 0.6.0
236
+ Per-source IP limit Yes 0.6.0
237
237
  Do not reject wrong usernames Yes 0.1.0
238
- Port stealing protection No ---
238
+ Port stealing protection Yes 0.1.0
239
239
  </pre>
240
240
 
241
241
  ## RFC-2640 - Internationalization of the File Transfer Protocol
@@ -214,6 +214,7 @@ module Example
214
214
  puts "TLS: #{@args.tls}"
215
215
  puts "Directory: #{@data_dir}"
216
216
  puts "URI: ftp://#{HOST}:#{@server.bound_port}"
217
+ puts "PID: #{$$}"
217
218
  end
218
219
 
219
220
  def create_connection_script