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