1 /* 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors 3 * 4 * Squid software is distributed under GPLv2+ license and includes 5 * contributions from numerous individuals and organizations. 6 * Please see the COPYING and CONTRIBUTORS files for details. 7 */ 8 9 /* DEBUG: section 09 File Transfer Protocol (FTP) */ 10 11 #ifndef SQUID_FTP_CLIENT_H 12 #define SQUID_FTP_CLIENT_H 13 14 #include "clients/Client.h" 15 16 class String; 17 namespace Ftp 18 { 19 20 extern const char *const crlf; 21 22 /// Common code for FTP server control and data channels. 23 /// Does not own the channel descriptor, which is managed by Ftp::Client. 24 class Channel 25 { 26 public: 27 /// called after the socket is opened, sets up close handler 28 void opened(const Comm::ConnectionPointer &conn, const AsyncCall::Pointer &aCloser); 29 30 /** Handles all operations needed to properly close the active channel FD. 31 * clearing the close handler, clearing the listen socket properly, and calling comm_close 32 */ 33 void close(); 34 35 void forget(); /// remove the close handler, leave connection open 36 37 void clear(); ///< just drops conn and close handler. does not close active connections. 38 39 Comm::ConnectionPointer conn; ///< channel descriptor 40 41 /** A temporary handle to the connection being listened on. 42 * Closing this will also close the waiting Data channel acceptor. 43 * If a data connection has already been accepted but is still waiting in the event queue 44 * the callback will still happen and needs to be handled (usually dropped). 45 */ 46 Comm::ConnectionPointer listenConn; 47 48 AsyncCall::Pointer opener; ///< Comm opener handler callback. 49 private: 50 AsyncCall::Pointer closer; ///< Comm close handler callback 51 }; 52 53 /// FTP channel for control commands. 54 /// This channel is opened once per transaction. 55 class CtrlChannel: public Ftp::Channel 56 { 57 public: 58 CtrlChannel(); 59 ~CtrlChannel(); 60 61 char *buf; 62 size_t size; 63 size_t offset; 64 wordlist *message; 65 char *last_command; 66 char *last_reply; 67 int replycode; 68 69 private: 70 CtrlChannel(const CtrlChannel &); // not implemented 71 CtrlChannel &operator =(const CtrlChannel &); // not implemented 72 }; 73 74 /// FTP channel for data exchanges. 75 /// This channel may be opened/closed a few times. 76 class DataChannel: public Ftp::Channel 77 { 78 public: 79 DataChannel(); 80 ~DataChannel(); 81 82 void addr(const Ip::Address &addr); ///< import host and port 83 84 public: 85 MemBuf *readBuf; 86 char *host; 87 unsigned short port; 88 bool read_pending; 89 }; 90 91 /// FTP client functionality shared among FTP Gateway and Relay clients. 92 class Client: public ::Client 93 { 94 CBDATA_CLASS(Client); 95 96 public: 97 explicit Client(FwdState *fwdState); 98 virtual ~Client(); 99 100 /// handle a fatal transaction error, closing the control connection 101 virtual void failed(err_type error = ERR_NONE, int xerrno = 0, 102 ErrorState *ftperr = nullptr); 103 104 /// read timeout handler 105 virtual void timeout(const CommTimeoutCbParams &io); 106 107 /* Client API */ 108 virtual void maybeReadVirginBody(); 109 110 void writeCommand(const char *buf); 111 112 /// extracts remoteAddr from PASV response, validates it, 113 /// sets data address details, and returns true on success 114 bool handlePasvReply(Ip::Address &remoteAddr); 115 bool handleEpsvReply(Ip::Address &remoteAddr); 116 117 bool sendEprt(); 118 bool sendPort(); 119 bool sendPassive(); 120 void connectDataChannel(); 121 bool openListenSocket(); 122 void switchTimeoutToDataChannel(); 123 124 CtrlChannel ctrl; ///< FTP control channel state 125 DataChannel data; ///< FTP data channel state 126 127 enum { 128 BEGIN, 129 SENT_USER, 130 SENT_PASS, 131 SENT_TYPE, 132 SENT_MDTM, 133 SENT_SIZE, 134 SENT_EPRT, 135 SENT_PORT, 136 SENT_EPSV_ALL, 137 SENT_EPSV_1, 138 SENT_EPSV_2, 139 SENT_PASV, 140 SENT_CWD, 141 SENT_LIST, 142 SENT_NLST, 143 SENT_REST, 144 SENT_RETR, 145 SENT_STOR, 146 SENT_QUIT, 147 READING_DATA, 148 WRITING_DATA, 149 SENT_MKDIR, 150 SENT_FEAT, 151 SENT_PWD, 152 SENT_CDUP, 153 SENT_DATA_REQUEST, // LIST, NLST or RETR requests.. 154 SENT_COMMAND, // General command 155 END 156 } ftp_state_t; 157 158 int state; 159 char *old_request; 160 char *old_reply; 161 162 protected: 163 /* AsyncJob API */ 164 virtual void start(); 165 166 /* Client API */ 167 virtual void closeServer(); 168 virtual bool doneWithServer() const; 169 virtual const Comm::ConnectionPointer & dataConnection() const; 170 virtual void abortAll(const char *reason); 171 172 virtual Http::StatusCode failedHttpStatus(err_type &error); 173 void ctrlClosed(const CommCloseCbParams &io); 174 void scheduleReadControlReply(int buffered_ok); 175 void readControlReply(const CommIoCbParams &io); 176 virtual void handleControlReply(); 177 void writeCommandCallback(const CommIoCbParams &io); 178 virtual void dataChannelConnected(const CommConnectCbParams &io) = 0; 179 void dataRead(const CommIoCbParams &io); 180 void dataComplete(); 181 AsyncCall::Pointer dataCloser(); 182 virtual void dataClosed(const CommCloseCbParams &io); 183 void initReadBuf(); 184 185 // sending of the request body to the server 186 virtual void sentRequestBody(const CommIoCbParams &io); 187 virtual void doneSendingRequestBody(); 188 189 private: 190 bool parseControlReply(size_t &bytesUsed); 191 192 /// XXX: An old hack for FTP servers like ftp.netscape.com that may not 193 /// respond to PASV. Use faster connect timeout instead of read timeout. 194 bool shortenReadTimeout; 195 }; 196 197 } // namespace Ftp 198 199 #endif /* SQUID_FTP_CLIENT_H */ 200 201