ftp_network_transaction_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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. 4 5#include "net/ftp/ftp_network_transaction.h" 6 7#include "build/build_config.h" 8 9#include "base/compiler_specific.h" 10#include "base/memory/ref_counted.h" 11#include "base/string_util.h" 12#include "base/utf_string_conversions.h" 13#include "net/base/host_port_pair.h" 14#include "net/base/io_buffer.h" 15#include "net/base/mock_host_resolver.h" 16#include "net/base/net_util.h" 17#include "net/base/test_completion_callback.h" 18#include "net/ftp/ftp_network_session.h" 19#include "net/ftp/ftp_request_info.h" 20#include "net/socket/socket_test_util.h" 21#include "testing/gtest/include/gtest/gtest.h" 22#include "testing/platform_test.h" 23 24namespace { 25 26// Size we use for IOBuffers used to receive data from the test data socket. 27const int kBufferSize = 128; 28 29} // namespace 30 31namespace net { 32 33class FtpSocketDataProvider : public DynamicSocketDataProvider { 34 public: 35 enum State { 36 NONE, 37 PRE_USER, 38 PRE_PASSWD, 39 PRE_SYST, 40 PRE_PWD, 41 PRE_TYPE, 42 PRE_SIZE, 43 PRE_EPSV, 44 PRE_PASV, 45 PRE_LIST, 46 PRE_RETR, 47 PRE_CWD, 48 PRE_QUIT, 49 PRE_NOPASV, 50 QUIT 51 }; 52 53 FtpSocketDataProvider() 54 : failure_injection_state_(NONE), 55 multiline_welcome_(false), 56 data_type_('I') { 57 Init(); 58 } 59 60 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 61 if (InjectFault()) 62 return MockWriteResult(ASYNC, data.length()); 63 switch (state()) { 64 case PRE_USER: 65 return Verify("USER anonymous\r\n", data, PRE_PASSWD, 66 "331 Password needed\r\n"); 67 case PRE_PASSWD: 68 { 69 const char* response_one = "230 Welcome\r\n"; 70 const char* response_multi = "230- One\r\n230- Two\r\n230 Three\r\n"; 71 return Verify("PASS chrome@example.com\r\n", data, PRE_SYST, 72 multiline_welcome_ ? response_multi : response_one); 73 } 74 case PRE_SYST: 75 return Verify("SYST\r\n", data, PRE_PWD, "215 UNIX\r\n"); 76 case PRE_PWD: 77 return Verify("PWD\r\n", data, PRE_TYPE, 78 "257 \"/\" is your current location\r\n"); 79 case PRE_TYPE: 80 return Verify(std::string("TYPE ") + data_type_ + "\r\n", data, 81 PRE_EPSV, "200 TYPE set successfully\r\n"); 82 case PRE_EPSV: 83 return Verify("EPSV\r\n", data, PRE_SIZE, 84 "227 Entering Extended Passive Mode (|||31744|)\r\n"); 85 case PRE_NOPASV: 86 // Use unallocated 599 FTP error code to make sure it falls into the 87 // generic ERR_FTP_FAILED bucket. 88 return Verify("PASV\r\n", data, PRE_QUIT, 89 "599 fail\r\n"); 90 case PRE_QUIT: 91 return Verify("QUIT\r\n", data, QUIT, "221 Goodbye.\r\n"); 92 default: 93 NOTREACHED() << "State not handled " << state(); 94 return MockWriteResult(ASYNC, ERR_UNEXPECTED); 95 } 96 } 97 98 void InjectFailure(State state, State next_state, const char* response) { 99 DCHECK_EQ(NONE, failure_injection_state_); 100 DCHECK_NE(NONE, state); 101 DCHECK_NE(NONE, next_state); 102 DCHECK_NE(state, next_state); 103 failure_injection_state_ = state; 104 failure_injection_next_state_ = next_state; 105 fault_response_ = response; 106 } 107 108 State state() const { 109 return state_; 110 } 111 112 virtual void Reset() OVERRIDE { 113 DynamicSocketDataProvider::Reset(); 114 Init(); 115 } 116 117 void set_multiline_welcome(bool multiline) { 118 multiline_welcome_ = multiline; 119 } 120 121 void set_data_type(char data_type) { 122 data_type_ = data_type; 123 } 124 125 protected: 126 void Init() { 127 state_ = PRE_USER; 128 SimulateRead("220 host TestFTPd\r\n"); 129 } 130 131 // If protocol fault injection has been requested, adjusts state and mocked 132 // read and returns true. 133 bool InjectFault() { 134 if (state_ != failure_injection_state_) 135 return false; 136 SimulateRead(fault_response_); 137 state_ = failure_injection_next_state_; 138 return true; 139 } 140 141 MockWriteResult Verify(const std::string& expected, 142 const std::string& data, 143 State next_state, 144 const char* next_read, 145 const size_t next_read_length) { 146 EXPECT_EQ(expected, data); 147 if (expected == data) { 148 state_ = next_state; 149 SimulateRead(next_read, next_read_length); 150 return MockWriteResult(ASYNC, data.length()); 151 } 152 return MockWriteResult(ASYNC, ERR_UNEXPECTED); 153 } 154 155 MockWriteResult Verify(const std::string& expected, 156 const std::string& data, 157 State next_state, 158 const char* next_read) { 159 return Verify(expected, data, next_state, 160 next_read, std::strlen(next_read)); 161 } 162 163 164 private: 165 State state_; 166 State failure_injection_state_; 167 State failure_injection_next_state_; 168 const char* fault_response_; 169 170 // If true, we will send multiple 230 lines as response after PASS. 171 bool multiline_welcome_; 172 173 // Data type to be used for TYPE command. 174 char data_type_; 175 176 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider); 177}; 178 179class FtpSocketDataProviderDirectoryListing : public FtpSocketDataProvider { 180 public: 181 FtpSocketDataProviderDirectoryListing() { 182 } 183 184 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 185 if (InjectFault()) 186 return MockWriteResult(ASYNC, data.length()); 187 switch (state()) { 188 case PRE_SIZE: 189 return Verify("SIZE /\r\n", data, PRE_CWD, 190 "550 I can only retrieve regular files\r\n"); 191 case PRE_CWD: 192 return Verify("CWD /\r\n", data, PRE_LIST, "200 OK\r\n"); 193 case PRE_LIST: 194 return Verify("LIST\r\n", data, PRE_QUIT, "200 OK\r\n"); 195 default: 196 return FtpSocketDataProvider::OnWrite(data); 197 } 198 } 199 200 private: 201 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing); 202}; 203 204class FtpSocketDataProviderDirectoryListingWithPasvFallback 205 : public FtpSocketDataProviderDirectoryListing { 206 public: 207 FtpSocketDataProviderDirectoryListingWithPasvFallback() { 208 } 209 210 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 211 if (InjectFault()) 212 return MockWriteResult(ASYNC, data.length()); 213 switch (state()) { 214 case PRE_EPSV: 215 return Verify("EPSV\r\n", data, PRE_PASV, 216 "500 no EPSV for you\r\n"); 217 case PRE_PASV: 218 return Verify("PASV\r\n", data, PRE_SIZE, 219 "227 Entering Passive Mode 127,0,0,1,123,456\r\n"); 220 default: 221 return FtpSocketDataProviderDirectoryListing::OnWrite(data); 222 } 223 } 224 225 private: 226 DISALLOW_COPY_AND_ASSIGN( 227 FtpSocketDataProviderDirectoryListingWithPasvFallback); 228}; 229 230class FtpSocketDataProviderDirectoryListingZeroSize 231 : public FtpSocketDataProviderDirectoryListing { 232 public: 233 FtpSocketDataProviderDirectoryListingZeroSize() { 234 } 235 236 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 237 if (InjectFault()) 238 return MockWriteResult(ASYNC, data.length()); 239 switch (state()) { 240 case PRE_SIZE: 241 return Verify("SIZE /\r\n", data, PRE_CWD, "213 0\r\n"); 242 default: 243 return FtpSocketDataProviderDirectoryListing::OnWrite(data); 244 } 245 } 246 247 private: 248 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize); 249}; 250 251class FtpSocketDataProviderVMSDirectoryListing : public FtpSocketDataProvider { 252 public: 253 FtpSocketDataProviderVMSDirectoryListing() { 254 } 255 256 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 257 if (InjectFault()) 258 return MockWriteResult(ASYNC, data.length()); 259 switch (state()) { 260 case PRE_SYST: 261 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n"); 262 case PRE_PWD: 263 return Verify("PWD\r\n", data, PRE_TYPE, 264 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n"); 265 case PRE_EPSV: 266 return Verify("EPSV\r\n", data, PRE_PASV, "500 Invalid command\r\n"); 267 case PRE_PASV: 268 return Verify("PASV\r\n", data, PRE_SIZE, 269 "227 Entering Passive Mode 127,0,0,1,123,456\r\n"); 270 case PRE_SIZE: 271 return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_CWD, 272 "550 I can only retrieve regular files\r\n"); 273 case PRE_CWD: 274 return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data, PRE_LIST, 275 "200 OK\r\n"); 276 case PRE_LIST: 277 return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n"); 278 default: 279 return FtpSocketDataProvider::OnWrite(data); 280 } 281 } 282 283 private: 284 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing); 285}; 286 287class FtpSocketDataProviderVMSDirectoryListingRootDirectory 288 : public FtpSocketDataProvider { 289 public: 290 FtpSocketDataProviderVMSDirectoryListingRootDirectory() { 291 } 292 293 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 294 if (InjectFault()) 295 return MockWriteResult(ASYNC, data.length()); 296 switch (state()) { 297 case PRE_SYST: 298 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n"); 299 case PRE_PWD: 300 return Verify("PWD\r\n", data, PRE_TYPE, 301 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n"); 302 case PRE_EPSV: 303 return Verify("EPSV\r\n", data, PRE_PASV, 304 "500 EPSV command unknown\r\n"); 305 case PRE_PASV: 306 return Verify("PASV\r\n", data, PRE_SIZE, 307 "227 Entering Passive Mode 127,0,0,1,123,456\r\n"); 308 case PRE_SIZE: 309 return Verify("SIZE ANONYMOUS_ROOT\r\n", data, PRE_CWD, 310 "550 I can only retrieve regular files\r\n"); 311 case PRE_CWD: 312 return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data, PRE_LIST, 313 "200 OK\r\n"); 314 case PRE_LIST: 315 return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n"); 316 default: 317 return FtpSocketDataProvider::OnWrite(data); 318 } 319 } 320 321 private: 322 DISALLOW_COPY_AND_ASSIGN( 323 FtpSocketDataProviderVMSDirectoryListingRootDirectory); 324}; 325 326class FtpSocketDataProviderFileDownloadWithFileTypecode 327 : public FtpSocketDataProvider { 328 public: 329 FtpSocketDataProviderFileDownloadWithFileTypecode() { 330 } 331 332 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 333 if (InjectFault()) 334 return MockWriteResult(ASYNC, data.length()); 335 switch (state()) { 336 case PRE_SIZE: 337 return Verify("SIZE /file\r\n", data, PRE_RETR, 338 "213 18\r\n"); 339 case PRE_RETR: 340 return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n"); 341 default: 342 return FtpSocketDataProvider::OnWrite(data); 343 } 344 } 345 346 private: 347 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode); 348}; 349 350class FtpSocketDataProviderFileDownload : public FtpSocketDataProvider { 351 public: 352 FtpSocketDataProviderFileDownload() { 353 } 354 355 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 356 if (InjectFault()) 357 return MockWriteResult(ASYNC, data.length()); 358 switch (state()) { 359 case PRE_SIZE: 360 return Verify("SIZE /file\r\n", data, PRE_CWD, 361 "213 18\r\n"); 362 case PRE_CWD: 363 return Verify("CWD /file\r\n", data, PRE_RETR, 364 "550 Not a directory\r\n"); 365 case PRE_RETR: 366 return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n"); 367 default: 368 return FtpSocketDataProvider::OnWrite(data); 369 } 370 } 371 372 private: 373 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload); 374}; 375 376class FtpSocketDataProviderFileNotFound : public FtpSocketDataProvider { 377 public: 378 FtpSocketDataProviderFileNotFound() { 379 } 380 381 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 382 if (InjectFault()) 383 return MockWriteResult(ASYNC, data.length()); 384 switch (state()) { 385 case PRE_SIZE: 386 return Verify("SIZE /file\r\n", data, PRE_CWD, 387 "550 File Not Found\r\n"); 388 case PRE_CWD: 389 return Verify("CWD /file\r\n", data, PRE_RETR, 390 "550 File Not Found\r\n"); 391 case PRE_RETR: 392 return Verify("RETR /file\r\n", data, PRE_QUIT, 393 "550 File Not Found\r\n"); 394 default: 395 return FtpSocketDataProvider::OnWrite(data); 396 } 397 } 398 399 private: 400 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound); 401}; 402 403class FtpSocketDataProviderFileDownloadWithPasvFallback 404 : public FtpSocketDataProviderFileDownload { 405 public: 406 FtpSocketDataProviderFileDownloadWithPasvFallback() { 407 } 408 409 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 410 if (InjectFault()) 411 return MockWriteResult(ASYNC, data.length()); 412 switch (state()) { 413 case PRE_EPSV: 414 return Verify("EPSV\r\n", data, PRE_PASV, 415 "500 No can do\r\n"); 416 case PRE_PASV: 417 return Verify("PASV\r\n", data, PRE_SIZE, 418 "227 Entering Passive Mode 127,0,0,1,123,456\r\n"); 419 default: 420 return FtpSocketDataProviderFileDownload::OnWrite(data); 421 } 422 } 423 424 private: 425 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback); 426}; 427 428class FtpSocketDataProviderFileDownloadZeroSize 429 : public FtpSocketDataProviderFileDownload { 430 public: 431 FtpSocketDataProviderFileDownloadZeroSize() { 432 } 433 434 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 435 if (InjectFault()) 436 return MockWriteResult(ASYNC, data.length()); 437 switch (state()) { 438 case PRE_SIZE: 439 return Verify("SIZE /file\r\n", data, PRE_CWD, 440 "213 0\r\n"); 441 case PRE_CWD: 442 return Verify("CWD /file\r\n", data, PRE_RETR, 443 "550 not a directory\r\n"); 444 default: 445 return FtpSocketDataProviderFileDownload::OnWrite(data); 446 } 447 } 448 449 private: 450 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize); 451}; 452 453class FtpSocketDataProviderFileDownloadCWD451 454 : public FtpSocketDataProviderFileDownload { 455 public: 456 FtpSocketDataProviderFileDownloadCWD451() { 457 } 458 459 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 460 if (InjectFault()) 461 return MockWriteResult(ASYNC, data.length()); 462 switch (state()) { 463 case PRE_CWD: 464 return Verify("CWD /file\r\n", data, PRE_RETR, 465 "451 not a directory\r\n"); 466 default: 467 return FtpSocketDataProviderFileDownload::OnWrite(data); 468 } 469 } 470 471 private: 472 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451); 473}; 474 475class FtpSocketDataProviderVMSFileDownload : public FtpSocketDataProvider { 476 public: 477 FtpSocketDataProviderVMSFileDownload() { 478 } 479 480 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 481 if (InjectFault()) 482 return MockWriteResult(ASYNC, data.length()); 483 switch (state()) { 484 case PRE_SYST: 485 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n"); 486 case PRE_PWD: 487 return Verify("PWD\r\n", data, PRE_TYPE, 488 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n"); 489 case PRE_EPSV: 490 return Verify("EPSV\r\n", data, PRE_PASV, 491 "500 EPSV command unknown\r\n"); 492 case PRE_PASV: 493 return Verify("PASV\r\n", data, PRE_SIZE, 494 "227 Entering Passive Mode 127,0,0,1,123,456\r\n"); 495 case PRE_SIZE: 496 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_CWD, 497 "213 18\r\n"); 498 case PRE_CWD: 499 return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data, PRE_RETR, 500 "550 Not a directory\r\n"); 501 case PRE_RETR: 502 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_QUIT, 503 "200 OK\r\n"); 504 default: 505 return FtpSocketDataProvider::OnWrite(data); 506 } 507 } 508 509 private: 510 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload); 511}; 512 513class FtpSocketDataProviderEscaping : public FtpSocketDataProviderFileDownload { 514 public: 515 FtpSocketDataProviderEscaping() { 516 } 517 518 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 519 if (InjectFault()) 520 return MockWriteResult(ASYNC, data.length()); 521 switch (state()) { 522 case PRE_SIZE: 523 return Verify("SIZE / !\"#$%y\200\201\r\n", data, PRE_CWD, 524 "213 18\r\n"); 525 case PRE_CWD: 526 return Verify("CWD / !\"#$%y\200\201\r\n", data, PRE_RETR, 527 "550 Not a directory\r\n"); 528 case PRE_RETR: 529 return Verify("RETR / !\"#$%y\200\201\r\n", data, PRE_QUIT, 530 "200 OK\r\n"); 531 default: 532 return FtpSocketDataProviderFileDownload::OnWrite(data); 533 } 534 } 535 536 private: 537 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping); 538}; 539 540class FtpSocketDataProviderFileDownloadTransferStarting 541 : public FtpSocketDataProviderFileDownload { 542 public: 543 FtpSocketDataProviderFileDownloadTransferStarting() { 544 } 545 546 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 547 if (InjectFault()) 548 return MockWriteResult(ASYNC, data.length()); 549 switch (state()) { 550 case PRE_RETR: 551 return Verify("RETR /file\r\n", data, PRE_QUIT, 552 "125-Data connection already open.\r\n" 553 "125 Transfer starting.\r\n" 554 "226 Transfer complete.\r\n"); 555 default: 556 return FtpSocketDataProviderFileDownload::OnWrite(data); 557 } 558 } 559 560 private: 561 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting); 562}; 563 564class FtpSocketDataProviderDirectoryListingTransferStarting 565 : public FtpSocketDataProviderDirectoryListing { 566 public: 567 FtpSocketDataProviderDirectoryListingTransferStarting() { 568 } 569 570 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 571 if (InjectFault()) 572 return MockWriteResult(ASYNC, data.length()); 573 switch (state()) { 574 case PRE_LIST: 575 return Verify("LIST\r\n", data, PRE_QUIT, 576 "125-Data connection already open.\r\n" 577 "125 Transfer starting.\r\n" 578 "226 Transfer complete.\r\n"); 579 default: 580 return FtpSocketDataProviderDirectoryListing::OnWrite(data); 581 } 582 } 583 584 private: 585 DISALLOW_COPY_AND_ASSIGN( 586 FtpSocketDataProviderDirectoryListingTransferStarting); 587}; 588 589class FtpSocketDataProviderFileDownloadInvalidResponse 590 : public FtpSocketDataProviderFileDownload { 591 public: 592 FtpSocketDataProviderFileDownloadInvalidResponse() { 593 } 594 595 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 596 if (InjectFault()) 597 return MockWriteResult(ASYNC, data.length()); 598 switch (state()) { 599 case PRE_SIZE: 600 // Use unallocated 599 FTP error code to make sure it falls into the 601 // generic ERR_FTP_FAILED bucket. 602 return Verify("SIZE /file\r\n", data, PRE_QUIT, 603 "599 Evil Response\r\n" 604 "599 More Evil\r\n"); 605 default: 606 return FtpSocketDataProviderFileDownload::OnWrite(data); 607 } 608 } 609 610 private: 611 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse); 612}; 613 614class FtpSocketDataProviderEvilEpsv : public FtpSocketDataProviderFileDownload { 615 public: 616 FtpSocketDataProviderEvilEpsv(const char* epsv_response, 617 State expected_state) 618 : epsv_response_(epsv_response), 619 epsv_response_length_(std::strlen(epsv_response)), 620 expected_state_(expected_state) {} 621 622 FtpSocketDataProviderEvilEpsv(const char* epsv_response, 623 size_t epsv_response_length, 624 State expected_state) 625 : epsv_response_(epsv_response), 626 epsv_response_length_(epsv_response_length), 627 expected_state_(expected_state) {} 628 629 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 630 if (InjectFault()) 631 return MockWriteResult(ASYNC, data.length()); 632 switch (state()) { 633 case PRE_EPSV: 634 return Verify("EPSV\r\n", data, expected_state_, 635 epsv_response_, epsv_response_length_); 636 default: 637 return FtpSocketDataProviderFileDownload::OnWrite(data); 638 } 639 } 640 641 private: 642 const char* epsv_response_; 643 const size_t epsv_response_length_; 644 const State expected_state_; 645 646 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv); 647}; 648 649class FtpSocketDataProviderEvilPasv 650 : public FtpSocketDataProviderFileDownloadWithPasvFallback { 651 public: 652 FtpSocketDataProviderEvilPasv(const char* pasv_response, State expected_state) 653 : pasv_response_(pasv_response), 654 expected_state_(expected_state) { 655 } 656 657 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 658 if (InjectFault()) 659 return MockWriteResult(ASYNC, data.length()); 660 switch (state()) { 661 case PRE_PASV: 662 return Verify("PASV\r\n", data, expected_state_, pasv_response_); 663 default: 664 return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data); 665 } 666 } 667 668 private: 669 const char* pasv_response_; 670 const State expected_state_; 671 672 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv); 673}; 674 675class FtpSocketDataProviderEvilSize : public FtpSocketDataProviderFileDownload { 676 public: 677 FtpSocketDataProviderEvilSize(const char* size_response, State expected_state) 678 : size_response_(size_response), 679 expected_state_(expected_state) { 680 } 681 682 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 683 if (InjectFault()) 684 return MockWriteResult(ASYNC, data.length()); 685 switch (state()) { 686 case PRE_SIZE: 687 return Verify("SIZE /file\r\n", data, expected_state_, size_response_); 688 default: 689 return FtpSocketDataProviderFileDownload::OnWrite(data); 690 } 691 } 692 693 private: 694 const char* size_response_; 695 const State expected_state_; 696 697 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize); 698}; 699 700class FtpSocketDataProviderEvilLogin 701 : public FtpSocketDataProviderFileDownload { 702 public: 703 FtpSocketDataProviderEvilLogin(const char* expected_user, 704 const char* expected_password) 705 : expected_user_(expected_user), 706 expected_password_(expected_password) { 707 } 708 709 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 710 if (InjectFault()) 711 return MockWriteResult(ASYNC, data.length()); 712 switch (state()) { 713 case PRE_USER: 714 return Verify(std::string("USER ") + expected_user_ + "\r\n", data, 715 PRE_PASSWD, "331 Password needed\r\n"); 716 case PRE_PASSWD: 717 return Verify(std::string("PASS ") + expected_password_ + "\r\n", data, 718 PRE_SYST, "230 Welcome\r\n"); 719 default: 720 return FtpSocketDataProviderFileDownload::OnWrite(data); 721 } 722 } 723 724 private: 725 const char* expected_user_; 726 const char* expected_password_; 727 728 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin); 729}; 730 731class FtpSocketDataProviderCloseConnection : public FtpSocketDataProvider { 732 public: 733 FtpSocketDataProviderCloseConnection() { 734 } 735 736 virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE { 737 if (InjectFault()) 738 return MockWriteResult(ASYNC, data.length()); 739 switch (state()) { 740 case PRE_USER: 741 return Verify("USER anonymous\r\n", data, 742 PRE_QUIT, ""); 743 default: 744 return FtpSocketDataProvider::OnWrite(data); 745 } 746 } 747 748 private: 749 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection); 750}; 751 752class FtpNetworkTransactionTest : public PlatformTest { 753 public: 754 FtpNetworkTransactionTest() 755 : host_resolver_(new MockHostResolver), 756 session_(new FtpNetworkSession(host_resolver_.get())), 757 transaction_(session_.get(), &mock_socket_factory_) { 758 } 759 760 protected: 761 FtpRequestInfo GetRequestInfo(const std::string& url) { 762 FtpRequestInfo info; 763 info.url = GURL(url); 764 return info; 765 } 766 767 void ExecuteTransaction(FtpSocketDataProvider* ctrl_socket, 768 const char* request, 769 int expected_result) { 770 std::string mock_data("mock-data"); 771 MockRead data_reads[] = { 772 // Usually FTP servers close the data connection after the entire data has 773 // been received. 774 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 775 MockRead(mock_data.c_str()), 776 }; 777 StaticSocketDataProvider data_socket(data_reads, arraysize(data_reads), 778 NULL, 0); 779 mock_socket_factory_.AddSocketDataProvider(ctrl_socket); 780 mock_socket_factory_.AddSocketDataProvider(&data_socket); 781 FtpRequestInfo request_info = GetRequestInfo(request); 782 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState()); 783 ASSERT_EQ(ERR_IO_PENDING, 784 transaction_.Start(&request_info, callback_.callback(), 785 BoundNetLog())); 786 EXPECT_NE(LOAD_STATE_IDLE, transaction_.GetLoadState()); 787 ASSERT_EQ(expected_result, callback_.WaitForResult()); 788 if (expected_result == OK) { 789 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(kBufferSize)); 790 memset(io_buffer->data(), 0, kBufferSize); 791 ASSERT_EQ(ERR_IO_PENDING, 792 transaction_.Read(io_buffer.get(), kBufferSize, 793 callback_.callback())); 794 ASSERT_EQ(static_cast<int>(mock_data.length()), 795 callback_.WaitForResult()); 796 EXPECT_EQ(mock_data, std::string(io_buffer->data(), mock_data.length())); 797 798 // Do another Read to detect that the data socket is now closed. 799 int rv = transaction_.Read(io_buffer.get(), kBufferSize, 800 callback_.callback()); 801 if (rv == ERR_IO_PENDING) { 802 EXPECT_EQ(0, callback_.WaitForResult()); 803 } else { 804 EXPECT_EQ(0, rv); 805 } 806 } 807 EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket->state()); 808 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState()); 809 } 810 811 void TransactionFailHelper(FtpSocketDataProvider* ctrl_socket, 812 const char* request, 813 FtpSocketDataProvider::State state, 814 FtpSocketDataProvider::State next_state, 815 const char* response, 816 int expected_result) { 817 ctrl_socket->InjectFailure(state, next_state, response); 818 ExecuteTransaction(ctrl_socket, request, expected_result); 819 } 820 821 scoped_ptr<MockHostResolver> host_resolver_; 822 scoped_refptr<FtpNetworkSession> session_; 823 MockClientSocketFactory mock_socket_factory_; 824 FtpNetworkTransaction transaction_; 825 TestCompletionCallback callback_; 826}; 827 828TEST_F(FtpNetworkTransactionTest, FailedLookup) { 829 FtpRequestInfo request_info = GetRequestInfo("ftp://badhost"); 830 host_resolver_->rules()->AddSimulatedFailure("badhost"); 831 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState()); 832 ASSERT_EQ(ERR_IO_PENDING, 833 transaction_.Start(&request_info, callback_.callback(), 834 BoundNetLog())); 835 ASSERT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult()); 836 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState()); 837} 838 839// Check that when determining the host, the square brackets decorating IPv6 840// literals in URLs are stripped. 841TEST_F(FtpNetworkTransactionTest, StripBracketsFromIPv6Literals) { 842 host_resolver_->rules()->AddSimulatedFailure("[::1]"); 843 844 // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE. 845 // The important part of this test is to make sure that we don't fail with 846 // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname 847 // was used. 848 FtpSocketDataProviderEvilSize ctrl_socket( 849 "213 99999999999999999999999999999999\r\n", 850 FtpSocketDataProvider::PRE_QUIT); 851 ExecuteTransaction(&ctrl_socket, "ftp://[::1]/file", ERR_INVALID_RESPONSE); 852} 853 854TEST_F(FtpNetworkTransactionTest, DirectoryTransaction) { 855 FtpSocketDataProviderDirectoryListing ctrl_socket; 856 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 857 858 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing); 859 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size); 860 EXPECT_EQ("192.0.2.33", 861 transaction_.GetResponseInfo()->socket_address.host()); 862 EXPECT_EQ(0, transaction_.GetResponseInfo()->socket_address.port()); 863} 864 865TEST_F(FtpNetworkTransactionTest, DirectoryTransactionWithPasvFallback) { 866 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket; 867 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 868 869 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing); 870 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size); 871} 872 873TEST_F(FtpNetworkTransactionTest, DirectoryTransactionWithTypecode) { 874 FtpSocketDataProviderDirectoryListing ctrl_socket; 875 ExecuteTransaction(&ctrl_socket, "ftp://host;type=d", OK); 876 877 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing); 878 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size); 879} 880 881TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcome) { 882 FtpSocketDataProviderDirectoryListing ctrl_socket; 883 ctrl_socket.set_multiline_welcome(true); 884 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 885} 886 887TEST_F(FtpNetworkTransactionTest, DirectoryTransactionShortReads2) { 888 FtpSocketDataProviderDirectoryListing ctrl_socket; 889 ctrl_socket.set_short_read_limit(2); 890 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 891} 892 893TEST_F(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) { 894 FtpSocketDataProviderDirectoryListing ctrl_socket; 895 ctrl_socket.set_short_read_limit(5); 896 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 897} 898 899TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcomeShort) { 900 FtpSocketDataProviderDirectoryListing ctrl_socket; 901 // The client will not consume all three 230 lines. That's good, we want to 902 // test that scenario. 903 ctrl_socket.allow_unconsumed_reads(true); 904 ctrl_socket.set_multiline_welcome(true); 905 ctrl_socket.set_short_read_limit(5); 906 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 907} 908 909// Regression test for http://crbug.com/60555. 910TEST_F(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) { 911 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket; 912 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 913} 914 915TEST_F(FtpNetworkTransactionTest, DirectoryTransactionVMS) { 916 FtpSocketDataProviderVMSDirectoryListing ctrl_socket; 917 ExecuteTransaction(&ctrl_socket, "ftp://host/dir", OK); 918} 919 920TEST_F(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) { 921 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket; 922 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 923} 924 925TEST_F(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) { 926 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket; 927 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 928} 929 930TEST_F(FtpNetworkTransactionTest, DownloadTransaction) { 931 FtpSocketDataProviderFileDownload ctrl_socket; 932 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 933 934 // We pass an artificial value of 18 as a response to the SIZE command. 935 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); 936 EXPECT_EQ("192.0.2.33", 937 transaction_.GetResponseInfo()->socket_address.host()); 938 EXPECT_EQ(0, transaction_.GetResponseInfo()->socket_address.port()); 939} 940 941TEST_F(FtpNetworkTransactionTest, DownloadTransactionWithPasvFallback) { 942 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket; 943 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 944 945 // We pass an artificial value of 18 as a response to the SIZE command. 946 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); 947} 948 949TEST_F(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeA) { 950 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket; 951 ctrl_socket.set_data_type('A'); 952 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=a", OK); 953 954 // We pass an artificial value of 18 as a response to the SIZE command. 955 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); 956} 957 958TEST_F(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeI) { 959 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket; 960 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=i", OK); 961 962 // We pass an artificial value of 18 as a response to the SIZE command. 963 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); 964} 965 966TEST_F(FtpNetworkTransactionTest, DownloadTransactionMultilineWelcome) { 967 FtpSocketDataProviderFileDownload ctrl_socket; 968 ctrl_socket.set_multiline_welcome(true); 969 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 970} 971 972TEST_F(FtpNetworkTransactionTest, DownloadTransactionShortReads2) { 973 FtpSocketDataProviderFileDownload ctrl_socket; 974 ctrl_socket.set_short_read_limit(2); 975 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 976} 977 978TEST_F(FtpNetworkTransactionTest, DownloadTransactionShortReads5) { 979 FtpSocketDataProviderFileDownload ctrl_socket; 980 ctrl_socket.set_short_read_limit(5); 981 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 982} 983 984TEST_F(FtpNetworkTransactionTest, DownloadTransactionZeroSize) { 985 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket; 986 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 987} 988 989TEST_F(FtpNetworkTransactionTest, DownloadTransactionCWD451) { 990 FtpSocketDataProviderFileDownloadCWD451 ctrl_socket; 991 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 992} 993 994TEST_F(FtpNetworkTransactionTest, DownloadTransactionVMS) { 995 FtpSocketDataProviderVMSFileDownload ctrl_socket; 996 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 997} 998 999TEST_F(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) { 1000 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket; 1001 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 1002} 1003 1004TEST_F(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) { 1005 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket; 1006 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1007} 1008 1009TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvReallyBadFormat) { 1010 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,\r\n", 1011 FtpSocketDataProvider::PRE_QUIT); 1012 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1013} 1014 1015TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort1) { 1016 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n", 1017 FtpSocketDataProvider::PRE_QUIT); 1018 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1019} 1020 1021TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort2) { 1022 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024. 1023 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n", 1024 FtpSocketDataProvider::PRE_QUIT); 1025 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1026} 1027 1028TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort3) { 1029 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024. 1030 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n", 1031 FtpSocketDataProvider::PRE_QUIT); 1032 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1033} 1034 1035TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort4) { 1036 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs. 1037 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n", 1038 FtpSocketDataProvider::PRE_QUIT); 1039 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1040} 1041 1042TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafeHost) { 1043 FtpSocketDataProviderEvilPasv ctrl_socket( 1044 "227 Portscan (10,1,2,3,123,456)\r\n", FtpSocketDataProvider::PRE_SIZE); 1045 std::string mock_data("mock-data"); 1046 MockRead data_reads[] = { 1047 MockRead(mock_data.c_str()), 1048 }; 1049 StaticSocketDataProvider data_socket1(data_reads, arraysize(data_reads), 1050 NULL, 0); 1051 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket); 1052 mock_socket_factory_.AddSocketDataProvider(&data_socket1); 1053 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file"); 1054 1055 // Start the transaction. 1056 ASSERT_EQ(ERR_IO_PENDING, 1057 transaction_.Start(&request_info, callback_.callback(), 1058 BoundNetLog())); 1059 ASSERT_EQ(OK, callback_.WaitForResult()); 1060 1061 // The transaction fires the callback when we can start reading data. That 1062 // means that the data socket should be open. 1063 MockTCPClientSocket* data_socket = 1064 static_cast<MockTCPClientSocket*>(transaction_.data_socket_.get()); 1065 ASSERT_TRUE(data_socket); 1066 ASSERT_TRUE(data_socket->IsConnected()); 1067 1068 // Even if the PASV response specified some other address, we connect 1069 // to the address we used for control connection (which could be 127.0.0.1 1070 // or ::1 depending on whether we use IPv6). 1071 for (AddressList::const_iterator it = data_socket->addresses().begin(); 1072 it != data_socket->addresses().end(); ++it) { 1073 EXPECT_NE("10.1.2.3", it->ToStringWithoutPort()); 1074 } 1075} 1076 1077TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat1) { 1078 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22)\r\n", 1079 FtpSocketDataProvider::PRE_QUIT); 1080 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1081} 1082 1083TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat2) { 1084 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||\r\n", 1085 FtpSocketDataProvider::PRE_QUIT); 1086 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1087} 1088 1089TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat3) { 1090 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan\r\n", 1091 FtpSocketDataProvider::PRE_QUIT); 1092 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1093} 1094 1095TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat4) { 1096 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||||)\r\n", 1097 FtpSocketDataProvider::PRE_QUIT); 1098 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1099} 1100 1101TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat5) { 1102 const char response[] = "227 Portscan (\0\0\031773\0)\r\n"; 1103 FtpSocketDataProviderEvilEpsv ctrl_socket(response, sizeof(response)-1, 1104 FtpSocketDataProvider::PRE_QUIT); 1105 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1106} 1107 1108TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort1) { 1109 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22|)\r\n", 1110 FtpSocketDataProvider::PRE_QUIT); 1111 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1112} 1113 1114TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort2) { 1115 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||258|)\r\n", 1116 FtpSocketDataProvider::PRE_QUIT); 1117 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1118} 1119 1120TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort3) { 1121 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||772|)\r\n", 1122 FtpSocketDataProvider::PRE_QUIT); 1123 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1124} 1125 1126TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort4) { 1127 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||2049|)\r\n", 1128 FtpSocketDataProvider::PRE_QUIT); 1129 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1130} 1131 1132TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvWeirdSep) { 1133 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$31744$)\r\n", 1134 FtpSocketDataProvider::PRE_SIZE); 1135 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 1136} 1137 1138TEST_F(FtpNetworkTransactionTest, 1139 DownloadTransactionEvilEpsvWeirdSepUnsafePort) { 1140 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$317$)\r\n", 1141 FtpSocketDataProvider::PRE_QUIT); 1142 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1143} 1144 1145TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvIllegalHost) { 1146 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|2|::1|31744|)\r\n", 1147 FtpSocketDataProvider::PRE_QUIT); 1148 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1149} 1150 1151TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) { 1152 FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test"); 1153 ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", OK); 1154} 1155 1156TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) { 1157 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld"); 1158 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", OK); 1159} 1160 1161TEST_F(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) { 1162 FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test"); 1163 ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", OK); 1164} 1165 1166TEST_F(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) { 1167 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world"); 1168 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", OK); 1169} 1170 1171TEST_F(FtpNetworkTransactionTest, EvilRestartUser) { 1172 FtpSocketDataProvider ctrl_socket1; 1173 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD, 1174 FtpSocketDataProvider::PRE_QUIT, 1175 "530 Login authentication failed\r\n"); 1176 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1); 1177 1178 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file"); 1179 1180 ASSERT_EQ(ERR_IO_PENDING, 1181 transaction_.Start(&request_info, callback_.callback(), 1182 BoundNetLog())); 1183 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult()); 1184 1185 MockRead ctrl_reads[] = { 1186 MockRead("220 host TestFTPd\r\n"), 1187 MockRead("221 Goodbye!\r\n"), 1188 MockRead(SYNCHRONOUS, OK), 1189 }; 1190 MockWrite ctrl_writes[] = { 1191 MockWrite("QUIT\r\n"), 1192 }; 1193 StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads), 1194 ctrl_writes, arraysize(ctrl_writes)); 1195 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2); 1196 ASSERT_EQ(ERR_IO_PENDING, 1197 transaction_.RestartWithAuth( 1198 AuthCredentials( 1199 ASCIIToUTF16("foo\nownz0red"), 1200 ASCIIToUTF16("innocent")), 1201 callback_.callback())); 1202 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult()); 1203} 1204 1205TEST_F(FtpNetworkTransactionTest, EvilRestartPassword) { 1206 FtpSocketDataProvider ctrl_socket1; 1207 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD, 1208 FtpSocketDataProvider::PRE_QUIT, 1209 "530 Login authentication failed\r\n"); 1210 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1); 1211 1212 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file"); 1213 1214 ASSERT_EQ(ERR_IO_PENDING, 1215 transaction_.Start(&request_info, callback_.callback(), 1216 BoundNetLog())); 1217 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult()); 1218 1219 MockRead ctrl_reads[] = { 1220 MockRead("220 host TestFTPd\r\n"), 1221 MockRead("331 User okay, send password\r\n"), 1222 MockRead("221 Goodbye!\r\n"), 1223 MockRead(SYNCHRONOUS, OK), 1224 }; 1225 MockWrite ctrl_writes[] = { 1226 MockWrite("USER innocent\r\n"), 1227 MockWrite("QUIT\r\n"), 1228 }; 1229 StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads), 1230 ctrl_writes, arraysize(ctrl_writes)); 1231 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2); 1232 ASSERT_EQ(ERR_IO_PENDING, 1233 transaction_.RestartWithAuth( 1234 AuthCredentials(ASCIIToUTF16("innocent"), 1235 ASCIIToUTF16("foo\nownz0red")), 1236 callback_.callback())); 1237 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult()); 1238} 1239 1240TEST_F(FtpNetworkTransactionTest, Escaping) { 1241 FtpSocketDataProviderEscaping ctrl_socket; 1242 ExecuteTransaction(&ctrl_socket, "ftp://host/%20%21%22%23%24%25%79%80%81", 1243 OK); 1244} 1245 1246// Test for http://crbug.com/23794. 1247TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilSize) { 1248 // Try to overflow int64 in the response. 1249 FtpSocketDataProviderEvilSize ctrl_socket( 1250 "213 99999999999999999999999999999999\r\n", 1251 FtpSocketDataProvider::PRE_QUIT); 1252 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1253} 1254 1255// Test for http://crbug.com/36360. 1256TEST_F(FtpNetworkTransactionTest, DownloadTransactionBigSize) { 1257 // Pass a valid, but large file size. The transaction should not fail. 1258 FtpSocketDataProviderEvilSize ctrl_socket( 1259 "213 3204427776\r\n", 1260 FtpSocketDataProvider::PRE_CWD); 1261 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 1262 EXPECT_EQ(3204427776LL, 1263 transaction_.GetResponseInfo()->expected_content_size); 1264} 1265 1266// Regression test for http://crbug.com/25023. 1267TEST_F(FtpNetworkTransactionTest, CloseConnection) { 1268 FtpSocketDataProviderCloseConnection ctrl_socket; 1269 ExecuteTransaction(&ctrl_socket, "ftp://host", ERR_EMPTY_RESPONSE); 1270} 1271 1272TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailUser) { 1273 FtpSocketDataProviderDirectoryListing ctrl_socket; 1274 // Use unallocated 599 FTP error code to make sure it falls into the generic 1275 // ERR_FTP_FAILED bucket. 1276 TransactionFailHelper(&ctrl_socket, 1277 "ftp://host", 1278 FtpSocketDataProvider::PRE_USER, 1279 FtpSocketDataProvider::PRE_QUIT, 1280 "599 fail\r\n", 1281 ERR_FTP_FAILED); 1282} 1283 1284TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPass) { 1285 FtpSocketDataProviderDirectoryListing ctrl_socket; 1286 TransactionFailHelper(&ctrl_socket, 1287 "ftp://host", 1288 FtpSocketDataProvider::PRE_PASSWD, 1289 FtpSocketDataProvider::PRE_QUIT, 1290 "530 Login authentication failed\r\n", 1291 ERR_FTP_FAILED); 1292} 1293 1294// Regression test for http://crbug.com/38707. 1295TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPass503) { 1296 FtpSocketDataProviderDirectoryListing ctrl_socket; 1297 TransactionFailHelper(&ctrl_socket, 1298 "ftp://host", 1299 FtpSocketDataProvider::PRE_PASSWD, 1300 FtpSocketDataProvider::PRE_QUIT, 1301 "503 Bad sequence of commands\r\n", 1302 ERR_FTP_BAD_COMMAND_SEQUENCE); 1303} 1304 1305TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailSyst) { 1306 FtpSocketDataProviderDirectoryListing ctrl_socket; 1307 // Use unallocated 599 FTP error code to make sure it falls into the generic 1308 // ERR_FTP_FAILED bucket. 1309 TransactionFailHelper(&ctrl_socket, 1310 "ftp://host", 1311 FtpSocketDataProvider::PRE_SYST, 1312 FtpSocketDataProvider::PRE_PWD, 1313 "599 fail\r\n", 1314 OK); 1315} 1316 1317TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPwd) { 1318 FtpSocketDataProviderDirectoryListing ctrl_socket; 1319 // Use unallocated 599 FTP error code to make sure it falls into the generic 1320 // ERR_FTP_FAILED bucket. 1321 TransactionFailHelper(&ctrl_socket, 1322 "ftp://host", 1323 FtpSocketDataProvider::PRE_PWD, 1324 FtpSocketDataProvider::PRE_QUIT, 1325 "599 fail\r\n", 1326 ERR_FTP_FAILED); 1327} 1328 1329TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailType) { 1330 FtpSocketDataProviderDirectoryListing ctrl_socket; 1331 // Use unallocated 599 FTP error code to make sure it falls into the generic 1332 // ERR_FTP_FAILED bucket. 1333 TransactionFailHelper(&ctrl_socket, 1334 "ftp://host", 1335 FtpSocketDataProvider::PRE_TYPE, 1336 FtpSocketDataProvider::PRE_QUIT, 1337 "599 fail\r\n", 1338 ERR_FTP_FAILED); 1339} 1340 1341TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailEpsv) { 1342 FtpSocketDataProviderDirectoryListing ctrl_socket; 1343 // Use unallocated 599 FTP error code to make sure it falls into the generic 1344 // ERR_FTP_FAILED bucket. 1345 TransactionFailHelper(&ctrl_socket, 1346 "ftp://host", 1347 FtpSocketDataProvider::PRE_EPSV, 1348 FtpSocketDataProvider::PRE_NOPASV, 1349 "599 fail\r\n", 1350 ERR_FTP_FAILED); 1351} 1352 1353TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailCwd) { 1354 FtpSocketDataProviderDirectoryListing ctrl_socket; 1355 // Use unallocated 599 FTP error code to make sure it falls into the generic 1356 // ERR_FTP_FAILED bucket. 1357 TransactionFailHelper(&ctrl_socket, 1358 "ftp://host", 1359 FtpSocketDataProvider::PRE_CWD, 1360 FtpSocketDataProvider::PRE_QUIT, 1361 "599 fail\r\n", 1362 ERR_FTP_FAILED); 1363} 1364 1365TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailList) { 1366 FtpSocketDataProviderVMSDirectoryListing ctrl_socket; 1367 // Use unallocated 599 FTP error code to make sure it falls into the generic 1368 // ERR_FTP_FAILED bucket. 1369 TransactionFailHelper(&ctrl_socket, 1370 "ftp://host/dir", 1371 FtpSocketDataProvider::PRE_LIST, 1372 FtpSocketDataProvider::PRE_QUIT, 1373 "599 fail\r\n", 1374 ERR_FTP_FAILED); 1375} 1376 1377TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailUser) { 1378 FtpSocketDataProviderFileDownload ctrl_socket; 1379 // Use unallocated 599 FTP error code to make sure it falls into the generic 1380 // ERR_FTP_FAILED bucket. 1381 TransactionFailHelper(&ctrl_socket, 1382 "ftp://host/file", 1383 FtpSocketDataProvider::PRE_USER, 1384 FtpSocketDataProvider::PRE_QUIT, 1385 "599 fail\r\n", 1386 ERR_FTP_FAILED); 1387} 1388 1389TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailPass) { 1390 FtpSocketDataProviderFileDownload ctrl_socket; 1391 TransactionFailHelper(&ctrl_socket, 1392 "ftp://host/file", 1393 FtpSocketDataProvider::PRE_PASSWD, 1394 FtpSocketDataProvider::PRE_QUIT, 1395 "530 Login authentication failed\r\n", 1396 ERR_FTP_FAILED); 1397} 1398 1399TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailSyst) { 1400 FtpSocketDataProviderFileDownload ctrl_socket; 1401 // Use unallocated 599 FTP error code to make sure it falls into the generic 1402 // ERR_FTP_FAILED bucket. 1403 TransactionFailHelper(&ctrl_socket, 1404 "ftp://host/file", 1405 FtpSocketDataProvider::PRE_SYST, 1406 FtpSocketDataProvider::PRE_PWD, 1407 "599 fail\r\n", 1408 OK); 1409} 1410 1411TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailPwd) { 1412 FtpSocketDataProviderFileDownload ctrl_socket; 1413 // Use unallocated 599 FTP error code to make sure it falls into the generic 1414 // ERR_FTP_FAILED bucket. 1415 TransactionFailHelper(&ctrl_socket, 1416 "ftp://host/file", 1417 FtpSocketDataProvider::PRE_PWD, 1418 FtpSocketDataProvider::PRE_QUIT, 1419 "599 fail\r\n", 1420 ERR_FTP_FAILED); 1421} 1422 1423TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailType) { 1424 FtpSocketDataProviderFileDownload ctrl_socket; 1425 // Use unallocated 599 FTP error code to make sure it falls into the generic 1426 // ERR_FTP_FAILED bucket. 1427 TransactionFailHelper(&ctrl_socket, 1428 "ftp://host/file", 1429 FtpSocketDataProvider::PRE_TYPE, 1430 FtpSocketDataProvider::PRE_QUIT, 1431 "599 fail\r\n", 1432 ERR_FTP_FAILED); 1433} 1434 1435TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailEpsv) { 1436 FtpSocketDataProviderFileDownload ctrl_socket; 1437 // Use unallocated 599 FTP error code to make sure it falls into the generic 1438 // ERR_FTP_FAILED bucket. 1439 TransactionFailHelper(&ctrl_socket, 1440 "ftp://host/file", 1441 FtpSocketDataProvider::PRE_EPSV, 1442 FtpSocketDataProvider::PRE_NOPASV, 1443 "599 fail\r\n", 1444 ERR_FTP_FAILED); 1445} 1446 1447TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailRetr) { 1448 FtpSocketDataProviderFileDownload ctrl_socket; 1449 // Use unallocated 599 FTP error code to make sure it falls into the generic 1450 // ERR_FTP_FAILED bucket. 1451 TransactionFailHelper(&ctrl_socket, 1452 "ftp://host/file", 1453 FtpSocketDataProvider::PRE_RETR, 1454 FtpSocketDataProvider::PRE_QUIT, 1455 "599 fail\r\n", 1456 ERR_FTP_FAILED); 1457} 1458 1459TEST_F(FtpNetworkTransactionTest, FileNotFound) { 1460 FtpSocketDataProviderFileNotFound ctrl_socket; 1461 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_FTP_FAILED); 1462} 1463 1464// Test for http://crbug.com/38845. 1465TEST_F(FtpNetworkTransactionTest, ZeroLengthDirInPWD) { 1466 FtpSocketDataProviderFileDownload ctrl_socket; 1467 TransactionFailHelper(&ctrl_socket, 1468 "ftp://host/file", 1469 FtpSocketDataProvider::PRE_PWD, 1470 FtpSocketDataProvider::PRE_TYPE, 1471 "257 \"\"\r\n", 1472 OK); 1473} 1474 1475} // namespace net 1476