1// Copyright (c) 2011 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/memory/ref_counted.h" 10#include "base/string_util.h" 11#include "base/utf_string_conversions.h" 12#include "net/base/host_port_pair.h" 13#include "net/base/io_buffer.h" 14#include "net/base/mock_host_resolver.h" 15#include "net/base/net_util.h" 16#include "net/base/sys_addrinfo.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) { 61 if (InjectFault()) 62 return MockWriteResult(true, 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(true, 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() { 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(true, data.length()); 151 } 152 return MockWriteResult(true, 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) { 185 if (InjectFault()) 186 return MockWriteResult(true, 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) { 211 if (InjectFault()) 212 return MockWriteResult(true, 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) { 237 if (InjectFault()) 238 return MockWriteResult(true, 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) { 257 if (InjectFault()) 258 return MockWriteResult(true, 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) { 294 if (InjectFault()) 295 return MockWriteResult(true, 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) { 333 if (InjectFault()) 334 return MockWriteResult(true, 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) { 356 if (InjectFault()) 357 return MockWriteResult(true, 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) { 382 if (InjectFault()) 383 return MockWriteResult(true, 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) { 410 if (InjectFault()) 411 return MockWriteResult(true, 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) { 435 if (InjectFault()) 436 return MockWriteResult(true, 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 FtpSocketDataProviderVMSFileDownload : public FtpSocketDataProvider { 454 public: 455 FtpSocketDataProviderVMSFileDownload() { 456 } 457 458 virtual MockWriteResult OnWrite(const std::string& data) { 459 if (InjectFault()) 460 return MockWriteResult(true, data.length()); 461 switch (state()) { 462 case PRE_SYST: 463 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n"); 464 case PRE_PWD: 465 return Verify("PWD\r\n", data, PRE_TYPE, 466 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n"); 467 case PRE_EPSV: 468 return Verify("EPSV\r\n", data, PRE_PASV, 469 "500 EPSV command unknown\r\n"); 470 case PRE_PASV: 471 return Verify("PASV\r\n", data, PRE_SIZE, 472 "227 Entering Passive Mode 127,0,0,1,123,456\r\n"); 473 case PRE_SIZE: 474 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_CWD, 475 "213 18\r\n"); 476 case PRE_CWD: 477 return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data, PRE_RETR, 478 "550 Not a directory\r\n"); 479 case PRE_RETR: 480 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_QUIT, 481 "200 OK\r\n"); 482 default: 483 return FtpSocketDataProvider::OnWrite(data); 484 } 485 } 486 487 private: 488 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload); 489}; 490 491class FtpSocketDataProviderEscaping : public FtpSocketDataProviderFileDownload { 492 public: 493 FtpSocketDataProviderEscaping() { 494 } 495 496 virtual MockWriteResult OnWrite(const std::string& data) { 497 if (InjectFault()) 498 return MockWriteResult(true, data.length()); 499 switch (state()) { 500 case PRE_SIZE: 501 return Verify("SIZE / !\"#$%y\200\201\r\n", data, PRE_CWD, 502 "213 18\r\n"); 503 case PRE_CWD: 504 return Verify("CWD / !\"#$%y\200\201\r\n", data, PRE_RETR, 505 "550 Not a directory\r\n"); 506 case PRE_RETR: 507 return Verify("RETR / !\"#$%y\200\201\r\n", data, PRE_QUIT, 508 "200 OK\r\n"); 509 default: 510 return FtpSocketDataProviderFileDownload::OnWrite(data); 511 } 512 } 513 514 private: 515 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping); 516}; 517 518class FtpSocketDataProviderFileDownloadTransferStarting 519 : public FtpSocketDataProviderFileDownload { 520 public: 521 FtpSocketDataProviderFileDownloadTransferStarting() { 522 } 523 524 virtual MockWriteResult OnWrite(const std::string& data) { 525 if (InjectFault()) 526 return MockWriteResult(true, data.length()); 527 switch (state()) { 528 case PRE_RETR: 529 return Verify("RETR /file\r\n", data, PRE_QUIT, 530 "125-Data connection already open.\r\n" 531 "125 Transfer starting.\r\n" 532 "226 Transfer complete.\r\n"); 533 default: 534 return FtpSocketDataProviderFileDownload::OnWrite(data); 535 } 536 } 537 538 private: 539 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting); 540}; 541 542class FtpSocketDataProviderDirectoryListingTransferStarting 543 : public FtpSocketDataProviderDirectoryListing { 544 public: 545 FtpSocketDataProviderDirectoryListingTransferStarting() { 546 } 547 548 virtual MockWriteResult OnWrite(const std::string& data) { 549 if (InjectFault()) 550 return MockWriteResult(true, data.length()); 551 switch (state()) { 552 case PRE_LIST: 553 return Verify("LIST\r\n", data, PRE_QUIT, 554 "125-Data connection already open.\r\n" 555 "125 Transfer starting.\r\n" 556 "226 Transfer complete.\r\n"); 557 default: 558 return FtpSocketDataProviderDirectoryListing::OnWrite(data); 559 } 560 } 561 562 private: 563 DISALLOW_COPY_AND_ASSIGN( 564 FtpSocketDataProviderDirectoryListingTransferStarting); 565}; 566 567class FtpSocketDataProviderFileDownloadInvalidResponse 568 : public FtpSocketDataProviderFileDownload { 569 public: 570 FtpSocketDataProviderFileDownloadInvalidResponse() { 571 } 572 573 virtual MockWriteResult OnWrite(const std::string& data) { 574 if (InjectFault()) 575 return MockWriteResult(true, data.length()); 576 switch (state()) { 577 case PRE_SIZE: 578 // Use unallocated 599 FTP error code to make sure it falls into the 579 // generic ERR_FTP_FAILED bucket. 580 return Verify("SIZE /file\r\n", data, PRE_QUIT, 581 "599 Evil Response\r\n" 582 "599 More Evil\r\n"); 583 default: 584 return FtpSocketDataProviderFileDownload::OnWrite(data); 585 } 586 } 587 588 private: 589 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse); 590}; 591 592class FtpSocketDataProviderEvilEpsv : public FtpSocketDataProviderFileDownload { 593 public: 594 FtpSocketDataProviderEvilEpsv(const char* epsv_response, 595 State expected_state) 596 : epsv_response_(epsv_response), 597 epsv_response_length_(std::strlen(epsv_response)), 598 expected_state_(expected_state) {} 599 600 FtpSocketDataProviderEvilEpsv(const char* epsv_response, 601 size_t epsv_response_length, 602 State expected_state) 603 : epsv_response_(epsv_response), 604 epsv_response_length_(epsv_response_length), 605 expected_state_(expected_state) {} 606 607 virtual MockWriteResult OnWrite(const std::string& data) { 608 if (InjectFault()) 609 return MockWriteResult(true, data.length()); 610 switch (state()) { 611 case PRE_EPSV: 612 return Verify("EPSV\r\n", data, expected_state_, 613 epsv_response_, epsv_response_length_); 614 default: 615 return FtpSocketDataProviderFileDownload::OnWrite(data); 616 } 617 } 618 619 private: 620 const char* epsv_response_; 621 const size_t epsv_response_length_; 622 const State expected_state_; 623 624 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv); 625}; 626 627class FtpSocketDataProviderEvilPasv 628 : public FtpSocketDataProviderFileDownloadWithPasvFallback { 629 public: 630 explicit FtpSocketDataProviderEvilPasv(const char* pasv_response, 631 State expected_state) 632 : pasv_response_(pasv_response), 633 expected_state_(expected_state) { 634 } 635 636 virtual MockWriteResult OnWrite(const std::string& data) { 637 if (InjectFault()) 638 return MockWriteResult(true, data.length()); 639 switch (state()) { 640 case PRE_PASV: 641 return Verify("PASV\r\n", data, expected_state_, pasv_response_); 642 default: 643 return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data); 644 } 645 } 646 647 private: 648 const char* pasv_response_; 649 const State expected_state_; 650 651 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv); 652}; 653 654class FtpSocketDataProviderEvilSize : public FtpSocketDataProviderFileDownload { 655 public: 656 FtpSocketDataProviderEvilSize(const char* size_response, State expected_state) 657 : size_response_(size_response), 658 expected_state_(expected_state) { 659 } 660 661 virtual MockWriteResult OnWrite(const std::string& data) { 662 if (InjectFault()) 663 return MockWriteResult(true, data.length()); 664 switch (state()) { 665 case PRE_SIZE: 666 return Verify("SIZE /file\r\n", data, expected_state_, size_response_); 667 default: 668 return FtpSocketDataProviderFileDownload::OnWrite(data); 669 } 670 } 671 672 private: 673 const char* size_response_; 674 const State expected_state_; 675 676 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize); 677}; 678 679class FtpSocketDataProviderEvilLogin 680 : public FtpSocketDataProviderFileDownload { 681 public: 682 FtpSocketDataProviderEvilLogin(const char* expected_user, 683 const char* expected_password) 684 : expected_user_(expected_user), 685 expected_password_(expected_password) { 686 } 687 688 virtual MockWriteResult OnWrite(const std::string& data) { 689 if (InjectFault()) 690 return MockWriteResult(true, data.length()); 691 switch (state()) { 692 case PRE_USER: 693 return Verify(std::string("USER ") + expected_user_ + "\r\n", data, 694 PRE_PASSWD, "331 Password needed\r\n"); 695 case PRE_PASSWD: 696 return Verify(std::string("PASS ") + expected_password_ + "\r\n", data, 697 PRE_SYST, "230 Welcome\r\n"); 698 default: 699 return FtpSocketDataProviderFileDownload::OnWrite(data); 700 } 701 } 702 703 private: 704 const char* expected_user_; 705 const char* expected_password_; 706 707 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin); 708}; 709 710class FtpSocketDataProviderCloseConnection : public FtpSocketDataProvider { 711 public: 712 FtpSocketDataProviderCloseConnection() { 713 } 714 715 virtual MockWriteResult OnWrite(const std::string& data) { 716 if (InjectFault()) 717 return MockWriteResult(true, data.length()); 718 switch (state()) { 719 case PRE_USER: 720 return Verify("USER anonymous\r\n", data, 721 PRE_QUIT, ""); 722 default: 723 return FtpSocketDataProvider::OnWrite(data); 724 } 725 } 726 727 private: 728 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection); 729}; 730 731class FtpNetworkTransactionTest : public PlatformTest { 732 public: 733 FtpNetworkTransactionTest() 734 : host_resolver_(new MockHostResolver), 735 session_(new FtpNetworkSession(host_resolver_.get())), 736 transaction_(session_.get(), &mock_socket_factory_) { 737 } 738 739 protected: 740 FtpRequestInfo GetRequestInfo(const std::string& url) { 741 FtpRequestInfo info; 742 info.url = GURL(url); 743 return info; 744 } 745 746 void ExecuteTransaction(FtpSocketDataProvider* ctrl_socket, 747 const char* request, 748 int expected_result) { 749 std::string mock_data("mock-data"); 750 MockRead data_reads[] = { 751 // Usually FTP servers close the data connection after the entire data has 752 // been received. 753 MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 754 MockRead(mock_data.c_str()), 755 }; 756 StaticSocketDataProvider data_socket(data_reads, arraysize(data_reads), 757 NULL, 0); 758 mock_socket_factory_.AddSocketDataProvider(ctrl_socket); 759 mock_socket_factory_.AddSocketDataProvider(&data_socket); 760 FtpRequestInfo request_info = GetRequestInfo(request); 761 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState()); 762 ASSERT_EQ(ERR_IO_PENDING, 763 transaction_.Start(&request_info, &callback_, BoundNetLog())); 764 EXPECT_NE(LOAD_STATE_IDLE, transaction_.GetLoadState()); 765 ASSERT_EQ(expected_result, callback_.WaitForResult()); 766 if (expected_result == OK) { 767 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(kBufferSize)); 768 memset(io_buffer->data(), 0, kBufferSize); 769 ASSERT_EQ(ERR_IO_PENDING, 770 transaction_.Read(io_buffer.get(), kBufferSize, &callback_)); 771 ASSERT_EQ(static_cast<int>(mock_data.length()), 772 callback_.WaitForResult()); 773 EXPECT_EQ(mock_data, std::string(io_buffer->data(), mock_data.length())); 774 775 // Do another Read to detect that the data socket is now closed. 776 int rv = transaction_.Read(io_buffer.get(), kBufferSize, &callback_); 777 if (rv == ERR_IO_PENDING) { 778 EXPECT_EQ(0, callback_.WaitForResult()); 779 } else { 780 EXPECT_EQ(0, rv); 781 } 782 } 783 EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket->state()); 784 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState()); 785 } 786 787 void TransactionFailHelper(FtpSocketDataProvider* ctrl_socket, 788 const char* request, 789 FtpSocketDataProvider::State state, 790 FtpSocketDataProvider::State next_state, 791 const char* response, 792 int expected_result) { 793 ctrl_socket->InjectFailure(state, next_state, response); 794 ExecuteTransaction(ctrl_socket, request, expected_result); 795 } 796 797 scoped_ptr<MockHostResolver> host_resolver_; 798 scoped_refptr<FtpNetworkSession> session_; 799 MockClientSocketFactory mock_socket_factory_; 800 FtpNetworkTransaction transaction_; 801 TestCompletionCallback callback_; 802}; 803 804TEST_F(FtpNetworkTransactionTest, FailedLookup) { 805 FtpRequestInfo request_info = GetRequestInfo("ftp://badhost"); 806 host_resolver_->rules()->AddSimulatedFailure("badhost"); 807 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState()); 808 ASSERT_EQ(ERR_IO_PENDING, 809 transaction_.Start(&request_info, &callback_, BoundNetLog())); 810 ASSERT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult()); 811 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState()); 812} 813 814// Check that when determining the host, the square brackets decorating IPv6 815// literals in URLs are stripped. 816TEST_F(FtpNetworkTransactionTest, StripBracketsFromIPv6Literals) { 817 host_resolver_->rules()->AddSimulatedFailure("[::1]"); 818 819 // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE. 820 // The important part of this test is to make sure that we don't fail with 821 // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname 822 // was used. 823 FtpSocketDataProviderEvilSize ctrl_socket( 824 "213 99999999999999999999999999999999\r\n", 825 FtpSocketDataProvider::PRE_QUIT); 826 ExecuteTransaction(&ctrl_socket, "ftp://[::1]/file", ERR_INVALID_RESPONSE); 827} 828 829TEST_F(FtpNetworkTransactionTest, DirectoryTransaction) { 830 FtpSocketDataProviderDirectoryListing ctrl_socket; 831 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 832 833 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing); 834 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size); 835 EXPECT_EQ("192.0.2.33", 836 transaction_.GetResponseInfo()->socket_address.host()); 837 EXPECT_EQ(0, transaction_.GetResponseInfo()->socket_address.port()); 838} 839 840TEST_F(FtpNetworkTransactionTest, DirectoryTransactionWithPasvFallback) { 841 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket; 842 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 843 844 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing); 845 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size); 846} 847 848TEST_F(FtpNetworkTransactionTest, DirectoryTransactionWithTypecode) { 849 FtpSocketDataProviderDirectoryListing ctrl_socket; 850 ExecuteTransaction(&ctrl_socket, "ftp://host;type=d", OK); 851 852 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing); 853 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size); 854} 855 856TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcome) { 857 FtpSocketDataProviderDirectoryListing ctrl_socket; 858 ctrl_socket.set_multiline_welcome(true); 859 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 860} 861 862TEST_F(FtpNetworkTransactionTest, DirectoryTransactionShortReads2) { 863 FtpSocketDataProviderDirectoryListing ctrl_socket; 864 ctrl_socket.set_short_read_limit(2); 865 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 866} 867 868TEST_F(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) { 869 FtpSocketDataProviderDirectoryListing ctrl_socket; 870 ctrl_socket.set_short_read_limit(5); 871 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 872} 873 874TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcomeShort) { 875 FtpSocketDataProviderDirectoryListing ctrl_socket; 876 // The client will not consume all three 230 lines. That's good, we want to 877 // test that scenario. 878 ctrl_socket.allow_unconsumed_reads(true); 879 ctrl_socket.set_multiline_welcome(true); 880 ctrl_socket.set_short_read_limit(5); 881 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 882} 883 884// Regression test for http://crbug.com/60555. 885TEST_F(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) { 886 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket; 887 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 888} 889 890TEST_F(FtpNetworkTransactionTest, DirectoryTransactionVMS) { 891 FtpSocketDataProviderVMSDirectoryListing ctrl_socket; 892 ExecuteTransaction(&ctrl_socket, "ftp://host/dir", OK); 893} 894 895TEST_F(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) { 896 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket; 897 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 898} 899 900TEST_F(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) { 901 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket; 902 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); 903} 904 905TEST_F(FtpNetworkTransactionTest, DownloadTransaction) { 906 FtpSocketDataProviderFileDownload ctrl_socket; 907 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 908 909 // We pass an artificial value of 18 as a response to the SIZE command. 910 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); 911 EXPECT_EQ("192.0.2.33", 912 transaction_.GetResponseInfo()->socket_address.host()); 913 EXPECT_EQ(0, transaction_.GetResponseInfo()->socket_address.port()); 914} 915 916TEST_F(FtpNetworkTransactionTest, DownloadTransactionWithPasvFallback) { 917 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket; 918 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 919 920 // We pass an artificial value of 18 as a response to the SIZE command. 921 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); 922} 923 924TEST_F(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeA) { 925 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket; 926 ctrl_socket.set_data_type('A'); 927 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=a", OK); 928 929 // We pass an artificial value of 18 as a response to the SIZE command. 930 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); 931} 932 933TEST_F(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeI) { 934 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket; 935 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=i", OK); 936 937 // We pass an artificial value of 18 as a response to the SIZE command. 938 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); 939} 940 941TEST_F(FtpNetworkTransactionTest, DownloadTransactionMultilineWelcome) { 942 FtpSocketDataProviderFileDownload ctrl_socket; 943 ctrl_socket.set_multiline_welcome(true); 944 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 945} 946 947TEST_F(FtpNetworkTransactionTest, DownloadTransactionShortReads2) { 948 FtpSocketDataProviderFileDownload ctrl_socket; 949 ctrl_socket.set_short_read_limit(2); 950 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 951} 952 953TEST_F(FtpNetworkTransactionTest, DownloadTransactionShortReads5) { 954 FtpSocketDataProviderFileDownload ctrl_socket; 955 ctrl_socket.set_short_read_limit(5); 956 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 957} 958 959TEST_F(FtpNetworkTransactionTest, DownloadTransactionZeroSize) { 960 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket; 961 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 962} 963 964TEST_F(FtpNetworkTransactionTest, DownloadTransactionVMS) { 965 FtpSocketDataProviderVMSFileDownload ctrl_socket; 966 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 967} 968 969TEST_F(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) { 970 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket; 971 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 972} 973 974TEST_F(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) { 975 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket; 976 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 977} 978 979TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvReallyBadFormat) { 980 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,\r\n", 981 FtpSocketDataProvider::PRE_QUIT); 982 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 983} 984 985TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort1) { 986 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n", 987 FtpSocketDataProvider::PRE_QUIT); 988 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 989} 990 991TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort2) { 992 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024. 993 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n", 994 FtpSocketDataProvider::PRE_QUIT); 995 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 996} 997 998TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort3) { 999 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024. 1000 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n", 1001 FtpSocketDataProvider::PRE_QUIT); 1002 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1003} 1004 1005TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort4) { 1006 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs. 1007 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n", 1008 FtpSocketDataProvider::PRE_QUIT); 1009 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1010} 1011 1012TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafeHost) { 1013 FtpSocketDataProviderEvilPasv ctrl_socket( 1014 "227 Portscan (10,1,2,3,4,123,456)\r\n", FtpSocketDataProvider::PRE_SIZE); 1015 std::string mock_data("mock-data"); 1016 MockRead data_reads[] = { 1017 MockRead(mock_data.c_str()), 1018 }; 1019 StaticSocketDataProvider data_socket1(data_reads, arraysize(data_reads), 1020 NULL, 0); 1021 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket); 1022 mock_socket_factory_.AddSocketDataProvider(&data_socket1); 1023 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file"); 1024 1025 // Start the transaction. 1026 ASSERT_EQ(ERR_IO_PENDING, 1027 transaction_.Start(&request_info, &callback_, BoundNetLog())); 1028 ASSERT_EQ(OK, callback_.WaitForResult()); 1029 1030 // The transaction fires the callback when we can start reading data. That 1031 // means that the data socket should be open. 1032 MockTCPClientSocket* data_socket = 1033 mock_socket_factory_.GetMockTCPClientSocket(1); 1034 ASSERT_TRUE(data_socket); 1035 ASSERT_TRUE(data_socket->IsConnected()); 1036 1037 // Even if the PASV response specified some other address, we connect 1038 // to the address we used for control connection (which could be 127.0.0.1 1039 // or ::1 depending on whether we use IPv6). 1040 const struct addrinfo* addrinfo = data_socket->addresses().head(); 1041 while (addrinfo) { 1042 EXPECT_NE("1.2.3.4", NetAddressToString(addrinfo)); 1043 addrinfo = addrinfo->ai_next; 1044 } 1045} 1046 1047TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat1) { 1048 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22)\r\n", 1049 FtpSocketDataProvider::PRE_QUIT); 1050 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1051} 1052 1053TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat2) { 1054 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||\r\n", 1055 FtpSocketDataProvider::PRE_QUIT); 1056 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1057} 1058 1059TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat3) { 1060 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan\r\n", 1061 FtpSocketDataProvider::PRE_QUIT); 1062 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1063} 1064 1065TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat4) { 1066 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||||)\r\n", 1067 FtpSocketDataProvider::PRE_QUIT); 1068 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1069} 1070 1071TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat5) { 1072 const char response[] = "227 Portscan (\0\0\031773\0)\r\n"; 1073 FtpSocketDataProviderEvilEpsv ctrl_socket(response, sizeof(response)-1, 1074 FtpSocketDataProvider::PRE_QUIT); 1075 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1076} 1077 1078TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort1) { 1079 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22|)\r\n", 1080 FtpSocketDataProvider::PRE_QUIT); 1081 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1082} 1083 1084TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort2) { 1085 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||258|)\r\n", 1086 FtpSocketDataProvider::PRE_QUIT); 1087 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1088} 1089 1090TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort3) { 1091 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||772|)\r\n", 1092 FtpSocketDataProvider::PRE_QUIT); 1093 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1094} 1095 1096TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort4) { 1097 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||2049|)\r\n", 1098 FtpSocketDataProvider::PRE_QUIT); 1099 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1100} 1101 1102TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvWeirdSep) { 1103 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$31744$)\r\n", 1104 FtpSocketDataProvider::PRE_SIZE); 1105 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 1106} 1107 1108TEST_F(FtpNetworkTransactionTest, 1109 DownloadTransactionEvilEpsvWeirdSepUnsafePort) { 1110 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$317$)\r\n", 1111 FtpSocketDataProvider::PRE_QUIT); 1112 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); 1113} 1114 1115TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvIllegalHost) { 1116 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|2|::1|31744|)\r\n", 1117 FtpSocketDataProvider::PRE_QUIT); 1118 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1119} 1120 1121TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) { 1122 FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test"); 1123 ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", OK); 1124} 1125 1126TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) { 1127 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld"); 1128 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", OK); 1129} 1130 1131TEST_F(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) { 1132 FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test"); 1133 ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", OK); 1134} 1135 1136TEST_F(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) { 1137 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world"); 1138 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", OK); 1139} 1140 1141TEST_F(FtpNetworkTransactionTest, EvilRestartUser) { 1142 FtpSocketDataProvider ctrl_socket1; 1143 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD, 1144 FtpSocketDataProvider::PRE_QUIT, 1145 "530 Login authentication failed\r\n"); 1146 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1); 1147 1148 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file"); 1149 1150 ASSERT_EQ(ERR_IO_PENDING, 1151 transaction_.Start(&request_info, &callback_, BoundNetLog())); 1152 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult()); 1153 1154 MockRead ctrl_reads[] = { 1155 MockRead("220 host TestFTPd\r\n"), 1156 MockRead("221 Goodbye!\r\n"), 1157 MockRead(false, OK), 1158 }; 1159 MockWrite ctrl_writes[] = { 1160 MockWrite("QUIT\r\n"), 1161 }; 1162 StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads), 1163 ctrl_writes, arraysize(ctrl_writes)); 1164 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2); 1165 ASSERT_EQ(ERR_IO_PENDING, 1166 transaction_.RestartWithAuth(ASCIIToUTF16("foo\nownz0red"), 1167 ASCIIToUTF16("innocent"), 1168 &callback_)); 1169 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult()); 1170} 1171 1172TEST_F(FtpNetworkTransactionTest, EvilRestartPassword) { 1173 FtpSocketDataProvider ctrl_socket1; 1174 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD, 1175 FtpSocketDataProvider::PRE_QUIT, 1176 "530 Login authentication failed\r\n"); 1177 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1); 1178 1179 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file"); 1180 1181 ASSERT_EQ(ERR_IO_PENDING, 1182 transaction_.Start(&request_info, &callback_, BoundNetLog())); 1183 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult()); 1184 1185 MockRead ctrl_reads[] = { 1186 MockRead("220 host TestFTPd\r\n"), 1187 MockRead("331 User okay, send password\r\n"), 1188 MockRead("221 Goodbye!\r\n"), 1189 MockRead(false, OK), 1190 }; 1191 MockWrite ctrl_writes[] = { 1192 MockWrite("USER innocent\r\n"), 1193 MockWrite("QUIT\r\n"), 1194 }; 1195 StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads), 1196 ctrl_writes, arraysize(ctrl_writes)); 1197 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2); 1198 ASSERT_EQ(ERR_IO_PENDING, 1199 transaction_.RestartWithAuth(ASCIIToUTF16("innocent"), 1200 ASCIIToUTF16("foo\nownz0red"), 1201 &callback_)); 1202 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult()); 1203} 1204 1205TEST_F(FtpNetworkTransactionTest, Escaping) { 1206 FtpSocketDataProviderEscaping ctrl_socket; 1207 ExecuteTransaction(&ctrl_socket, "ftp://host/%20%21%22%23%24%25%79%80%81", 1208 OK); 1209} 1210 1211// Test for http://crbug.com/23794. 1212TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilSize) { 1213 // Try to overflow int64 in the response. 1214 FtpSocketDataProviderEvilSize ctrl_socket( 1215 "213 99999999999999999999999999999999\r\n", 1216 FtpSocketDataProvider::PRE_QUIT); 1217 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); 1218} 1219 1220// Test for http://crbug.com/36360. 1221TEST_F(FtpNetworkTransactionTest, DownloadTransactionBigSize) { 1222 // Pass a valid, but large file size. The transaction should not fail. 1223 FtpSocketDataProviderEvilSize ctrl_socket( 1224 "213 3204427776\r\n", 1225 FtpSocketDataProvider::PRE_CWD); 1226 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); 1227 EXPECT_EQ(3204427776LL, 1228 transaction_.GetResponseInfo()->expected_content_size); 1229} 1230 1231// Regression test for http://crbug.com/25023. 1232TEST_F(FtpNetworkTransactionTest, CloseConnection) { 1233 FtpSocketDataProviderCloseConnection ctrl_socket; 1234 ExecuteTransaction(&ctrl_socket, "ftp://host", ERR_EMPTY_RESPONSE); 1235} 1236 1237TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailUser) { 1238 FtpSocketDataProviderDirectoryListing ctrl_socket; 1239 // Use unallocated 599 FTP error code to make sure it falls into the generic 1240 // ERR_FTP_FAILED bucket. 1241 TransactionFailHelper(&ctrl_socket, 1242 "ftp://host", 1243 FtpSocketDataProvider::PRE_USER, 1244 FtpSocketDataProvider::PRE_QUIT, 1245 "599 fail\r\n", 1246 ERR_FTP_FAILED); 1247} 1248 1249TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPass) { 1250 FtpSocketDataProviderDirectoryListing ctrl_socket; 1251 TransactionFailHelper(&ctrl_socket, 1252 "ftp://host", 1253 FtpSocketDataProvider::PRE_PASSWD, 1254 FtpSocketDataProvider::PRE_QUIT, 1255 "530 Login authentication failed\r\n", 1256 ERR_FTP_FAILED); 1257} 1258 1259// Regression test for http://crbug.com/38707. 1260TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPass503) { 1261 FtpSocketDataProviderDirectoryListing ctrl_socket; 1262 TransactionFailHelper(&ctrl_socket, 1263 "ftp://host", 1264 FtpSocketDataProvider::PRE_PASSWD, 1265 FtpSocketDataProvider::PRE_QUIT, 1266 "503 Bad sequence of commands\r\n", 1267 ERR_FTP_BAD_COMMAND_SEQUENCE); 1268} 1269 1270TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailSyst) { 1271 FtpSocketDataProviderDirectoryListing ctrl_socket; 1272 // Use unallocated 599 FTP error code to make sure it falls into the generic 1273 // ERR_FTP_FAILED bucket. 1274 TransactionFailHelper(&ctrl_socket, 1275 "ftp://host", 1276 FtpSocketDataProvider::PRE_SYST, 1277 FtpSocketDataProvider::PRE_PWD, 1278 "599 fail\r\n", 1279 OK); 1280} 1281 1282TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPwd) { 1283 FtpSocketDataProviderDirectoryListing ctrl_socket; 1284 // Use unallocated 599 FTP error code to make sure it falls into the generic 1285 // ERR_FTP_FAILED bucket. 1286 TransactionFailHelper(&ctrl_socket, 1287 "ftp://host", 1288 FtpSocketDataProvider::PRE_PWD, 1289 FtpSocketDataProvider::PRE_QUIT, 1290 "599 fail\r\n", 1291 ERR_FTP_FAILED); 1292} 1293 1294TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailType) { 1295 FtpSocketDataProviderDirectoryListing ctrl_socket; 1296 // Use unallocated 599 FTP error code to make sure it falls into the generic 1297 // ERR_FTP_FAILED bucket. 1298 TransactionFailHelper(&ctrl_socket, 1299 "ftp://host", 1300 FtpSocketDataProvider::PRE_TYPE, 1301 FtpSocketDataProvider::PRE_QUIT, 1302 "599 fail\r\n", 1303 ERR_FTP_FAILED); 1304} 1305 1306TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailEpsv) { 1307 FtpSocketDataProviderDirectoryListing ctrl_socket; 1308 // Use unallocated 599 FTP error code to make sure it falls into the generic 1309 // ERR_FTP_FAILED bucket. 1310 TransactionFailHelper(&ctrl_socket, 1311 "ftp://host", 1312 FtpSocketDataProvider::PRE_EPSV, 1313 FtpSocketDataProvider::PRE_NOPASV, 1314 "599 fail\r\n", 1315 ERR_FTP_FAILED); 1316} 1317 1318TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailCwd) { 1319 FtpSocketDataProviderDirectoryListing ctrl_socket; 1320 // Use unallocated 599 FTP error code to make sure it falls into the generic 1321 // ERR_FTP_FAILED bucket. 1322 TransactionFailHelper(&ctrl_socket, 1323 "ftp://host", 1324 FtpSocketDataProvider::PRE_CWD, 1325 FtpSocketDataProvider::PRE_QUIT, 1326 "599 fail\r\n", 1327 ERR_FTP_FAILED); 1328} 1329 1330TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailList) { 1331 FtpSocketDataProviderVMSDirectoryListing ctrl_socket; 1332 // Use unallocated 599 FTP error code to make sure it falls into the generic 1333 // ERR_FTP_FAILED bucket. 1334 TransactionFailHelper(&ctrl_socket, 1335 "ftp://host/dir", 1336 FtpSocketDataProvider::PRE_LIST, 1337 FtpSocketDataProvider::PRE_QUIT, 1338 "599 fail\r\n", 1339 ERR_FTP_FAILED); 1340} 1341 1342TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailUser) { 1343 FtpSocketDataProviderFileDownload ctrl_socket; 1344 // Use unallocated 599 FTP error code to make sure it falls into the generic 1345 // ERR_FTP_FAILED bucket. 1346 TransactionFailHelper(&ctrl_socket, 1347 "ftp://host/file", 1348 FtpSocketDataProvider::PRE_USER, 1349 FtpSocketDataProvider::PRE_QUIT, 1350 "599 fail\r\n", 1351 ERR_FTP_FAILED); 1352} 1353 1354TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailPass) { 1355 FtpSocketDataProviderFileDownload ctrl_socket; 1356 TransactionFailHelper(&ctrl_socket, 1357 "ftp://host/file", 1358 FtpSocketDataProvider::PRE_PASSWD, 1359 FtpSocketDataProvider::PRE_QUIT, 1360 "530 Login authentication failed\r\n", 1361 ERR_FTP_FAILED); 1362} 1363 1364TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailSyst) { 1365 FtpSocketDataProviderFileDownload ctrl_socket; 1366 // Use unallocated 599 FTP error code to make sure it falls into the generic 1367 // ERR_FTP_FAILED bucket. 1368 TransactionFailHelper(&ctrl_socket, 1369 "ftp://host/file", 1370 FtpSocketDataProvider::PRE_SYST, 1371 FtpSocketDataProvider::PRE_PWD, 1372 "599 fail\r\n", 1373 OK); 1374} 1375 1376TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailPwd) { 1377 FtpSocketDataProviderFileDownload ctrl_socket; 1378 // Use unallocated 599 FTP error code to make sure it falls into the generic 1379 // ERR_FTP_FAILED bucket. 1380 TransactionFailHelper(&ctrl_socket, 1381 "ftp://host/file", 1382 FtpSocketDataProvider::PRE_PWD, 1383 FtpSocketDataProvider::PRE_QUIT, 1384 "599 fail\r\n", 1385 ERR_FTP_FAILED); 1386} 1387 1388TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailType) { 1389 FtpSocketDataProviderFileDownload ctrl_socket; 1390 // Use unallocated 599 FTP error code to make sure it falls into the generic 1391 // ERR_FTP_FAILED bucket. 1392 TransactionFailHelper(&ctrl_socket, 1393 "ftp://host/file", 1394 FtpSocketDataProvider::PRE_TYPE, 1395 FtpSocketDataProvider::PRE_QUIT, 1396 "599 fail\r\n", 1397 ERR_FTP_FAILED); 1398} 1399 1400TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailEpsv) { 1401 FtpSocketDataProviderFileDownload ctrl_socket; 1402 // Use unallocated 599 FTP error code to make sure it falls into the generic 1403 // ERR_FTP_FAILED bucket. 1404 TransactionFailHelper(&ctrl_socket, 1405 "ftp://host/file", 1406 FtpSocketDataProvider::PRE_EPSV, 1407 FtpSocketDataProvider::PRE_NOPASV, 1408 "599 fail\r\n", 1409 ERR_FTP_FAILED); 1410} 1411 1412TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailRetr) { 1413 FtpSocketDataProviderFileDownload ctrl_socket; 1414 // Use unallocated 599 FTP error code to make sure it falls into the generic 1415 // ERR_FTP_FAILED bucket. 1416 TransactionFailHelper(&ctrl_socket, 1417 "ftp://host/file", 1418 FtpSocketDataProvider::PRE_RETR, 1419 FtpSocketDataProvider::PRE_QUIT, 1420 "599 fail\r\n", 1421 ERR_FTP_FAILED); 1422} 1423 1424TEST_F(FtpNetworkTransactionTest, FileNotFound) { 1425 FtpSocketDataProviderFileNotFound ctrl_socket; 1426 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_FTP_FAILED); 1427} 1428 1429// Test for http://crbug.com/38845. 1430TEST_F(FtpNetworkTransactionTest, ZeroLengthDirInPWD) { 1431 FtpSocketDataProviderFileDownload ctrl_socket; 1432 TransactionFailHelper(&ctrl_socket, 1433 "ftp://host/file", 1434 FtpSocketDataProvider::PRE_PWD, 1435 FtpSocketDataProvider::PRE_TYPE, 1436 "257 \"\"\r\n", 1437 OK); 1438} 1439 1440} // namespace net 1441