Update V8 to version 4.7.50.
[chromium-blink-merge.git] / net / ftp / ftp_network_transaction_unittest.cc
blob0d364a1160e2a7d4d359b4263d47278376923774
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/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "net/base/host_port_pair.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/net_util.h"
16 #include "net/base/test_completion_callback.h"
17 #include "net/dns/mock_host_resolver.h"
18 #include "net/ftp/ftp_request_info.h"
19 #include "net/socket/socket_test_util.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "testing/platform_test.h"
23 namespace {
25 // Size we use for IOBuffers used to receive data from the test data socket.
26 const int kBufferSize = 128;
28 } // namespace
30 namespace net {
32 class FtpSocketDataProvider : public SocketDataProvider {
33 public:
34 enum State {
35 NONE,
36 PRE_USER,
37 PRE_PASSWD,
38 PRE_SYST,
39 PRE_PWD,
40 PRE_TYPE,
41 PRE_SIZE,
42 PRE_LIST_EPSV,
43 PRE_LIST_PASV,
44 PRE_LIST,
45 PRE_RETR,
46 PRE_RETR_EPSV,
47 PRE_RETR_PASV,
48 PRE_CWD,
49 PRE_QUIT,
50 PRE_NOPASV,
51 QUIT
54 FtpSocketDataProvider()
55 : short_read_limit_(0),
56 allow_unconsumed_reads_(false),
57 failure_injection_state_(NONE),
58 multiline_welcome_(false),
59 use_epsv_(true),
60 data_type_('I') {
61 Init();
64 // SocketDataProvider implementation.
65 MockRead OnRead() override {
66 if (reads_.empty())
67 return MockRead(SYNCHRONOUS, ERR_UNEXPECTED);
68 MockRead result = reads_.front();
69 if (short_read_limit_ == 0 || result.data_len <= short_read_limit_) {
70 reads_.pop_front();
71 } else {
72 result.data_len = short_read_limit_;
73 reads_.front().data += result.data_len;
74 reads_.front().data_len -= result.data_len;
76 return result;
79 MockWriteResult OnWrite(const std::string& data) override {
80 if (InjectFault())
81 return MockWriteResult(ASYNC, data.length());
82 switch (state()) {
83 case PRE_USER:
84 return Verify("USER anonymous\r\n", data, PRE_PASSWD,
85 "331 Password needed\r\n");
86 case PRE_PASSWD:
88 static const char response_one[] = "230 Welcome\r\n";
89 static const char response_multi[] =
90 "230- One\r\n230- Two\r\n230 Three\r\n";
91 return Verify("PASS chrome@example.com\r\n", data, PRE_SYST,
92 multiline_welcome_ ? response_multi : response_one);
94 case PRE_SYST:
95 return Verify("SYST\r\n", data, PRE_PWD, "215 UNIX\r\n");
96 case PRE_PWD:
97 return Verify("PWD\r\n", data, PRE_TYPE,
98 "257 \"/\" is your current location\r\n");
99 case PRE_TYPE:
100 return Verify(std::string("TYPE ") + data_type_ + "\r\n", data,
101 PRE_SIZE, "200 TYPE set successfully\r\n");
102 case PRE_LIST_EPSV:
103 return Verify("EPSV\r\n", data, PRE_LIST,
104 "227 Entering Extended Passive Mode (|||31744|)\r\n");
105 case PRE_LIST_PASV:
106 return Verify("PASV\r\n", data, PRE_LIST,
107 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
108 case PRE_RETR_EPSV:
109 return Verify("EPSV\r\n", data, PRE_RETR,
110 "227 Entering Extended Passive Mode (|||31744|)\r\n");
111 case PRE_RETR_PASV:
112 return Verify("PASV\r\n", data, PRE_RETR,
113 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
114 case PRE_NOPASV:
115 // Use unallocated 599 FTP error code to make sure it falls into the
116 // generic ERR_FTP_FAILED bucket.
117 return Verify("PASV\r\n", data, PRE_QUIT,
118 "599 fail\r\n");
119 case PRE_QUIT:
120 return Verify("QUIT\r\n", data, QUIT, "221 Goodbye.\r\n");
121 default:
122 NOTREACHED() << "State not handled " << state();
123 return MockWriteResult(ASYNC, ERR_UNEXPECTED);
127 void InjectFailure(State state, State next_state, const char* response) {
128 DCHECK_EQ(NONE, failure_injection_state_);
129 DCHECK_NE(NONE, state);
130 DCHECK_NE(NONE, next_state);
131 DCHECK_NE(state, next_state);
132 failure_injection_state_ = state;
133 failure_injection_next_state_ = next_state;
134 fault_response_ = response;
137 State state() const {
138 return state_;
141 void Reset() override {
142 reads_.clear();
143 Init();
146 bool AllReadDataConsumed() const override { return state_ == QUIT; }
148 bool AllWriteDataConsumed() const override { return state_ == QUIT; }
150 void set_multiline_welcome(bool multiline) { multiline_welcome_ = multiline; }
152 bool use_epsv() const { return use_epsv_; }
153 void set_use_epsv(bool use_epsv) { use_epsv_ = use_epsv; }
155 void set_data_type(char data_type) { data_type_ = data_type; }
157 int short_read_limit() const { return short_read_limit_; }
158 void set_short_read_limit(int limit) { short_read_limit_ = limit; }
160 void set_allow_unconsumed_reads(bool allow) {
161 allow_unconsumed_reads_ = allow;
164 protected:
165 void Init() {
166 state_ = PRE_USER;
167 SimulateRead("220 host TestFTPd\r\n");
170 // If protocol fault injection has been requested, adjusts state and mocked
171 // read and returns true.
172 bool InjectFault() {
173 if (state_ != failure_injection_state_)
174 return false;
175 SimulateRead(fault_response_);
176 state_ = failure_injection_next_state_;
177 return true;
180 MockWriteResult Verify(const std::string& expected,
181 const std::string& data,
182 State next_state,
183 const char* next_read,
184 const size_t next_read_length) {
185 EXPECT_EQ(expected, data);
186 if (expected == data) {
187 state_ = next_state;
188 SimulateRead(next_read, next_read_length);
189 return MockWriteResult(ASYNC, data.length());
191 return MockWriteResult(ASYNC, ERR_UNEXPECTED);
194 MockWriteResult Verify(const std::string& expected,
195 const std::string& data,
196 State next_state,
197 const char* next_read) {
198 return Verify(expected, data, next_state,
199 next_read, std::strlen(next_read));
202 // The next time there is a read from this socket, it will return |data|.
203 // Before calling SimulateRead next time, the previous data must be consumed.
204 void SimulateRead(const char* data, size_t length) {
205 if (!allow_unconsumed_reads_) {
206 EXPECT_TRUE(reads_.empty()) << "Unconsumed read: " << reads_.front().data;
208 reads_.push_back(MockRead(ASYNC, data, length));
210 void SimulateRead(const char* data) { SimulateRead(data, std::strlen(data)); }
212 private:
213 // List of reads to be consumed.
214 std::deque<MockRead> reads_;
216 // Max number of bytes we will read at a time. 0 means no limit.
217 int short_read_limit_;
219 // If true, we'll not require the client to consume all data before we
220 // mock the next read.
221 bool allow_unconsumed_reads_;
223 State state_;
224 State failure_injection_state_;
225 State failure_injection_next_state_;
226 const char* fault_response_;
228 // If true, we will send multiple 230 lines as response after PASS.
229 bool multiline_welcome_;
231 // If true, we will use EPSV command.
232 bool use_epsv_;
234 // Data type to be used for TYPE command.
235 char data_type_;
237 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider);
240 class FtpSocketDataProviderDirectoryListing : public FtpSocketDataProvider {
241 public:
242 FtpSocketDataProviderDirectoryListing() {
245 MockWriteResult OnWrite(const std::string& data) override {
246 if (InjectFault())
247 return MockWriteResult(ASYNC, data.length());
248 switch (state()) {
249 case PRE_SIZE:
250 return Verify("SIZE /\r\n", data, PRE_CWD,
251 "550 I can only retrieve regular files\r\n");
252 case PRE_CWD:
253 return Verify("CWD /\r\n", data,
254 use_epsv() ? PRE_LIST_EPSV : PRE_LIST_PASV, "200 OK\r\n");
255 case PRE_LIST:
256 return Verify("LIST -l\r\n", data, PRE_QUIT, "200 OK\r\n");
257 default:
258 return FtpSocketDataProvider::OnWrite(data);
262 private:
263 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing);
266 class FtpSocketDataProviderDirectoryListingWithPasvFallback
267 : public FtpSocketDataProviderDirectoryListing {
268 public:
269 FtpSocketDataProviderDirectoryListingWithPasvFallback() {
272 MockWriteResult OnWrite(const std::string& data) override {
273 if (InjectFault())
274 return MockWriteResult(ASYNC, data.length());
275 switch (state()) {
276 case PRE_LIST_EPSV:
277 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
278 "500 no EPSV for you\r\n");
279 case PRE_SIZE:
280 return Verify("SIZE /\r\n", data, PRE_CWD,
281 "550 I can only retrieve regular files\r\n");
282 default:
283 return FtpSocketDataProviderDirectoryListing::OnWrite(data);
287 private:
288 DISALLOW_COPY_AND_ASSIGN(
289 FtpSocketDataProviderDirectoryListingWithPasvFallback);
292 class FtpSocketDataProviderDirectoryListingZeroSize
293 : public FtpSocketDataProviderDirectoryListing {
294 public:
295 FtpSocketDataProviderDirectoryListingZeroSize() {
298 MockWriteResult OnWrite(const std::string& data) override {
299 if (InjectFault())
300 return MockWriteResult(ASYNC, data.length());
301 switch (state()) {
302 case PRE_SIZE:
303 return Verify("SIZE /\r\n", data, PRE_CWD, "213 0\r\n");
304 default:
305 return FtpSocketDataProviderDirectoryListing::OnWrite(data);
309 private:
310 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize);
313 class FtpSocketDataProviderVMSDirectoryListing : public FtpSocketDataProvider {
314 public:
315 FtpSocketDataProviderVMSDirectoryListing() {
318 MockWriteResult OnWrite(const std::string& data) override {
319 if (InjectFault())
320 return MockWriteResult(ASYNC, data.length());
321 switch (state()) {
322 case PRE_SYST:
323 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
324 case PRE_PWD:
325 return Verify("PWD\r\n", data, PRE_TYPE,
326 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
327 case PRE_LIST_EPSV:
328 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
329 "500 Invalid command\r\n");
330 case PRE_SIZE:
331 return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_CWD,
332 "550 I can only retrieve regular files\r\n");
333 case PRE_CWD:
334 return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data,
335 use_epsv() ? PRE_LIST_EPSV : PRE_LIST_PASV, "200 OK\r\n");
336 case PRE_LIST:
337 return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
338 default:
339 return FtpSocketDataProvider::OnWrite(data);
343 private:
344 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing);
347 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
348 : public FtpSocketDataProvider {
349 public:
350 FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
353 MockWriteResult OnWrite(const std::string& data) override {
354 if (InjectFault())
355 return MockWriteResult(ASYNC, data.length());
356 switch (state()) {
357 case PRE_SYST:
358 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
359 case PRE_PWD:
360 return Verify("PWD\r\n", data, PRE_TYPE,
361 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
362 case PRE_LIST_EPSV:
363 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
364 "500 EPSV command unknown\r\n");
365 case PRE_SIZE:
366 return Verify("SIZE ANONYMOUS_ROOT\r\n", data, PRE_CWD,
367 "550 I can only retrieve regular files\r\n");
368 case PRE_CWD:
369 return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data,
370 use_epsv() ? PRE_LIST_EPSV : PRE_LIST_PASV, "200 OK\r\n");
371 case PRE_LIST:
372 return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
373 default:
374 return FtpSocketDataProvider::OnWrite(data);
378 private:
379 DISALLOW_COPY_AND_ASSIGN(
380 FtpSocketDataProviderVMSDirectoryListingRootDirectory);
383 class FtpSocketDataProviderFileDownloadWithFileTypecode
384 : public FtpSocketDataProvider {
385 public:
386 FtpSocketDataProviderFileDownloadWithFileTypecode() {
389 MockWriteResult OnWrite(const std::string& data) override {
390 if (InjectFault())
391 return MockWriteResult(ASYNC, data.length());
392 switch (state()) {
393 case PRE_SIZE:
394 return Verify("SIZE /file\r\n", data,
395 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV, "213 18\r\n");
396 case PRE_RETR:
397 return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n");
398 default:
399 return FtpSocketDataProvider::OnWrite(data);
403 private:
404 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode);
407 class FtpSocketDataProviderFileDownload : public FtpSocketDataProvider {
408 public:
409 FtpSocketDataProviderFileDownload() {
412 MockWriteResult OnWrite(const std::string& data) override {
413 if (InjectFault())
414 return MockWriteResult(ASYNC, data.length());
415 switch (state()) {
416 case PRE_SIZE:
417 return Verify("SIZE /file\r\n", data, PRE_CWD, "213 18\r\n");
418 case PRE_CWD:
419 return Verify("CWD /file\r\n", data,
420 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
421 "550 Not a directory\r\n");
422 case PRE_RETR:
423 return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n");
424 default:
425 return FtpSocketDataProvider::OnWrite(data);
429 private:
430 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload);
433 class FtpSocketDataProviderFileNotFound : public FtpSocketDataProvider {
434 public:
435 FtpSocketDataProviderFileNotFound() {
438 MockWriteResult OnWrite(const std::string& data) override {
439 if (InjectFault())
440 return MockWriteResult(ASYNC, data.length());
441 switch (state()) {
442 case PRE_SIZE:
443 return Verify("SIZE /file\r\n", data, PRE_CWD,
444 "550 File Not Found\r\n");
445 case PRE_CWD:
446 return Verify("CWD /file\r\n", data,
447 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
448 "550 File Not Found\r\n");
449 case PRE_RETR:
450 return Verify("RETR /file\r\n", data, PRE_QUIT,
451 "550 File Not Found\r\n");
452 default:
453 return FtpSocketDataProvider::OnWrite(data);
457 private:
458 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound);
461 class FtpSocketDataProviderFileDownloadWithPasvFallback
462 : public FtpSocketDataProviderFileDownload {
463 public:
464 FtpSocketDataProviderFileDownloadWithPasvFallback() {
467 MockWriteResult OnWrite(const std::string& data) override {
468 if (InjectFault())
469 return MockWriteResult(ASYNC, data.length());
470 switch (state()) {
471 case PRE_RETR_EPSV:
472 return Verify("EPSV\r\n", data, PRE_RETR_PASV, "500 No can do\r\n");
473 case PRE_CWD:
474 return Verify("CWD /file\r\n", data,
475 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
476 "550 Not a directory\r\n");
477 default:
478 return FtpSocketDataProviderFileDownload::OnWrite(data);
482 private:
483 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback);
486 class FtpSocketDataProviderFileDownloadZeroSize
487 : public FtpSocketDataProviderFileDownload {
488 public:
489 FtpSocketDataProviderFileDownloadZeroSize() {
492 MockWriteResult OnWrite(const std::string& data) override {
493 if (InjectFault())
494 return MockWriteResult(ASYNC, data.length());
495 switch (state()) {
496 case PRE_SIZE:
497 return Verify("SIZE /file\r\n", data, PRE_CWD,
498 "213 0\r\n");
499 case PRE_CWD:
500 return Verify("CWD /file\r\n", data,
501 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
502 "550 not a directory\r\n");
503 default:
504 return FtpSocketDataProviderFileDownload::OnWrite(data);
508 private:
509 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize);
512 class FtpSocketDataProviderFileDownloadCWD451
513 : public FtpSocketDataProviderFileDownload {
514 public:
515 FtpSocketDataProviderFileDownloadCWD451() {
518 MockWriteResult OnWrite(const std::string& data) override {
519 if (InjectFault())
520 return MockWriteResult(ASYNC, data.length());
521 switch (state()) {
522 case PRE_CWD:
523 return Verify("CWD /file\r\n", data,
524 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
525 "451 not a directory\r\n");
526 default:
527 return FtpSocketDataProviderFileDownload::OnWrite(data);
531 private:
532 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451);
535 class FtpSocketDataProviderVMSFileDownload : public FtpSocketDataProvider {
536 public:
537 FtpSocketDataProviderVMSFileDownload() {
540 MockWriteResult OnWrite(const std::string& data) override {
541 if (InjectFault())
542 return MockWriteResult(ASYNC, data.length());
543 switch (state()) {
544 case PRE_SYST:
545 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
546 case PRE_PWD:
547 return Verify("PWD\r\n", data, PRE_TYPE,
548 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
549 case PRE_LIST_EPSV:
550 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
551 "500 EPSV command unknown\r\n");
552 case PRE_SIZE:
553 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_CWD,
554 "213 18\r\n");
555 case PRE_CWD:
556 return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data,
557 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
558 "550 Not a directory\r\n");
559 case PRE_RETR:
560 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_QUIT,
561 "200 OK\r\n");
562 default:
563 return FtpSocketDataProvider::OnWrite(data);
567 private:
568 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload);
571 class FtpSocketDataProviderEscaping : public FtpSocketDataProviderFileDownload {
572 public:
573 FtpSocketDataProviderEscaping() {
576 MockWriteResult OnWrite(const std::string& data) override {
577 if (InjectFault())
578 return MockWriteResult(ASYNC, data.length());
579 switch (state()) {
580 case PRE_SIZE:
581 return Verify("SIZE / !\"#$%y\200\201\r\n", data, PRE_CWD,
582 "213 18\r\n");
583 case PRE_CWD:
584 return Verify("CWD / !\"#$%y\200\201\r\n", data,
585 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
586 "550 Not a directory\r\n");
587 case PRE_RETR:
588 return Verify("RETR / !\"#$%y\200\201\r\n", data, PRE_QUIT,
589 "200 OK\r\n");
590 default:
591 return FtpSocketDataProviderFileDownload::OnWrite(data);
595 private:
596 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping);
599 class FtpSocketDataProviderFileDownloadTransferStarting
600 : public FtpSocketDataProviderFileDownload {
601 public:
602 FtpSocketDataProviderFileDownloadTransferStarting() {
605 MockWriteResult OnWrite(const std::string& data) override {
606 if (InjectFault())
607 return MockWriteResult(ASYNC, data.length());
608 switch (state()) {
609 case PRE_RETR:
610 return Verify("RETR /file\r\n", data, PRE_QUIT,
611 "125-Data connection already open.\r\n"
612 "125 Transfer starting.\r\n"
613 "226 Transfer complete.\r\n");
614 default:
615 return FtpSocketDataProviderFileDownload::OnWrite(data);
619 private:
620 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting);
623 class FtpSocketDataProviderDirectoryListingTransferStarting
624 : public FtpSocketDataProviderDirectoryListing {
625 public:
626 FtpSocketDataProviderDirectoryListingTransferStarting() {
629 MockWriteResult OnWrite(const std::string& data) override {
630 if (InjectFault())
631 return MockWriteResult(ASYNC, data.length());
632 switch (state()) {
633 case PRE_LIST:
634 return Verify("LIST -l\r\n", data, PRE_QUIT,
635 "125-Data connection already open.\r\n"
636 "125 Transfer starting.\r\n"
637 "226 Transfer complete.\r\n");
638 default:
639 return FtpSocketDataProviderDirectoryListing::OnWrite(data);
643 private:
644 DISALLOW_COPY_AND_ASSIGN(
645 FtpSocketDataProviderDirectoryListingTransferStarting);
648 class FtpSocketDataProviderFileDownloadInvalidResponse
649 : public FtpSocketDataProviderFileDownload {
650 public:
651 FtpSocketDataProviderFileDownloadInvalidResponse() {
654 MockWriteResult OnWrite(const std::string& data) override {
655 if (InjectFault())
656 return MockWriteResult(ASYNC, data.length());
657 switch (state()) {
658 case PRE_SIZE:
659 // Use unallocated 599 FTP error code to make sure it falls into the
660 // generic ERR_FTP_FAILED bucket.
661 return Verify("SIZE /file\r\n", data, PRE_QUIT,
662 "599 Evil Response\r\n"
663 "599 More Evil\r\n");
664 default:
665 return FtpSocketDataProviderFileDownload::OnWrite(data);
669 private:
670 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse);
673 class FtpSocketDataProviderEvilEpsv : public FtpSocketDataProviderFileDownload {
674 public:
675 FtpSocketDataProviderEvilEpsv(const char* epsv_response,
676 State expected_state)
677 : epsv_response_(epsv_response),
678 epsv_response_length_(std::strlen(epsv_response)),
679 expected_state_(expected_state) {}
681 FtpSocketDataProviderEvilEpsv(const char* epsv_response,
682 size_t epsv_response_length,
683 State expected_state)
684 : epsv_response_(epsv_response),
685 epsv_response_length_(epsv_response_length),
686 expected_state_(expected_state) {}
688 MockWriteResult OnWrite(const std::string& data) override {
689 if (InjectFault())
690 return MockWriteResult(ASYNC, data.length());
691 switch (state()) {
692 case PRE_RETR_EPSV:
693 return Verify("EPSV\r\n", data, expected_state_,
694 epsv_response_, epsv_response_length_);
695 default:
696 return FtpSocketDataProviderFileDownload::OnWrite(data);
700 private:
701 const char* epsv_response_;
702 const size_t epsv_response_length_;
703 const State expected_state_;
705 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv);
708 class FtpSocketDataProviderEvilPasv
709 : public FtpSocketDataProviderFileDownloadWithPasvFallback {
710 public:
711 FtpSocketDataProviderEvilPasv(const char* pasv_response, State expected_state)
712 : pasv_response_(pasv_response),
713 expected_state_(expected_state) {
716 MockWriteResult OnWrite(const std::string& data) override {
717 if (InjectFault())
718 return MockWriteResult(ASYNC, data.length());
719 switch (state()) {
720 case PRE_RETR_PASV:
721 return Verify("PASV\r\n", data, expected_state_, pasv_response_);
722 default:
723 return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data);
727 private:
728 const char* pasv_response_;
729 const State expected_state_;
731 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv);
734 class FtpSocketDataProviderEvilSize : public FtpSocketDataProviderFileDownload {
735 public:
736 FtpSocketDataProviderEvilSize(const char* size_response, State expected_state)
737 : size_response_(size_response),
738 expected_state_(expected_state) {
741 MockWriteResult OnWrite(const std::string& data) override {
742 if (InjectFault())
743 return MockWriteResult(ASYNC, data.length());
744 switch (state()) {
745 case PRE_SIZE:
746 return Verify("SIZE /file\r\n", data, expected_state_, size_response_);
747 default:
748 return FtpSocketDataProviderFileDownload::OnWrite(data);
752 private:
753 const char* size_response_;
754 const State expected_state_;
756 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize);
759 class FtpSocketDataProviderEvilLogin
760 : public FtpSocketDataProviderFileDownload {
761 public:
762 FtpSocketDataProviderEvilLogin(const char* expected_user,
763 const char* expected_password)
764 : expected_user_(expected_user),
765 expected_password_(expected_password) {
768 MockWriteResult OnWrite(const std::string& data) override {
769 if (InjectFault())
770 return MockWriteResult(ASYNC, data.length());
771 switch (state()) {
772 case PRE_USER:
773 return Verify(std::string("USER ") + expected_user_ + "\r\n", data,
774 PRE_PASSWD, "331 Password needed\r\n");
775 case PRE_PASSWD:
776 return Verify(std::string("PASS ") + expected_password_ + "\r\n", data,
777 PRE_SYST, "230 Welcome\r\n");
778 default:
779 return FtpSocketDataProviderFileDownload::OnWrite(data);
783 private:
784 const char* expected_user_;
785 const char* expected_password_;
787 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin);
790 class FtpSocketDataProviderCloseConnection : public FtpSocketDataProvider {
791 public:
792 FtpSocketDataProviderCloseConnection() {
795 MockWriteResult OnWrite(const std::string& data) override {
796 if (InjectFault())
797 return MockWriteResult(ASYNC, data.length());
798 switch (state()) {
799 case PRE_USER:
800 return Verify("USER anonymous\r\n", data,
801 PRE_QUIT, "");
802 default:
803 return FtpSocketDataProvider::OnWrite(data);
807 private:
808 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection);
811 class FtpNetworkTransactionTest
812 : public PlatformTest,
813 public ::testing::WithParamInterface<int> {
814 public:
815 FtpNetworkTransactionTest()
816 : host_resolver_(new MockHostResolver),
817 transaction_(host_resolver_.get(), &mock_socket_factory_) {
818 scoped_refptr<RuleBasedHostResolverProc> rules(
819 new RuleBasedHostResolverProc(NULL));
820 if (GetFamily() == AF_INET) {
821 rules->AddIPLiteralRule("*", "127.0.0.1", "127.0.0.1");
822 } else if (GetFamily() == AF_INET6) {
823 rules->AddIPLiteralRule("*", "::1", "::1");
824 } else {
825 NOTREACHED();
827 host_resolver_->set_rules(rules.get());
830 protected:
831 // Accessor to make code refactoring-friendly, e.g. when we change the way
832 // parameters are passed (like more parameters).
833 int GetFamily() {
834 return GetParam();
837 FtpRequestInfo GetRequestInfo(const std::string& url) {
838 FtpRequestInfo info;
839 info.url = GURL(url);
840 return info;
843 void ExecuteTransaction(FtpSocketDataProvider* ctrl_socket,
844 const char* request,
845 int expected_result) {
846 // Expect EPSV usage for non-IPv4 control connections.
847 ctrl_socket->set_use_epsv((GetFamily() != AF_INET));
849 mock_socket_factory_.AddSocketDataProvider(ctrl_socket);
851 std::string mock_data("mock-data");
852 MockRead data_reads[] = {
853 // Usually FTP servers close the data connection after the entire data has
854 // been received.
855 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
856 MockRead(mock_data.c_str()),
859 scoped_ptr<StaticSocketDataProvider> data_socket(
860 new StaticSocketDataProvider(data_reads, arraysize(data_reads), NULL,
861 0));
862 mock_socket_factory_.AddSocketDataProvider(data_socket.get());
863 FtpRequestInfo request_info = GetRequestInfo(request);
864 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
865 ASSERT_EQ(ERR_IO_PENDING,
866 transaction_.Start(&request_info, callback_.callback(),
867 BoundNetLog()));
868 EXPECT_NE(LOAD_STATE_IDLE, transaction_.GetLoadState());
869 ASSERT_EQ(expected_result, callback_.WaitForResult());
870 if (expected_result == OK) {
871 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(kBufferSize));
872 memset(io_buffer->data(), 0, kBufferSize);
873 ASSERT_EQ(ERR_IO_PENDING,
874 transaction_.Read(io_buffer.get(), kBufferSize,
875 callback_.callback()));
876 ASSERT_EQ(static_cast<int>(mock_data.length()),
877 callback_.WaitForResult());
878 EXPECT_EQ(mock_data, std::string(io_buffer->data(), mock_data.length()));
880 // Do another Read to detect that the data socket is now closed.
881 int rv = transaction_.Read(io_buffer.get(), kBufferSize,
882 callback_.callback());
883 if (rv == ERR_IO_PENDING) {
884 EXPECT_EQ(0, callback_.WaitForResult());
885 } else {
886 EXPECT_EQ(0, rv);
889 EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket->state());
890 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
893 void TransactionFailHelper(FtpSocketDataProvider* ctrl_socket,
894 const char* request,
895 FtpSocketDataProvider::State state,
896 FtpSocketDataProvider::State next_state,
897 const char* response,
898 int expected_result) {
899 ctrl_socket->InjectFailure(state, next_state, response);
900 ExecuteTransaction(ctrl_socket, request, expected_result);
903 scoped_ptr<MockHostResolver> host_resolver_;
904 MockClientSocketFactory mock_socket_factory_;
905 FtpNetworkTransaction transaction_;
906 TestCompletionCallback callback_;
909 TEST_P(FtpNetworkTransactionTest, FailedLookup) {
910 FtpRequestInfo request_info = GetRequestInfo("ftp://badhost");
911 scoped_refptr<RuleBasedHostResolverProc> rules(
912 new RuleBasedHostResolverProc(NULL));
913 rules->AddSimulatedFailure("badhost");
914 host_resolver_->set_rules(rules.get());
916 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
917 ASSERT_EQ(ERR_IO_PENDING,
918 transaction_.Start(&request_info, callback_.callback(),
919 BoundNetLog()));
920 ASSERT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
921 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
924 // Check that when determining the host, the square brackets decorating IPv6
925 // literals in URLs are stripped.
926 TEST_P(FtpNetworkTransactionTest, StripBracketsFromIPv6Literals) {
927 // This test only makes sense for IPv6 connections.
928 if (GetFamily() != AF_INET6)
929 return;
931 host_resolver_->rules()->AddSimulatedFailure("[::1]");
933 // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE.
934 // The important part of this test is to make sure that we don't fail with
935 // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname
936 // was used.
937 FtpSocketDataProviderEvilSize ctrl_socket(
938 "213 99999999999999999999999999999999\r\n",
939 FtpSocketDataProvider::PRE_QUIT);
940 ExecuteTransaction(&ctrl_socket, "ftp://[::1]/file", ERR_INVALID_RESPONSE);
943 TEST_P(FtpNetworkTransactionTest, DirectoryTransaction) {
944 FtpSocketDataProviderDirectoryListing ctrl_socket;
945 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
947 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
948 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
949 EXPECT_EQ((GetFamily() == AF_INET) ? "127.0.0.1" : "::1",
950 transaction_.GetResponseInfo()->socket_address.host());
951 EXPECT_EQ(21, transaction_.GetResponseInfo()->socket_address.port());
954 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithPasvFallback) {
955 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket;
956 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
958 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
959 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
962 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithTypecode) {
963 FtpSocketDataProviderDirectoryListing ctrl_socket;
964 ExecuteTransaction(&ctrl_socket, "ftp://host/;type=d", OK);
966 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
967 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
970 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcome) {
971 FtpSocketDataProviderDirectoryListing ctrl_socket;
972 ctrl_socket.set_multiline_welcome(true);
973 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
976 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads2) {
977 FtpSocketDataProviderDirectoryListing ctrl_socket;
978 ctrl_socket.set_short_read_limit(2);
979 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
982 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) {
983 FtpSocketDataProviderDirectoryListing ctrl_socket;
984 ctrl_socket.set_short_read_limit(5);
985 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
988 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcomeShort) {
989 FtpSocketDataProviderDirectoryListing ctrl_socket;
990 // The client will not consume all three 230 lines. That's good, we want to
991 // test that scenario.
992 ctrl_socket.set_allow_unconsumed_reads(true);
993 ctrl_socket.set_multiline_welcome(true);
994 ctrl_socket.set_short_read_limit(5);
995 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
998 // Regression test for http://crbug.com/60555.
999 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) {
1000 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket;
1001 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
1004 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMS) {
1005 FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
1006 ExecuteTransaction(&ctrl_socket, "ftp://host/dir", OK);
1009 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) {
1010 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket;
1011 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
1014 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) {
1015 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket;
1016 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
1019 TEST_P(FtpNetworkTransactionTest, DownloadTransaction) {
1020 FtpSocketDataProviderFileDownload ctrl_socket;
1021 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1023 // We pass an artificial value of 18 as a response to the SIZE command.
1024 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1025 EXPECT_EQ((GetFamily() == AF_INET) ? "127.0.0.1" : "::1",
1026 transaction_.GetResponseInfo()->socket_address.host());
1027 EXPECT_EQ(21, transaction_.GetResponseInfo()->socket_address.port());
1030 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithPasvFallback) {
1031 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket;
1032 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1034 // We pass an artificial value of 18 as a response to the SIZE command.
1035 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1038 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeA) {
1039 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket;
1040 ctrl_socket.set_data_type('A');
1041 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=a", OK);
1043 // We pass an artificial value of 18 as a response to the SIZE command.
1044 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1047 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeI) {
1048 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket;
1049 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=i", OK);
1051 // We pass an artificial value of 18 as a response to the SIZE command.
1052 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1055 TEST_P(FtpNetworkTransactionTest, DownloadTransactionMultilineWelcome) {
1056 FtpSocketDataProviderFileDownload ctrl_socket;
1057 ctrl_socket.set_multiline_welcome(true);
1058 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1061 TEST_P(FtpNetworkTransactionTest, DownloadTransactionShortReads2) {
1062 FtpSocketDataProviderFileDownload ctrl_socket;
1063 ctrl_socket.set_short_read_limit(2);
1064 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1067 TEST_P(FtpNetworkTransactionTest, DownloadTransactionShortReads5) {
1068 FtpSocketDataProviderFileDownload ctrl_socket;
1069 ctrl_socket.set_short_read_limit(5);
1070 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1073 TEST_P(FtpNetworkTransactionTest, DownloadTransactionZeroSize) {
1074 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket;
1075 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1078 TEST_P(FtpNetworkTransactionTest, DownloadTransactionCWD451) {
1079 FtpSocketDataProviderFileDownloadCWD451 ctrl_socket;
1080 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1083 TEST_P(FtpNetworkTransactionTest, DownloadTransactionVMS) {
1084 FtpSocketDataProviderVMSFileDownload ctrl_socket;
1085 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1088 TEST_P(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) {
1089 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket;
1090 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1093 TEST_P(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) {
1094 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket;
1095 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1098 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvReallyBadFormat) {
1099 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,\r\n",
1100 FtpSocketDataProvider::PRE_QUIT);
1101 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1104 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort1) {
1105 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
1106 FtpSocketDataProvider::PRE_QUIT);
1107 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1110 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort2) {
1111 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
1112 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
1113 FtpSocketDataProvider::PRE_QUIT);
1114 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1117 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort3) {
1118 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
1119 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
1120 FtpSocketDataProvider::PRE_QUIT);
1121 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1124 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort4) {
1125 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
1126 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
1127 FtpSocketDataProvider::PRE_QUIT);
1128 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1131 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafeHost) {
1132 FtpSocketDataProviderEvilPasv ctrl_socket(
1133 "227 Portscan (10,1,2,3,123,456)\r\n", FtpSocketDataProvider::PRE_RETR);
1134 ctrl_socket.set_use_epsv(GetFamily() != AF_INET);
1135 std::string mock_data("mock-data");
1136 MockRead data_reads[] = {
1137 MockRead(mock_data.c_str()),
1139 StaticSocketDataProvider data_socket1;
1140 StaticSocketDataProvider data_socket2(data_reads, arraysize(data_reads),
1141 NULL, 0);
1142 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket);
1143 mock_socket_factory_.AddSocketDataProvider(&data_socket1);
1144 mock_socket_factory_.AddSocketDataProvider(&data_socket2);
1145 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1147 // Start the transaction.
1148 ASSERT_EQ(ERR_IO_PENDING,
1149 transaction_.Start(&request_info, callback_.callback(),
1150 BoundNetLog()));
1151 ASSERT_EQ(OK, callback_.WaitForResult());
1153 // The transaction fires the callback when we can start reading data. That
1154 // means that the data socket should be open.
1155 MockTCPClientSocket* data_socket =
1156 static_cast<MockTCPClientSocket*>(transaction_.data_socket_.get());
1157 ASSERT_TRUE(data_socket);
1158 ASSERT_TRUE(data_socket->IsConnected());
1160 // Even if the PASV response specified some other address, we connect
1161 // to the address we used for control connection (which could be 127.0.0.1
1162 // or ::1 depending on whether we use IPv6).
1163 for (AddressList::const_iterator it = data_socket->addresses().begin();
1164 it != data_socket->addresses().end(); ++it) {
1165 EXPECT_NE("10.1.2.3", it->ToStringWithoutPort());
1169 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat1) {
1170 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1171 if (GetFamily() == AF_INET)
1172 return;
1174 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22)\r\n",
1175 FtpSocketDataProvider::PRE_QUIT);
1176 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1179 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat2) {
1180 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1181 if (GetFamily() == AF_INET)
1182 return;
1184 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||\r\n",
1185 FtpSocketDataProvider::PRE_QUIT);
1186 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1189 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat3) {
1190 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1191 if (GetFamily() == AF_INET)
1192 return;
1194 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan\r\n",
1195 FtpSocketDataProvider::PRE_QUIT);
1196 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1199 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat4) {
1200 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1201 if (GetFamily() == AF_INET)
1202 return;
1204 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||||)\r\n",
1205 FtpSocketDataProvider::PRE_QUIT);
1206 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1209 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat5) {
1210 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1211 if (GetFamily() == AF_INET)
1212 return;
1214 // Breaking the string in the next line prevents MSVC warning C4125.
1215 const char response[] = "227 Portscan (\0\0\031" "773\0)\r\n";
1216 FtpSocketDataProviderEvilEpsv ctrl_socket(response, sizeof(response)-1,
1217 FtpSocketDataProvider::PRE_QUIT);
1218 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1221 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort1) {
1222 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1223 if (GetFamily() == AF_INET)
1224 return;
1226 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22|)\r\n",
1227 FtpSocketDataProvider::PRE_QUIT);
1228 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1231 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort2) {
1232 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1233 if (GetFamily() == AF_INET)
1234 return;
1236 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||258|)\r\n",
1237 FtpSocketDataProvider::PRE_QUIT);
1238 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1241 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort3) {
1242 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1243 if (GetFamily() == AF_INET)
1244 return;
1246 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||772|)\r\n",
1247 FtpSocketDataProvider::PRE_QUIT);
1248 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1251 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort4) {
1252 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1253 if (GetFamily() == AF_INET)
1254 return;
1256 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||2049|)\r\n",
1257 FtpSocketDataProvider::PRE_QUIT);
1258 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1261 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvWeirdSep) {
1262 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1263 if (GetFamily() == AF_INET)
1264 return;
1266 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$31744$)\r\n",
1267 FtpSocketDataProvider::PRE_RETR);
1268 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1271 TEST_P(FtpNetworkTransactionTest,
1272 DownloadTransactionEvilEpsvWeirdSepUnsafePort) {
1273 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1274 if (GetFamily() == AF_INET)
1275 return;
1277 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$317$)\r\n",
1278 FtpSocketDataProvider::PRE_QUIT);
1279 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1282 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvIllegalHost) {
1283 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1284 if (GetFamily() == AF_INET)
1285 return;
1287 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
1288 FtpSocketDataProvider::PRE_QUIT);
1289 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1292 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) {
1293 FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test");
1294 ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", OK);
1297 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) {
1298 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld");
1299 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", OK);
1302 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) {
1303 FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test");
1304 ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", OK);
1307 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) {
1308 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world");
1309 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", OK);
1312 TEST_P(FtpNetworkTransactionTest, EvilRestartUser) {
1313 FtpSocketDataProvider ctrl_socket1;
1314 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
1315 FtpSocketDataProvider::PRE_QUIT,
1316 "530 Login authentication failed\r\n");
1317 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
1319 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1321 ASSERT_EQ(ERR_IO_PENDING,
1322 transaction_.Start(&request_info, callback_.callback(),
1323 BoundNetLog()));
1324 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
1326 MockRead ctrl_reads[] = {
1327 MockRead("220 host TestFTPd\r\n"),
1328 MockRead("221 Goodbye!\r\n"),
1329 MockRead(SYNCHRONOUS, OK),
1331 MockWrite ctrl_writes[] = {
1332 MockWrite("QUIT\r\n"),
1334 StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
1335 ctrl_writes, arraysize(ctrl_writes));
1336 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
1337 ASSERT_EQ(ERR_IO_PENDING,
1338 transaction_.RestartWithAuth(
1339 AuthCredentials(
1340 base::ASCIIToUTF16("foo\nownz0red"),
1341 base::ASCIIToUTF16("innocent")),
1342 callback_.callback()));
1343 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
1346 TEST_P(FtpNetworkTransactionTest, EvilRestartPassword) {
1347 FtpSocketDataProvider ctrl_socket1;
1348 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
1349 FtpSocketDataProvider::PRE_QUIT,
1350 "530 Login authentication failed\r\n");
1351 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
1353 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1355 ASSERT_EQ(ERR_IO_PENDING,
1356 transaction_.Start(&request_info, callback_.callback(),
1357 BoundNetLog()));
1358 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
1360 MockRead ctrl_reads[] = {
1361 MockRead("220 host TestFTPd\r\n"),
1362 MockRead("331 User okay, send password\r\n"),
1363 MockRead("221 Goodbye!\r\n"),
1364 MockRead(SYNCHRONOUS, OK),
1366 MockWrite ctrl_writes[] = {
1367 MockWrite("USER innocent\r\n"),
1368 MockWrite("QUIT\r\n"),
1370 StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
1371 ctrl_writes, arraysize(ctrl_writes));
1372 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
1373 ASSERT_EQ(ERR_IO_PENDING,
1374 transaction_.RestartWithAuth(
1375 AuthCredentials(base::ASCIIToUTF16("innocent"),
1376 base::ASCIIToUTF16("foo\nownz0red")),
1377 callback_.callback()));
1378 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
1381 TEST_P(FtpNetworkTransactionTest, Escaping) {
1382 FtpSocketDataProviderEscaping ctrl_socket;
1383 ExecuteTransaction(&ctrl_socket, "ftp://host/%20%21%22%23%24%25%79%80%81",
1384 OK);
1387 // Test for http://crbug.com/23794.
1388 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilSize) {
1389 // Try to overflow int64 in the response.
1390 FtpSocketDataProviderEvilSize ctrl_socket(
1391 "213 99999999999999999999999999999999\r\n",
1392 FtpSocketDataProvider::PRE_QUIT);
1393 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1396 // Test for http://crbug.com/36360.
1397 TEST_P(FtpNetworkTransactionTest, DownloadTransactionBigSize) {
1398 // Pass a valid, but large file size. The transaction should not fail.
1399 FtpSocketDataProviderEvilSize ctrl_socket(
1400 "213 3204427776\r\n",
1401 FtpSocketDataProvider::PRE_CWD);
1402 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1403 EXPECT_EQ(3204427776LL,
1404 transaction_.GetResponseInfo()->expected_content_size);
1407 // Regression test for http://crbug.com/25023.
1408 TEST_P(FtpNetworkTransactionTest, CloseConnection) {
1409 FtpSocketDataProviderCloseConnection ctrl_socket;
1410 ExecuteTransaction(&ctrl_socket, "ftp://host", ERR_EMPTY_RESPONSE);
1413 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailUser) {
1414 FtpSocketDataProviderDirectoryListing ctrl_socket;
1415 // Use unallocated 599 FTP error code to make sure it falls into the generic
1416 // ERR_FTP_FAILED bucket.
1417 TransactionFailHelper(&ctrl_socket,
1418 "ftp://host",
1419 FtpSocketDataProvider::PRE_USER,
1420 FtpSocketDataProvider::PRE_QUIT,
1421 "599 fail\r\n",
1422 ERR_FTP_FAILED);
1425 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass) {
1426 FtpSocketDataProviderDirectoryListing ctrl_socket;
1427 TransactionFailHelper(&ctrl_socket,
1428 "ftp://host",
1429 FtpSocketDataProvider::PRE_PASSWD,
1430 FtpSocketDataProvider::PRE_QUIT,
1431 "530 Login authentication failed\r\n",
1432 ERR_FTP_FAILED);
1435 // Regression test for http://crbug.com/38707.
1436 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass503) {
1437 FtpSocketDataProviderDirectoryListing ctrl_socket;
1438 TransactionFailHelper(&ctrl_socket,
1439 "ftp://host",
1440 FtpSocketDataProvider::PRE_PASSWD,
1441 FtpSocketDataProvider::PRE_QUIT,
1442 "503 Bad sequence of commands\r\n",
1443 ERR_FTP_BAD_COMMAND_SEQUENCE);
1446 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailSyst) {
1447 FtpSocketDataProviderDirectoryListing ctrl_socket;
1448 // Use unallocated 599 FTP error code to make sure it falls into the generic
1449 // ERR_FTP_FAILED bucket.
1450 TransactionFailHelper(&ctrl_socket,
1451 "ftp://host",
1452 FtpSocketDataProvider::PRE_SYST,
1453 FtpSocketDataProvider::PRE_PWD,
1454 "599 fail\r\n",
1455 OK);
1458 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPwd) {
1459 FtpSocketDataProviderDirectoryListing ctrl_socket;
1460 // Use unallocated 599 FTP error code to make sure it falls into the generic
1461 // ERR_FTP_FAILED bucket.
1462 TransactionFailHelper(&ctrl_socket,
1463 "ftp://host",
1464 FtpSocketDataProvider::PRE_PWD,
1465 FtpSocketDataProvider::PRE_QUIT,
1466 "599 fail\r\n",
1467 ERR_FTP_FAILED);
1470 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailType) {
1471 FtpSocketDataProviderDirectoryListing ctrl_socket;
1472 // Use unallocated 599 FTP error code to make sure it falls into the generic
1473 // ERR_FTP_FAILED bucket.
1474 TransactionFailHelper(&ctrl_socket,
1475 "ftp://host",
1476 FtpSocketDataProvider::PRE_TYPE,
1477 FtpSocketDataProvider::PRE_QUIT,
1478 "599 fail\r\n",
1479 ERR_FTP_FAILED);
1482 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailEpsv) {
1483 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1484 if (GetFamily() == AF_INET)
1485 return;
1487 FtpSocketDataProviderDirectoryListing ctrl_socket;
1488 // Use unallocated 599 FTP error code to make sure it falls into the generic
1489 // ERR_FTP_FAILED bucket.
1490 TransactionFailHelper(
1491 &ctrl_socket, "ftp://host", FtpSocketDataProvider::PRE_LIST_EPSV,
1492 FtpSocketDataProvider::PRE_NOPASV, "599 fail\r\n", ERR_FTP_FAILED);
1495 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailCwd) {
1496 FtpSocketDataProviderDirectoryListing ctrl_socket;
1497 // Use unallocated 599 FTP error code to make sure it falls into the generic
1498 // ERR_FTP_FAILED bucket.
1499 TransactionFailHelper(&ctrl_socket,
1500 "ftp://host",
1501 FtpSocketDataProvider::PRE_CWD,
1502 FtpSocketDataProvider::PRE_QUIT,
1503 "599 fail\r\n",
1504 ERR_FTP_FAILED);
1507 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailList) {
1508 FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
1509 // Use unallocated 599 FTP error code to make sure it falls into the generic
1510 // ERR_FTP_FAILED bucket.
1511 TransactionFailHelper(&ctrl_socket,
1512 "ftp://host/dir",
1513 FtpSocketDataProvider::PRE_LIST,
1514 FtpSocketDataProvider::PRE_QUIT,
1515 "599 fail\r\n",
1516 ERR_FTP_FAILED);
1519 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailUser) {
1520 FtpSocketDataProviderFileDownload ctrl_socket;
1521 // Use unallocated 599 FTP error code to make sure it falls into the generic
1522 // ERR_FTP_FAILED bucket.
1523 TransactionFailHelper(&ctrl_socket,
1524 "ftp://host/file",
1525 FtpSocketDataProvider::PRE_USER,
1526 FtpSocketDataProvider::PRE_QUIT,
1527 "599 fail\r\n",
1528 ERR_FTP_FAILED);
1531 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPass) {
1532 FtpSocketDataProviderFileDownload ctrl_socket;
1533 TransactionFailHelper(&ctrl_socket,
1534 "ftp://host/file",
1535 FtpSocketDataProvider::PRE_PASSWD,
1536 FtpSocketDataProvider::PRE_QUIT,
1537 "530 Login authentication failed\r\n",
1538 ERR_FTP_FAILED);
1541 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailSyst) {
1542 FtpSocketDataProviderFileDownload ctrl_socket;
1543 // Use unallocated 599 FTP error code to make sure it falls into the generic
1544 // ERR_FTP_FAILED bucket.
1545 TransactionFailHelper(&ctrl_socket,
1546 "ftp://host/file",
1547 FtpSocketDataProvider::PRE_SYST,
1548 FtpSocketDataProvider::PRE_PWD,
1549 "599 fail\r\n",
1550 OK);
1553 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPwd) {
1554 FtpSocketDataProviderFileDownload ctrl_socket;
1555 // Use unallocated 599 FTP error code to make sure it falls into the generic
1556 // ERR_FTP_FAILED bucket.
1557 TransactionFailHelper(&ctrl_socket,
1558 "ftp://host/file",
1559 FtpSocketDataProvider::PRE_PWD,
1560 FtpSocketDataProvider::PRE_QUIT,
1561 "599 fail\r\n",
1562 ERR_FTP_FAILED);
1565 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailType) {
1566 FtpSocketDataProviderFileDownload ctrl_socket;
1567 // Use unallocated 599 FTP error code to make sure it falls into the generic
1568 // ERR_FTP_FAILED bucket.
1569 TransactionFailHelper(&ctrl_socket,
1570 "ftp://host/file",
1571 FtpSocketDataProvider::PRE_TYPE,
1572 FtpSocketDataProvider::PRE_QUIT,
1573 "599 fail\r\n",
1574 ERR_FTP_FAILED);
1577 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailEpsv) {
1578 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1579 if (GetFamily() == AF_INET)
1580 return;
1582 FtpSocketDataProviderFileDownload ctrl_socket;
1583 // Use unallocated 599 FTP error code to make sure it falls into the generic
1584 // ERR_FTP_FAILED bucket.
1585 TransactionFailHelper(
1586 &ctrl_socket, "ftp://host/file", FtpSocketDataProvider::PRE_RETR_EPSV,
1587 FtpSocketDataProvider::PRE_NOPASV, "599 fail\r\n", ERR_FTP_FAILED);
1590 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailRetr) {
1591 FtpSocketDataProviderFileDownload ctrl_socket;
1592 // Use unallocated 599 FTP error code to make sure it falls into the generic
1593 // ERR_FTP_FAILED bucket.
1594 TransactionFailHelper(&ctrl_socket,
1595 "ftp://host/file",
1596 FtpSocketDataProvider::PRE_RETR,
1597 FtpSocketDataProvider::PRE_QUIT,
1598 "599 fail\r\n",
1599 ERR_FTP_FAILED);
1602 TEST_P(FtpNetworkTransactionTest, FileNotFound) {
1603 FtpSocketDataProviderFileNotFound ctrl_socket;
1604 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_FTP_FAILED);
1607 // Test for http://crbug.com/38845.
1608 TEST_P(FtpNetworkTransactionTest, ZeroLengthDirInPWD) {
1609 FtpSocketDataProviderFileDownload ctrl_socket;
1610 TransactionFailHelper(&ctrl_socket,
1611 "ftp://host/file",
1612 FtpSocketDataProvider::PRE_PWD,
1613 FtpSocketDataProvider::PRE_TYPE,
1614 "257 \"\"\r\n",
1615 OK);
1618 INSTANTIATE_TEST_CASE_P(FTP,
1619 FtpNetworkTransactionTest,
1620 ::testing::Values(AF_INET, AF_INET6));
1622 } // namespace net