Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / ftp / ftp_network_transaction_unittest.cc
blob806cb191ce841b1df7e4394b8012c332394f24bf
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/ftp/ftp_network_transaction.h"
7 #include "build/build_config.h"
9 #include "base/compiler_specific.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_util.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/dns/mock_host_resolver.h"
19 #include "net/ftp/ftp_network_session.h"
20 #include "net/ftp/ftp_request_info.h"
21 #include "net/socket/socket_test_util.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "testing/platform_test.h"
25 namespace {
27 // Size we use for IOBuffers used to receive data from the test data socket.
28 const int kBufferSize = 128;
30 } // namespace
32 namespace net {
34 class FtpSocketDataProvider : public SocketDataProvider {
35 public:
36 enum State {
37 NONE,
38 PRE_USER,
39 PRE_PASSWD,
40 PRE_SYST,
41 PRE_PWD,
42 PRE_TYPE,
43 PRE_SIZE,
44 PRE_LIST_EPSV,
45 PRE_LIST_PASV,
46 PRE_LIST,
47 PRE_RETR,
48 PRE_RETR_EPSV,
49 PRE_RETR_PASV,
50 PRE_CWD,
51 PRE_QUIT,
52 PRE_NOPASV,
53 QUIT
56 FtpSocketDataProvider()
57 : short_read_limit_(0),
58 allow_unconsumed_reads_(false),
59 failure_injection_state_(NONE),
60 multiline_welcome_(false),
61 use_epsv_(true),
62 data_type_('I') {
63 Init();
66 // SocketDataProvider implementation.
67 MockRead OnRead() override {
68 if (reads_.empty())
69 return MockRead(SYNCHRONOUS, ERR_UNEXPECTED);
70 MockRead result = reads_.front();
71 if (short_read_limit_ == 0 || result.data_len <= short_read_limit_) {
72 reads_.pop_front();
73 } else {
74 result.data_len = short_read_limit_;
75 reads_.front().data += result.data_len;
76 reads_.front().data_len -= result.data_len;
78 return result;
81 MockWriteResult OnWrite(const std::string& data) override {
82 if (InjectFault())
83 return MockWriteResult(ASYNC, data.length());
84 switch (state()) {
85 case PRE_USER:
86 return Verify("USER anonymous\r\n", data, PRE_PASSWD,
87 "331 Password needed\r\n");
88 case PRE_PASSWD:
90 static const char response_one[] = "230 Welcome\r\n";
91 static const char response_multi[] =
92 "230- One\r\n230- Two\r\n230 Three\r\n";
93 return Verify("PASS chrome@example.com\r\n", data, PRE_SYST,
94 multiline_welcome_ ? response_multi : response_one);
96 case PRE_SYST:
97 return Verify("SYST\r\n", data, PRE_PWD, "215 UNIX\r\n");
98 case PRE_PWD:
99 return Verify("PWD\r\n", data, PRE_TYPE,
100 "257 \"/\" is your current location\r\n");
101 case PRE_TYPE:
102 return Verify(std::string("TYPE ") + data_type_ + "\r\n", data,
103 PRE_SIZE, "200 TYPE set successfully\r\n");
104 case PRE_LIST_EPSV:
105 return Verify("EPSV\r\n", data, PRE_LIST,
106 "227 Entering Extended Passive Mode (|||31744|)\r\n");
107 case PRE_LIST_PASV:
108 return Verify("PASV\r\n", data, PRE_LIST,
109 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
110 case PRE_RETR_EPSV:
111 return Verify("EPSV\r\n", data, PRE_RETR,
112 "227 Entering Extended Passive Mode (|||31744|)\r\n");
113 case PRE_RETR_PASV:
114 return Verify("PASV\r\n", data, PRE_RETR,
115 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
116 case PRE_NOPASV:
117 // Use unallocated 599 FTP error code to make sure it falls into the
118 // generic ERR_FTP_FAILED bucket.
119 return Verify("PASV\r\n", data, PRE_QUIT,
120 "599 fail\r\n");
121 case PRE_QUIT:
122 return Verify("QUIT\r\n", data, QUIT, "221 Goodbye.\r\n");
123 default:
124 NOTREACHED() << "State not handled " << state();
125 return MockWriteResult(ASYNC, ERR_UNEXPECTED);
129 void InjectFailure(State state, State next_state, const char* response) {
130 DCHECK_EQ(NONE, failure_injection_state_);
131 DCHECK_NE(NONE, state);
132 DCHECK_NE(NONE, next_state);
133 DCHECK_NE(state, next_state);
134 failure_injection_state_ = state;
135 failure_injection_next_state_ = next_state;
136 fault_response_ = response;
139 State state() const {
140 return state_;
143 void Reset() override {
144 reads_.clear();
145 Init();
148 bool AllReadDataConsumed() const override { return state_ == QUIT; }
150 bool AllWriteDataConsumed() const override { return state_ == QUIT; }
152 void set_multiline_welcome(bool multiline) { multiline_welcome_ = multiline; }
154 bool use_epsv() const { return use_epsv_; }
155 void set_use_epsv(bool use_epsv) { use_epsv_ = use_epsv; }
157 void set_data_type(char data_type) { data_type_ = data_type; }
159 int short_read_limit() const { return short_read_limit_; }
160 void set_short_read_limit(int limit) { short_read_limit_ = limit; }
162 void set_allow_unconsumed_reads(bool allow) {
163 allow_unconsumed_reads_ = allow;
166 protected:
167 void Init() {
168 state_ = PRE_USER;
169 SimulateRead("220 host TestFTPd\r\n");
172 // If protocol fault injection has been requested, adjusts state and mocked
173 // read and returns true.
174 bool InjectFault() {
175 if (state_ != failure_injection_state_)
176 return false;
177 SimulateRead(fault_response_);
178 state_ = failure_injection_next_state_;
179 return true;
182 MockWriteResult Verify(const std::string& expected,
183 const std::string& data,
184 State next_state,
185 const char* next_read,
186 const size_t next_read_length) {
187 EXPECT_EQ(expected, data);
188 if (expected == data) {
189 state_ = next_state;
190 SimulateRead(next_read, next_read_length);
191 return MockWriteResult(ASYNC, data.length());
193 return MockWriteResult(ASYNC, ERR_UNEXPECTED);
196 MockWriteResult Verify(const std::string& expected,
197 const std::string& data,
198 State next_state,
199 const char* next_read) {
200 return Verify(expected, data, next_state,
201 next_read, std::strlen(next_read));
204 // The next time there is a read from this socket, it will return |data|.
205 // Before calling SimulateRead next time, the previous data must be consumed.
206 void SimulateRead(const char* data, size_t length) {
207 if (!allow_unconsumed_reads_) {
208 EXPECT_TRUE(reads_.empty()) << "Unconsumed read: " << reads_.front().data;
210 reads_.push_back(MockRead(ASYNC, data, length));
212 void SimulateRead(const char* data) { SimulateRead(data, std::strlen(data)); }
214 private:
215 // List of reads to be consumed.
216 std::deque<MockRead> reads_;
218 // Max number of bytes we will read at a time. 0 means no limit.
219 int short_read_limit_;
221 // If true, we'll not require the client to consume all data before we
222 // mock the next read.
223 bool allow_unconsumed_reads_;
225 State state_;
226 State failure_injection_state_;
227 State failure_injection_next_state_;
228 const char* fault_response_;
230 // If true, we will send multiple 230 lines as response after PASS.
231 bool multiline_welcome_;
233 // If true, we will use EPSV command.
234 bool use_epsv_;
236 // Data type to be used for TYPE command.
237 char data_type_;
239 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider);
242 class FtpSocketDataProviderDirectoryListing : public FtpSocketDataProvider {
243 public:
244 FtpSocketDataProviderDirectoryListing() {
247 MockWriteResult OnWrite(const std::string& data) override {
248 if (InjectFault())
249 return MockWriteResult(ASYNC, data.length());
250 switch (state()) {
251 case PRE_SIZE:
252 return Verify("SIZE /\r\n", data, PRE_CWD,
253 "550 I can only retrieve regular files\r\n");
254 case PRE_CWD:
255 return Verify("CWD /\r\n", data,
256 use_epsv() ? PRE_LIST_EPSV : PRE_LIST_PASV, "200 OK\r\n");
257 case PRE_LIST:
258 return Verify("LIST -l\r\n", data, PRE_QUIT, "200 OK\r\n");
259 default:
260 return FtpSocketDataProvider::OnWrite(data);
264 private:
265 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing);
268 class FtpSocketDataProviderDirectoryListingWithPasvFallback
269 : public FtpSocketDataProviderDirectoryListing {
270 public:
271 FtpSocketDataProviderDirectoryListingWithPasvFallback() {
274 MockWriteResult OnWrite(const std::string& data) override {
275 if (InjectFault())
276 return MockWriteResult(ASYNC, data.length());
277 switch (state()) {
278 case PRE_LIST_EPSV:
279 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
280 "500 no EPSV for you\r\n");
281 case PRE_SIZE:
282 return Verify("SIZE /\r\n", data, PRE_CWD,
283 "550 I can only retrieve regular files\r\n");
284 default:
285 return FtpSocketDataProviderDirectoryListing::OnWrite(data);
289 private:
290 DISALLOW_COPY_AND_ASSIGN(
291 FtpSocketDataProviderDirectoryListingWithPasvFallback);
294 class FtpSocketDataProviderDirectoryListingZeroSize
295 : public FtpSocketDataProviderDirectoryListing {
296 public:
297 FtpSocketDataProviderDirectoryListingZeroSize() {
300 MockWriteResult OnWrite(const std::string& data) override {
301 if (InjectFault())
302 return MockWriteResult(ASYNC, data.length());
303 switch (state()) {
304 case PRE_SIZE:
305 return Verify("SIZE /\r\n", data, PRE_CWD, "213 0\r\n");
306 default:
307 return FtpSocketDataProviderDirectoryListing::OnWrite(data);
311 private:
312 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize);
315 class FtpSocketDataProviderVMSDirectoryListing : public FtpSocketDataProvider {
316 public:
317 FtpSocketDataProviderVMSDirectoryListing() {
320 MockWriteResult OnWrite(const std::string& data) override {
321 if (InjectFault())
322 return MockWriteResult(ASYNC, data.length());
323 switch (state()) {
324 case PRE_SYST:
325 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
326 case PRE_PWD:
327 return Verify("PWD\r\n", data, PRE_TYPE,
328 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
329 case PRE_LIST_EPSV:
330 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
331 "500 Invalid command\r\n");
332 case PRE_SIZE:
333 return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_CWD,
334 "550 I can only retrieve regular files\r\n");
335 case PRE_CWD:
336 return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data,
337 use_epsv() ? PRE_LIST_EPSV : PRE_LIST_PASV, "200 OK\r\n");
338 case PRE_LIST:
339 return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
340 default:
341 return FtpSocketDataProvider::OnWrite(data);
345 private:
346 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing);
349 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
350 : public FtpSocketDataProvider {
351 public:
352 FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
355 MockWriteResult OnWrite(const std::string& data) override {
356 if (InjectFault())
357 return MockWriteResult(ASYNC, data.length());
358 switch (state()) {
359 case PRE_SYST:
360 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
361 case PRE_PWD:
362 return Verify("PWD\r\n", data, PRE_TYPE,
363 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
364 case PRE_LIST_EPSV:
365 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
366 "500 EPSV command unknown\r\n");
367 case PRE_SIZE:
368 return Verify("SIZE ANONYMOUS_ROOT\r\n", data, PRE_CWD,
369 "550 I can only retrieve regular files\r\n");
370 case PRE_CWD:
371 return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data,
372 use_epsv() ? PRE_LIST_EPSV : PRE_LIST_PASV, "200 OK\r\n");
373 case PRE_LIST:
374 return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
375 default:
376 return FtpSocketDataProvider::OnWrite(data);
380 private:
381 DISALLOW_COPY_AND_ASSIGN(
382 FtpSocketDataProviderVMSDirectoryListingRootDirectory);
385 class FtpSocketDataProviderFileDownloadWithFileTypecode
386 : public FtpSocketDataProvider {
387 public:
388 FtpSocketDataProviderFileDownloadWithFileTypecode() {
391 MockWriteResult OnWrite(const std::string& data) override {
392 if (InjectFault())
393 return MockWriteResult(ASYNC, data.length());
394 switch (state()) {
395 case PRE_SIZE:
396 return Verify("SIZE /file\r\n", data,
397 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV, "213 18\r\n");
398 case PRE_RETR:
399 return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n");
400 default:
401 return FtpSocketDataProvider::OnWrite(data);
405 private:
406 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode);
409 class FtpSocketDataProviderFileDownload : public FtpSocketDataProvider {
410 public:
411 FtpSocketDataProviderFileDownload() {
414 MockWriteResult OnWrite(const std::string& data) override {
415 if (InjectFault())
416 return MockWriteResult(ASYNC, data.length());
417 switch (state()) {
418 case PRE_SIZE:
419 return Verify("SIZE /file\r\n", data, PRE_CWD, "213 18\r\n");
420 case PRE_CWD:
421 return Verify("CWD /file\r\n", data,
422 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
423 "550 Not a directory\r\n");
424 case PRE_RETR:
425 return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n");
426 default:
427 return FtpSocketDataProvider::OnWrite(data);
431 private:
432 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload);
435 class FtpSocketDataProviderFileNotFound : public FtpSocketDataProvider {
436 public:
437 FtpSocketDataProviderFileNotFound() {
440 MockWriteResult OnWrite(const std::string& data) override {
441 if (InjectFault())
442 return MockWriteResult(ASYNC, data.length());
443 switch (state()) {
444 case PRE_SIZE:
445 return Verify("SIZE /file\r\n", data, PRE_CWD,
446 "550 File Not Found\r\n");
447 case PRE_CWD:
448 return Verify("CWD /file\r\n", data,
449 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
450 "550 File Not Found\r\n");
451 case PRE_RETR:
452 return Verify("RETR /file\r\n", data, PRE_QUIT,
453 "550 File Not Found\r\n");
454 default:
455 return FtpSocketDataProvider::OnWrite(data);
459 private:
460 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound);
463 class FtpSocketDataProviderFileDownloadWithPasvFallback
464 : public FtpSocketDataProviderFileDownload {
465 public:
466 FtpSocketDataProviderFileDownloadWithPasvFallback() {
469 MockWriteResult OnWrite(const std::string& data) override {
470 if (InjectFault())
471 return MockWriteResult(ASYNC, data.length());
472 switch (state()) {
473 case PRE_RETR_EPSV:
474 return Verify("EPSV\r\n", data, PRE_RETR_PASV, "500 No can do\r\n");
475 case PRE_CWD:
476 return Verify("CWD /file\r\n", data,
477 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
478 "550 Not a directory\r\n");
479 default:
480 return FtpSocketDataProviderFileDownload::OnWrite(data);
484 private:
485 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback);
488 class FtpSocketDataProviderFileDownloadZeroSize
489 : public FtpSocketDataProviderFileDownload {
490 public:
491 FtpSocketDataProviderFileDownloadZeroSize() {
494 MockWriteResult OnWrite(const std::string& data) override {
495 if (InjectFault())
496 return MockWriteResult(ASYNC, data.length());
497 switch (state()) {
498 case PRE_SIZE:
499 return Verify("SIZE /file\r\n", data, PRE_CWD,
500 "213 0\r\n");
501 case PRE_CWD:
502 return Verify("CWD /file\r\n", data,
503 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
504 "550 not a directory\r\n");
505 default:
506 return FtpSocketDataProviderFileDownload::OnWrite(data);
510 private:
511 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize);
514 class FtpSocketDataProviderFileDownloadCWD451
515 : public FtpSocketDataProviderFileDownload {
516 public:
517 FtpSocketDataProviderFileDownloadCWD451() {
520 MockWriteResult OnWrite(const std::string& data) override {
521 if (InjectFault())
522 return MockWriteResult(ASYNC, data.length());
523 switch (state()) {
524 case PRE_CWD:
525 return Verify("CWD /file\r\n", data,
526 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
527 "451 not a directory\r\n");
528 default:
529 return FtpSocketDataProviderFileDownload::OnWrite(data);
533 private:
534 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451);
537 class FtpSocketDataProviderVMSFileDownload : public FtpSocketDataProvider {
538 public:
539 FtpSocketDataProviderVMSFileDownload() {
542 MockWriteResult OnWrite(const std::string& data) override {
543 if (InjectFault())
544 return MockWriteResult(ASYNC, data.length());
545 switch (state()) {
546 case PRE_SYST:
547 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
548 case PRE_PWD:
549 return Verify("PWD\r\n", data, PRE_TYPE,
550 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
551 case PRE_LIST_EPSV:
552 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
553 "500 EPSV command unknown\r\n");
554 case PRE_SIZE:
555 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_CWD,
556 "213 18\r\n");
557 case PRE_CWD:
558 return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data,
559 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
560 "550 Not a directory\r\n");
561 case PRE_RETR:
562 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_QUIT,
563 "200 OK\r\n");
564 default:
565 return FtpSocketDataProvider::OnWrite(data);
569 private:
570 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload);
573 class FtpSocketDataProviderEscaping : public FtpSocketDataProviderFileDownload {
574 public:
575 FtpSocketDataProviderEscaping() {
578 MockWriteResult OnWrite(const std::string& data) override {
579 if (InjectFault())
580 return MockWriteResult(ASYNC, data.length());
581 switch (state()) {
582 case PRE_SIZE:
583 return Verify("SIZE / !\"#$%y\200\201\r\n", data, PRE_CWD,
584 "213 18\r\n");
585 case PRE_CWD:
586 return Verify("CWD / !\"#$%y\200\201\r\n", data,
587 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
588 "550 Not a directory\r\n");
589 case PRE_RETR:
590 return Verify("RETR / !\"#$%y\200\201\r\n", data, PRE_QUIT,
591 "200 OK\r\n");
592 default:
593 return FtpSocketDataProviderFileDownload::OnWrite(data);
597 private:
598 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping);
601 class FtpSocketDataProviderFileDownloadTransferStarting
602 : public FtpSocketDataProviderFileDownload {
603 public:
604 FtpSocketDataProviderFileDownloadTransferStarting() {
607 MockWriteResult OnWrite(const std::string& data) override {
608 if (InjectFault())
609 return MockWriteResult(ASYNC, data.length());
610 switch (state()) {
611 case PRE_RETR:
612 return Verify("RETR /file\r\n", data, PRE_QUIT,
613 "125-Data connection already open.\r\n"
614 "125 Transfer starting.\r\n"
615 "226 Transfer complete.\r\n");
616 default:
617 return FtpSocketDataProviderFileDownload::OnWrite(data);
621 private:
622 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting);
625 class FtpSocketDataProviderDirectoryListingTransferStarting
626 : public FtpSocketDataProviderDirectoryListing {
627 public:
628 FtpSocketDataProviderDirectoryListingTransferStarting() {
631 MockWriteResult OnWrite(const std::string& data) override {
632 if (InjectFault())
633 return MockWriteResult(ASYNC, data.length());
634 switch (state()) {
635 case PRE_LIST:
636 return Verify("LIST -l\r\n", data, PRE_QUIT,
637 "125-Data connection already open.\r\n"
638 "125 Transfer starting.\r\n"
639 "226 Transfer complete.\r\n");
640 default:
641 return FtpSocketDataProviderDirectoryListing::OnWrite(data);
645 private:
646 DISALLOW_COPY_AND_ASSIGN(
647 FtpSocketDataProviderDirectoryListingTransferStarting);
650 class FtpSocketDataProviderFileDownloadInvalidResponse
651 : public FtpSocketDataProviderFileDownload {
652 public:
653 FtpSocketDataProviderFileDownloadInvalidResponse() {
656 MockWriteResult OnWrite(const std::string& data) override {
657 if (InjectFault())
658 return MockWriteResult(ASYNC, data.length());
659 switch (state()) {
660 case PRE_SIZE:
661 // Use unallocated 599 FTP error code to make sure it falls into the
662 // generic ERR_FTP_FAILED bucket.
663 return Verify("SIZE /file\r\n", data, PRE_QUIT,
664 "599 Evil Response\r\n"
665 "599 More Evil\r\n");
666 default:
667 return FtpSocketDataProviderFileDownload::OnWrite(data);
671 private:
672 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse);
675 class FtpSocketDataProviderEvilEpsv : public FtpSocketDataProviderFileDownload {
676 public:
677 FtpSocketDataProviderEvilEpsv(const char* epsv_response,
678 State expected_state)
679 : epsv_response_(epsv_response),
680 epsv_response_length_(std::strlen(epsv_response)),
681 expected_state_(expected_state) {}
683 FtpSocketDataProviderEvilEpsv(const char* epsv_response,
684 size_t epsv_response_length,
685 State expected_state)
686 : epsv_response_(epsv_response),
687 epsv_response_length_(epsv_response_length),
688 expected_state_(expected_state) {}
690 MockWriteResult OnWrite(const std::string& data) override {
691 if (InjectFault())
692 return MockWriteResult(ASYNC, data.length());
693 switch (state()) {
694 case PRE_RETR_EPSV:
695 return Verify("EPSV\r\n", data, expected_state_,
696 epsv_response_, epsv_response_length_);
697 default:
698 return FtpSocketDataProviderFileDownload::OnWrite(data);
702 private:
703 const char* epsv_response_;
704 const size_t epsv_response_length_;
705 const State expected_state_;
707 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv);
710 class FtpSocketDataProviderEvilPasv
711 : public FtpSocketDataProviderFileDownloadWithPasvFallback {
712 public:
713 FtpSocketDataProviderEvilPasv(const char* pasv_response, State expected_state)
714 : pasv_response_(pasv_response),
715 expected_state_(expected_state) {
718 MockWriteResult OnWrite(const std::string& data) override {
719 if (InjectFault())
720 return MockWriteResult(ASYNC, data.length());
721 switch (state()) {
722 case PRE_RETR_PASV:
723 return Verify("PASV\r\n", data, expected_state_, pasv_response_);
724 default:
725 return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data);
729 private:
730 const char* pasv_response_;
731 const State expected_state_;
733 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv);
736 class FtpSocketDataProviderEvilSize : public FtpSocketDataProviderFileDownload {
737 public:
738 FtpSocketDataProviderEvilSize(const char* size_response, State expected_state)
739 : size_response_(size_response),
740 expected_state_(expected_state) {
743 MockWriteResult OnWrite(const std::string& data) override {
744 if (InjectFault())
745 return MockWriteResult(ASYNC, data.length());
746 switch (state()) {
747 case PRE_SIZE:
748 return Verify("SIZE /file\r\n", data, expected_state_, size_response_);
749 default:
750 return FtpSocketDataProviderFileDownload::OnWrite(data);
754 private:
755 const char* size_response_;
756 const State expected_state_;
758 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize);
761 class FtpSocketDataProviderEvilLogin
762 : public FtpSocketDataProviderFileDownload {
763 public:
764 FtpSocketDataProviderEvilLogin(const char* expected_user,
765 const char* expected_password)
766 : expected_user_(expected_user),
767 expected_password_(expected_password) {
770 MockWriteResult OnWrite(const std::string& data) override {
771 if (InjectFault())
772 return MockWriteResult(ASYNC, data.length());
773 switch (state()) {
774 case PRE_USER:
775 return Verify(std::string("USER ") + expected_user_ + "\r\n", data,
776 PRE_PASSWD, "331 Password needed\r\n");
777 case PRE_PASSWD:
778 return Verify(std::string("PASS ") + expected_password_ + "\r\n", data,
779 PRE_SYST, "230 Welcome\r\n");
780 default:
781 return FtpSocketDataProviderFileDownload::OnWrite(data);
785 private:
786 const char* expected_user_;
787 const char* expected_password_;
789 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin);
792 class FtpSocketDataProviderCloseConnection : public FtpSocketDataProvider {
793 public:
794 FtpSocketDataProviderCloseConnection() {
797 MockWriteResult OnWrite(const std::string& data) override {
798 if (InjectFault())
799 return MockWriteResult(ASYNC, data.length());
800 switch (state()) {
801 case PRE_USER:
802 return Verify("USER anonymous\r\n", data,
803 PRE_QUIT, "");
804 default:
805 return FtpSocketDataProvider::OnWrite(data);
809 private:
810 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection);
813 class FtpNetworkTransactionTest
814 : public PlatformTest,
815 public ::testing::WithParamInterface<int> {
816 public:
817 FtpNetworkTransactionTest()
818 : host_resolver_(new MockHostResolver),
819 session_(new FtpNetworkSession(host_resolver_.get())),
820 transaction_(session_.get(), &mock_socket_factory_) {
821 scoped_refptr<RuleBasedHostResolverProc> rules(
822 new RuleBasedHostResolverProc(NULL));
823 if (GetFamily() == AF_INET) {
824 rules->AddIPLiteralRule("*", "127.0.0.1", "127.0.0.1");
825 } else if (GetFamily() == AF_INET6) {
826 rules->AddIPLiteralRule("*", "::1", "::1");
827 } else {
828 NOTREACHED();
830 host_resolver_->set_rules(rules.get());
833 protected:
834 // Accessor to make code refactoring-friendly, e.g. when we change the way
835 // parameters are passed (like more parameters).
836 int GetFamily() {
837 return GetParam();
840 FtpRequestInfo GetRequestInfo(const std::string& url) {
841 FtpRequestInfo info;
842 info.url = GURL(url);
843 return info;
846 void ExecuteTransaction(FtpSocketDataProvider* ctrl_socket,
847 const char* request,
848 int expected_result) {
849 // Expect EPSV usage for non-IPv4 control connections.
850 ctrl_socket->set_use_epsv((GetFamily() != AF_INET));
852 mock_socket_factory_.AddSocketDataProvider(ctrl_socket);
854 std::string mock_data("mock-data");
855 MockRead data_reads[] = {
856 // Usually FTP servers close the data connection after the entire data has
857 // been received.
858 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
859 MockRead(mock_data.c_str()),
862 scoped_ptr<StaticSocketDataProvider> data_socket(
863 new StaticSocketDataProvider(data_reads, arraysize(data_reads), NULL,
864 0));
865 mock_socket_factory_.AddSocketDataProvider(data_socket.get());
866 FtpRequestInfo request_info = GetRequestInfo(request);
867 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
868 ASSERT_EQ(ERR_IO_PENDING,
869 transaction_.Start(&request_info, callback_.callback(),
870 BoundNetLog()));
871 EXPECT_NE(LOAD_STATE_IDLE, transaction_.GetLoadState());
872 ASSERT_EQ(expected_result, callback_.WaitForResult());
873 if (expected_result == OK) {
874 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(kBufferSize));
875 memset(io_buffer->data(), 0, kBufferSize);
876 ASSERT_EQ(ERR_IO_PENDING,
877 transaction_.Read(io_buffer.get(), kBufferSize,
878 callback_.callback()));
879 ASSERT_EQ(static_cast<int>(mock_data.length()),
880 callback_.WaitForResult());
881 EXPECT_EQ(mock_data, std::string(io_buffer->data(), mock_data.length()));
883 // Do another Read to detect that the data socket is now closed.
884 int rv = transaction_.Read(io_buffer.get(), kBufferSize,
885 callback_.callback());
886 if (rv == ERR_IO_PENDING) {
887 EXPECT_EQ(0, callback_.WaitForResult());
888 } else {
889 EXPECT_EQ(0, rv);
892 EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket->state());
893 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
896 void TransactionFailHelper(FtpSocketDataProvider* ctrl_socket,
897 const char* request,
898 FtpSocketDataProvider::State state,
899 FtpSocketDataProvider::State next_state,
900 const char* response,
901 int expected_result) {
902 ctrl_socket->InjectFailure(state, next_state, response);
903 ExecuteTransaction(ctrl_socket, request, expected_result);
906 scoped_ptr<MockHostResolver> host_resolver_;
907 scoped_refptr<FtpNetworkSession> session_;
908 MockClientSocketFactory mock_socket_factory_;
909 FtpNetworkTransaction transaction_;
910 TestCompletionCallback callback_;
913 TEST_P(FtpNetworkTransactionTest, FailedLookup) {
914 FtpRequestInfo request_info = GetRequestInfo("ftp://badhost");
915 scoped_refptr<RuleBasedHostResolverProc> rules(
916 new RuleBasedHostResolverProc(NULL));
917 rules->AddSimulatedFailure("badhost");
918 host_resolver_->set_rules(rules.get());
920 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
921 ASSERT_EQ(ERR_IO_PENDING,
922 transaction_.Start(&request_info, callback_.callback(),
923 BoundNetLog()));
924 ASSERT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
925 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
928 // Check that when determining the host, the square brackets decorating IPv6
929 // literals in URLs are stripped.
930 TEST_P(FtpNetworkTransactionTest, StripBracketsFromIPv6Literals) {
931 // This test only makes sense for IPv6 connections.
932 if (GetFamily() != AF_INET6)
933 return;
935 host_resolver_->rules()->AddSimulatedFailure("[::1]");
937 // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE.
938 // The important part of this test is to make sure that we don't fail with
939 // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname
940 // was used.
941 FtpSocketDataProviderEvilSize ctrl_socket(
942 "213 99999999999999999999999999999999\r\n",
943 FtpSocketDataProvider::PRE_QUIT);
944 ExecuteTransaction(&ctrl_socket, "ftp://[::1]/file", ERR_INVALID_RESPONSE);
947 TEST_P(FtpNetworkTransactionTest, DirectoryTransaction) {
948 FtpSocketDataProviderDirectoryListing ctrl_socket;
949 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
951 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
952 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
953 EXPECT_EQ((GetFamily() == AF_INET) ? "127.0.0.1" : "::1",
954 transaction_.GetResponseInfo()->socket_address.host());
955 EXPECT_EQ(21, transaction_.GetResponseInfo()->socket_address.port());
958 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithPasvFallback) {
959 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket;
960 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
962 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
963 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
966 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithTypecode) {
967 FtpSocketDataProviderDirectoryListing ctrl_socket;
968 ExecuteTransaction(&ctrl_socket, "ftp://host/;type=d", OK);
970 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
971 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
974 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcome) {
975 FtpSocketDataProviderDirectoryListing ctrl_socket;
976 ctrl_socket.set_multiline_welcome(true);
977 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
980 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads2) {
981 FtpSocketDataProviderDirectoryListing ctrl_socket;
982 ctrl_socket.set_short_read_limit(2);
983 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
986 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) {
987 FtpSocketDataProviderDirectoryListing ctrl_socket;
988 ctrl_socket.set_short_read_limit(5);
989 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
992 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcomeShort) {
993 FtpSocketDataProviderDirectoryListing ctrl_socket;
994 // The client will not consume all three 230 lines. That's good, we want to
995 // test that scenario.
996 ctrl_socket.set_allow_unconsumed_reads(true);
997 ctrl_socket.set_multiline_welcome(true);
998 ctrl_socket.set_short_read_limit(5);
999 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
1002 // Regression test for http://crbug.com/60555.
1003 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) {
1004 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket;
1005 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
1008 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMS) {
1009 FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
1010 ExecuteTransaction(&ctrl_socket, "ftp://host/dir", OK);
1013 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) {
1014 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket;
1015 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
1018 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) {
1019 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket;
1020 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
1023 TEST_P(FtpNetworkTransactionTest, DownloadTransaction) {
1024 FtpSocketDataProviderFileDownload ctrl_socket;
1025 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1027 // We pass an artificial value of 18 as a response to the SIZE command.
1028 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1029 EXPECT_EQ((GetFamily() == AF_INET) ? "127.0.0.1" : "::1",
1030 transaction_.GetResponseInfo()->socket_address.host());
1031 EXPECT_EQ(21, transaction_.GetResponseInfo()->socket_address.port());
1034 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithPasvFallback) {
1035 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket;
1036 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1038 // We pass an artificial value of 18 as a response to the SIZE command.
1039 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1042 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeA) {
1043 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket;
1044 ctrl_socket.set_data_type('A');
1045 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=a", OK);
1047 // We pass an artificial value of 18 as a response to the SIZE command.
1048 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1051 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeI) {
1052 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket;
1053 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=i", OK);
1055 // We pass an artificial value of 18 as a response to the SIZE command.
1056 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1059 TEST_P(FtpNetworkTransactionTest, DownloadTransactionMultilineWelcome) {
1060 FtpSocketDataProviderFileDownload ctrl_socket;
1061 ctrl_socket.set_multiline_welcome(true);
1062 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1065 TEST_P(FtpNetworkTransactionTest, DownloadTransactionShortReads2) {
1066 FtpSocketDataProviderFileDownload ctrl_socket;
1067 ctrl_socket.set_short_read_limit(2);
1068 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1071 TEST_P(FtpNetworkTransactionTest, DownloadTransactionShortReads5) {
1072 FtpSocketDataProviderFileDownload ctrl_socket;
1073 ctrl_socket.set_short_read_limit(5);
1074 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1077 TEST_P(FtpNetworkTransactionTest, DownloadTransactionZeroSize) {
1078 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket;
1079 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1082 TEST_P(FtpNetworkTransactionTest, DownloadTransactionCWD451) {
1083 FtpSocketDataProviderFileDownloadCWD451 ctrl_socket;
1084 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1087 TEST_P(FtpNetworkTransactionTest, DownloadTransactionVMS) {
1088 FtpSocketDataProviderVMSFileDownload ctrl_socket;
1089 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1092 TEST_P(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) {
1093 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket;
1094 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1097 TEST_P(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) {
1098 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket;
1099 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1102 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvReallyBadFormat) {
1103 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,\r\n",
1104 FtpSocketDataProvider::PRE_QUIT);
1105 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1108 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort1) {
1109 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
1110 FtpSocketDataProvider::PRE_QUIT);
1111 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1114 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort2) {
1115 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
1116 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
1117 FtpSocketDataProvider::PRE_QUIT);
1118 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1121 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort3) {
1122 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
1123 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
1124 FtpSocketDataProvider::PRE_QUIT);
1125 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1128 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort4) {
1129 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
1130 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
1131 FtpSocketDataProvider::PRE_QUIT);
1132 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1135 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafeHost) {
1136 FtpSocketDataProviderEvilPasv ctrl_socket(
1137 "227 Portscan (10,1,2,3,123,456)\r\n", FtpSocketDataProvider::PRE_RETR);
1138 ctrl_socket.set_use_epsv(GetFamily() != AF_INET);
1139 std::string mock_data("mock-data");
1140 MockRead data_reads[] = {
1141 MockRead(mock_data.c_str()),
1143 StaticSocketDataProvider data_socket1;
1144 StaticSocketDataProvider data_socket2(data_reads, arraysize(data_reads),
1145 NULL, 0);
1146 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket);
1147 mock_socket_factory_.AddSocketDataProvider(&data_socket1);
1148 mock_socket_factory_.AddSocketDataProvider(&data_socket2);
1149 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1151 // Start the transaction.
1152 ASSERT_EQ(ERR_IO_PENDING,
1153 transaction_.Start(&request_info, callback_.callback(),
1154 BoundNetLog()));
1155 ASSERT_EQ(OK, callback_.WaitForResult());
1157 // The transaction fires the callback when we can start reading data. That
1158 // means that the data socket should be open.
1159 MockTCPClientSocket* data_socket =
1160 static_cast<MockTCPClientSocket*>(transaction_.data_socket_.get());
1161 ASSERT_TRUE(data_socket);
1162 ASSERT_TRUE(data_socket->IsConnected());
1164 // Even if the PASV response specified some other address, we connect
1165 // to the address we used for control connection (which could be 127.0.0.1
1166 // or ::1 depending on whether we use IPv6).
1167 for (AddressList::const_iterator it = data_socket->addresses().begin();
1168 it != data_socket->addresses().end(); ++it) {
1169 EXPECT_NE("10.1.2.3", it->ToStringWithoutPort());
1173 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat1) {
1174 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1175 if (GetFamily() == AF_INET)
1176 return;
1178 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22)\r\n",
1179 FtpSocketDataProvider::PRE_QUIT);
1180 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1183 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat2) {
1184 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1185 if (GetFamily() == AF_INET)
1186 return;
1188 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||\r\n",
1189 FtpSocketDataProvider::PRE_QUIT);
1190 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1193 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat3) {
1194 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1195 if (GetFamily() == AF_INET)
1196 return;
1198 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan\r\n",
1199 FtpSocketDataProvider::PRE_QUIT);
1200 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1203 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat4) {
1204 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1205 if (GetFamily() == AF_INET)
1206 return;
1208 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||||)\r\n",
1209 FtpSocketDataProvider::PRE_QUIT);
1210 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1213 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat5) {
1214 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1215 if (GetFamily() == AF_INET)
1216 return;
1218 // Breaking the string in the next line prevents MSVC warning C4125.
1219 const char response[] = "227 Portscan (\0\0\031" "773\0)\r\n";
1220 FtpSocketDataProviderEvilEpsv ctrl_socket(response, sizeof(response)-1,
1221 FtpSocketDataProvider::PRE_QUIT);
1222 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1225 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort1) {
1226 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1227 if (GetFamily() == AF_INET)
1228 return;
1230 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22|)\r\n",
1231 FtpSocketDataProvider::PRE_QUIT);
1232 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1235 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort2) {
1236 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1237 if (GetFamily() == AF_INET)
1238 return;
1240 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||258|)\r\n",
1241 FtpSocketDataProvider::PRE_QUIT);
1242 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1245 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort3) {
1246 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1247 if (GetFamily() == AF_INET)
1248 return;
1250 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||772|)\r\n",
1251 FtpSocketDataProvider::PRE_QUIT);
1252 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1255 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort4) {
1256 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1257 if (GetFamily() == AF_INET)
1258 return;
1260 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||2049|)\r\n",
1261 FtpSocketDataProvider::PRE_QUIT);
1262 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1265 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvWeirdSep) {
1266 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1267 if (GetFamily() == AF_INET)
1268 return;
1270 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$31744$)\r\n",
1271 FtpSocketDataProvider::PRE_RETR);
1272 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1275 TEST_P(FtpNetworkTransactionTest,
1276 DownloadTransactionEvilEpsvWeirdSepUnsafePort) {
1277 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1278 if (GetFamily() == AF_INET)
1279 return;
1281 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$317$)\r\n",
1282 FtpSocketDataProvider::PRE_QUIT);
1283 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1286 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvIllegalHost) {
1287 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1288 if (GetFamily() == AF_INET)
1289 return;
1291 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
1292 FtpSocketDataProvider::PRE_QUIT);
1293 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1296 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) {
1297 FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test");
1298 ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", OK);
1301 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) {
1302 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld");
1303 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", OK);
1306 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) {
1307 FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test");
1308 ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", OK);
1311 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) {
1312 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world");
1313 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", OK);
1316 TEST_P(FtpNetworkTransactionTest, EvilRestartUser) {
1317 FtpSocketDataProvider ctrl_socket1;
1318 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
1319 FtpSocketDataProvider::PRE_QUIT,
1320 "530 Login authentication failed\r\n");
1321 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
1323 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1325 ASSERT_EQ(ERR_IO_PENDING,
1326 transaction_.Start(&request_info, callback_.callback(),
1327 BoundNetLog()));
1328 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
1330 MockRead ctrl_reads[] = {
1331 MockRead("220 host TestFTPd\r\n"),
1332 MockRead("221 Goodbye!\r\n"),
1333 MockRead(SYNCHRONOUS, OK),
1335 MockWrite ctrl_writes[] = {
1336 MockWrite("QUIT\r\n"),
1338 StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
1339 ctrl_writes, arraysize(ctrl_writes));
1340 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
1341 ASSERT_EQ(ERR_IO_PENDING,
1342 transaction_.RestartWithAuth(
1343 AuthCredentials(
1344 base::ASCIIToUTF16("foo\nownz0red"),
1345 base::ASCIIToUTF16("innocent")),
1346 callback_.callback()));
1347 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
1350 TEST_P(FtpNetworkTransactionTest, EvilRestartPassword) {
1351 FtpSocketDataProvider ctrl_socket1;
1352 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
1353 FtpSocketDataProvider::PRE_QUIT,
1354 "530 Login authentication failed\r\n");
1355 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
1357 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1359 ASSERT_EQ(ERR_IO_PENDING,
1360 transaction_.Start(&request_info, callback_.callback(),
1361 BoundNetLog()));
1362 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
1364 MockRead ctrl_reads[] = {
1365 MockRead("220 host TestFTPd\r\n"),
1366 MockRead("331 User okay, send password\r\n"),
1367 MockRead("221 Goodbye!\r\n"),
1368 MockRead(SYNCHRONOUS, OK),
1370 MockWrite ctrl_writes[] = {
1371 MockWrite("USER innocent\r\n"),
1372 MockWrite("QUIT\r\n"),
1374 StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
1375 ctrl_writes, arraysize(ctrl_writes));
1376 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
1377 ASSERT_EQ(ERR_IO_PENDING,
1378 transaction_.RestartWithAuth(
1379 AuthCredentials(base::ASCIIToUTF16("innocent"),
1380 base::ASCIIToUTF16("foo\nownz0red")),
1381 callback_.callback()));
1382 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
1385 TEST_P(FtpNetworkTransactionTest, Escaping) {
1386 FtpSocketDataProviderEscaping ctrl_socket;
1387 ExecuteTransaction(&ctrl_socket, "ftp://host/%20%21%22%23%24%25%79%80%81",
1388 OK);
1391 // Test for http://crbug.com/23794.
1392 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilSize) {
1393 // Try to overflow int64 in the response.
1394 FtpSocketDataProviderEvilSize ctrl_socket(
1395 "213 99999999999999999999999999999999\r\n",
1396 FtpSocketDataProvider::PRE_QUIT);
1397 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1400 // Test for http://crbug.com/36360.
1401 TEST_P(FtpNetworkTransactionTest, DownloadTransactionBigSize) {
1402 // Pass a valid, but large file size. The transaction should not fail.
1403 FtpSocketDataProviderEvilSize ctrl_socket(
1404 "213 3204427776\r\n",
1405 FtpSocketDataProvider::PRE_CWD);
1406 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1407 EXPECT_EQ(3204427776LL,
1408 transaction_.GetResponseInfo()->expected_content_size);
1411 // Regression test for http://crbug.com/25023.
1412 TEST_P(FtpNetworkTransactionTest, CloseConnection) {
1413 FtpSocketDataProviderCloseConnection ctrl_socket;
1414 ExecuteTransaction(&ctrl_socket, "ftp://host", ERR_EMPTY_RESPONSE);
1417 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailUser) {
1418 FtpSocketDataProviderDirectoryListing ctrl_socket;
1419 // Use unallocated 599 FTP error code to make sure it falls into the generic
1420 // ERR_FTP_FAILED bucket.
1421 TransactionFailHelper(&ctrl_socket,
1422 "ftp://host",
1423 FtpSocketDataProvider::PRE_USER,
1424 FtpSocketDataProvider::PRE_QUIT,
1425 "599 fail\r\n",
1426 ERR_FTP_FAILED);
1429 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass) {
1430 FtpSocketDataProviderDirectoryListing ctrl_socket;
1431 TransactionFailHelper(&ctrl_socket,
1432 "ftp://host",
1433 FtpSocketDataProvider::PRE_PASSWD,
1434 FtpSocketDataProvider::PRE_QUIT,
1435 "530 Login authentication failed\r\n",
1436 ERR_FTP_FAILED);
1439 // Regression test for http://crbug.com/38707.
1440 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass503) {
1441 FtpSocketDataProviderDirectoryListing ctrl_socket;
1442 TransactionFailHelper(&ctrl_socket,
1443 "ftp://host",
1444 FtpSocketDataProvider::PRE_PASSWD,
1445 FtpSocketDataProvider::PRE_QUIT,
1446 "503 Bad sequence of commands\r\n",
1447 ERR_FTP_BAD_COMMAND_SEQUENCE);
1450 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailSyst) {
1451 FtpSocketDataProviderDirectoryListing ctrl_socket;
1452 // Use unallocated 599 FTP error code to make sure it falls into the generic
1453 // ERR_FTP_FAILED bucket.
1454 TransactionFailHelper(&ctrl_socket,
1455 "ftp://host",
1456 FtpSocketDataProvider::PRE_SYST,
1457 FtpSocketDataProvider::PRE_PWD,
1458 "599 fail\r\n",
1459 OK);
1462 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPwd) {
1463 FtpSocketDataProviderDirectoryListing ctrl_socket;
1464 // Use unallocated 599 FTP error code to make sure it falls into the generic
1465 // ERR_FTP_FAILED bucket.
1466 TransactionFailHelper(&ctrl_socket,
1467 "ftp://host",
1468 FtpSocketDataProvider::PRE_PWD,
1469 FtpSocketDataProvider::PRE_QUIT,
1470 "599 fail\r\n",
1471 ERR_FTP_FAILED);
1474 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailType) {
1475 FtpSocketDataProviderDirectoryListing ctrl_socket;
1476 // Use unallocated 599 FTP error code to make sure it falls into the generic
1477 // ERR_FTP_FAILED bucket.
1478 TransactionFailHelper(&ctrl_socket,
1479 "ftp://host",
1480 FtpSocketDataProvider::PRE_TYPE,
1481 FtpSocketDataProvider::PRE_QUIT,
1482 "599 fail\r\n",
1483 ERR_FTP_FAILED);
1486 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailEpsv) {
1487 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1488 if (GetFamily() == AF_INET)
1489 return;
1491 FtpSocketDataProviderDirectoryListing ctrl_socket;
1492 // Use unallocated 599 FTP error code to make sure it falls into the generic
1493 // ERR_FTP_FAILED bucket.
1494 TransactionFailHelper(
1495 &ctrl_socket, "ftp://host", FtpSocketDataProvider::PRE_LIST_EPSV,
1496 FtpSocketDataProvider::PRE_NOPASV, "599 fail\r\n", ERR_FTP_FAILED);
1499 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailCwd) {
1500 FtpSocketDataProviderDirectoryListing ctrl_socket;
1501 // Use unallocated 599 FTP error code to make sure it falls into the generic
1502 // ERR_FTP_FAILED bucket.
1503 TransactionFailHelper(&ctrl_socket,
1504 "ftp://host",
1505 FtpSocketDataProvider::PRE_CWD,
1506 FtpSocketDataProvider::PRE_QUIT,
1507 "599 fail\r\n",
1508 ERR_FTP_FAILED);
1511 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailList) {
1512 FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
1513 // Use unallocated 599 FTP error code to make sure it falls into the generic
1514 // ERR_FTP_FAILED bucket.
1515 TransactionFailHelper(&ctrl_socket,
1516 "ftp://host/dir",
1517 FtpSocketDataProvider::PRE_LIST,
1518 FtpSocketDataProvider::PRE_QUIT,
1519 "599 fail\r\n",
1520 ERR_FTP_FAILED);
1523 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailUser) {
1524 FtpSocketDataProviderFileDownload ctrl_socket;
1525 // Use unallocated 599 FTP error code to make sure it falls into the generic
1526 // ERR_FTP_FAILED bucket.
1527 TransactionFailHelper(&ctrl_socket,
1528 "ftp://host/file",
1529 FtpSocketDataProvider::PRE_USER,
1530 FtpSocketDataProvider::PRE_QUIT,
1531 "599 fail\r\n",
1532 ERR_FTP_FAILED);
1535 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPass) {
1536 FtpSocketDataProviderFileDownload ctrl_socket;
1537 TransactionFailHelper(&ctrl_socket,
1538 "ftp://host/file",
1539 FtpSocketDataProvider::PRE_PASSWD,
1540 FtpSocketDataProvider::PRE_QUIT,
1541 "530 Login authentication failed\r\n",
1542 ERR_FTP_FAILED);
1545 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailSyst) {
1546 FtpSocketDataProviderFileDownload ctrl_socket;
1547 // Use unallocated 599 FTP error code to make sure it falls into the generic
1548 // ERR_FTP_FAILED bucket.
1549 TransactionFailHelper(&ctrl_socket,
1550 "ftp://host/file",
1551 FtpSocketDataProvider::PRE_SYST,
1552 FtpSocketDataProvider::PRE_PWD,
1553 "599 fail\r\n",
1554 OK);
1557 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPwd) {
1558 FtpSocketDataProviderFileDownload ctrl_socket;
1559 // Use unallocated 599 FTP error code to make sure it falls into the generic
1560 // ERR_FTP_FAILED bucket.
1561 TransactionFailHelper(&ctrl_socket,
1562 "ftp://host/file",
1563 FtpSocketDataProvider::PRE_PWD,
1564 FtpSocketDataProvider::PRE_QUIT,
1565 "599 fail\r\n",
1566 ERR_FTP_FAILED);
1569 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailType) {
1570 FtpSocketDataProviderFileDownload ctrl_socket;
1571 // Use unallocated 599 FTP error code to make sure it falls into the generic
1572 // ERR_FTP_FAILED bucket.
1573 TransactionFailHelper(&ctrl_socket,
1574 "ftp://host/file",
1575 FtpSocketDataProvider::PRE_TYPE,
1576 FtpSocketDataProvider::PRE_QUIT,
1577 "599 fail\r\n",
1578 ERR_FTP_FAILED);
1581 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailEpsv) {
1582 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1583 if (GetFamily() == AF_INET)
1584 return;
1586 FtpSocketDataProviderFileDownload ctrl_socket;
1587 // Use unallocated 599 FTP error code to make sure it falls into the generic
1588 // ERR_FTP_FAILED bucket.
1589 TransactionFailHelper(
1590 &ctrl_socket, "ftp://host/file", FtpSocketDataProvider::PRE_RETR_EPSV,
1591 FtpSocketDataProvider::PRE_NOPASV, "599 fail\r\n", ERR_FTP_FAILED);
1594 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailRetr) {
1595 FtpSocketDataProviderFileDownload ctrl_socket;
1596 // Use unallocated 599 FTP error code to make sure it falls into the generic
1597 // ERR_FTP_FAILED bucket.
1598 TransactionFailHelper(&ctrl_socket,
1599 "ftp://host/file",
1600 FtpSocketDataProvider::PRE_RETR,
1601 FtpSocketDataProvider::PRE_QUIT,
1602 "599 fail\r\n",
1603 ERR_FTP_FAILED);
1606 TEST_P(FtpNetworkTransactionTest, FileNotFound) {
1607 FtpSocketDataProviderFileNotFound ctrl_socket;
1608 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_FTP_FAILED);
1611 // Test for http://crbug.com/38845.
1612 TEST_P(FtpNetworkTransactionTest, ZeroLengthDirInPWD) {
1613 FtpSocketDataProviderFileDownload ctrl_socket;
1614 TransactionFailHelper(&ctrl_socket,
1615 "ftp://host/file",
1616 FtpSocketDataProvider::PRE_PWD,
1617 FtpSocketDataProvider::PRE_TYPE,
1618 "257 \"\"\r\n",
1619 OK);
1622 INSTANTIATE_TEST_CASE_P(FTP,
1623 FtpNetworkTransactionTest,
1624 ::testing::Values(AF_INET, AF_INET6));
1626 } // namespace net