Home | History | Annotate | Download | only in ftp
      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 
     24 namespace {
     25 
     26 // Size we use for IOBuffers used to receive data from the test data socket.
     27 const int kBufferSize = 128;
     28 
     29 }  // namespace
     30 
     31 namespace net {
     32 
     33 class 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 (at) 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 
    179 class 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 
    204 class 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 
    230 class 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 
    251 class 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 
    287 class 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 
    326 class 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 
    350 class 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 
    376 class 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 
    403 class 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 
    428 class 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 
    453 class 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 
    491 class 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 
    518 class 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 
    542 class 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 
    567 class 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 
    592 class 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 
    627 class 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 
    654 class 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 
    679 class 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 
    710 class 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 
    731 class 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 
    804 TEST_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.
    816 TEST_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 
    829 TEST_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 
    840 TEST_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 
    848 TEST_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 
    856 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcome) {
    857   FtpSocketDataProviderDirectoryListing ctrl_socket;
    858   ctrl_socket.set_multiline_welcome(true);
    859   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
    860 }
    861 
    862 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionShortReads2) {
    863   FtpSocketDataProviderDirectoryListing ctrl_socket;
    864   ctrl_socket.set_short_read_limit(2);
    865   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
    866 }
    867 
    868 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) {
    869   FtpSocketDataProviderDirectoryListing ctrl_socket;
    870   ctrl_socket.set_short_read_limit(5);
    871   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
    872 }
    873 
    874 TEST_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.
    885 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) {
    886   FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket;
    887   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
    888 }
    889 
    890 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionVMS) {
    891   FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
    892   ExecuteTransaction(&ctrl_socket, "ftp://host/dir", OK);
    893 }
    894 
    895 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) {
    896   FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket;
    897   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
    898 }
    899 
    900 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) {
    901   FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket;
    902   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
    903 }
    904 
    905 TEST_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 
    916 TEST_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 
    924 TEST_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 
    933 TEST_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 
    941 TEST_F(FtpNetworkTransactionTest, DownloadTransactionMultilineWelcome) {
    942   FtpSocketDataProviderFileDownload ctrl_socket;
    943   ctrl_socket.set_multiline_welcome(true);
    944   ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
    945 }
    946 
    947 TEST_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 
    953 TEST_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 
    959 TEST_F(FtpNetworkTransactionTest, DownloadTransactionZeroSize) {
    960   FtpSocketDataProviderFileDownloadZeroSize ctrl_socket;
    961   ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
    962 }
    963 
    964 TEST_F(FtpNetworkTransactionTest, DownloadTransactionVMS) {
    965   FtpSocketDataProviderVMSFileDownload ctrl_socket;
    966   ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
    967 }
    968 
    969 TEST_F(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) {
    970   FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket;
    971   ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
    972 }
    973 
    974 TEST_F(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) {
    975   FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket;
    976   ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
    977 }
    978 
    979 TEST_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 
    985 TEST_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 
    991 TEST_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 
    998 TEST_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 
   1005 TEST_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 
   1012 TEST_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 
   1047 TEST_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 
   1053 TEST_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 
   1059 TEST_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 
   1065 TEST_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 
   1071 TEST_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 
   1078 TEST_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 
   1084 TEST_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 
   1090 TEST_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 
   1096 TEST_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 
   1102 TEST_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 
   1108 TEST_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 
   1115 TEST_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 
   1121 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) {
   1122   FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test");
   1123   ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", OK);
   1124 }
   1125 
   1126 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) {
   1127   FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld");
   1128   ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", OK);
   1129 }
   1130 
   1131 TEST_F(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) {
   1132   FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test");
   1133   ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", OK);
   1134 }
   1135 
   1136 TEST_F(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) {
   1137   FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world");
   1138   ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", OK);
   1139 }
   1140 
   1141 TEST_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 
   1172 TEST_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 
   1205 TEST_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.
   1212 TEST_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.
   1221 TEST_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.
   1232 TEST_F(FtpNetworkTransactionTest, CloseConnection) {
   1233   FtpSocketDataProviderCloseConnection ctrl_socket;
   1234   ExecuteTransaction(&ctrl_socket, "ftp://host", ERR_EMPTY_RESPONSE);
   1235 }
   1236 
   1237 TEST_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 
   1249 TEST_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.
   1260 TEST_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 
   1270 TEST_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 
   1282 TEST_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 
   1294 TEST_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 
   1306 TEST_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 
   1318 TEST_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 
   1330 TEST_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 
   1342 TEST_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 
   1354 TEST_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 
   1364 TEST_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 
   1376 TEST_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 
   1388 TEST_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 
   1400 TEST_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 
   1412 TEST_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 
   1424 TEST_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.
   1430 TEST_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