]>
| Commit | Line | Data |
|---|---|---|
| 92ae4c86 | 1 | /* |
| 1f7b830e | 2 | * Copyright (C) 1996-2025 The Squid Software Foundation and contributors |
| bbc27441 AJ |
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. | |
| 92ae4c86 AR |
7 | */ |
| 8 | ||
| bbc27441 AJ |
9 | /* DEBUG: section 33 Client-side Routines */ |
| 10 | ||
| ff9d9458 FC |
11 | #ifndef SQUID_SRC_SERVERS_FTPSERVER_H |
| 12 | #define SQUID_SRC_SERVERS_FTPSERVER_H | |
| 92ae4c86 | 13 | |
| 2b6b1bcb | 14 | #include "base/JobWait.h" |
| aea65fec | 15 | #include "base/Lock.h" |
| 8939f9c9 | 16 | #include "client_side.h" |
| 2b6b1bcb | 17 | #include "comm/forward.h" |
| a7b75c64 | 18 | #include "http/forward.h" |
| 92ae4c86 | 19 | |
| 27c841f6 AR |
20 | namespace Ftp |
| 21 | { | |
| 92ae4c86 AR |
22 | |
| 23 | typedef enum { | |
| 24 | fssBegin, | |
| 25 | fssConnected, | |
| 26 | fssHandleFeat, | |
| 27 | fssHandlePasv, | |
| 28 | fssHandlePort, | |
| 29 | fssHandleDataRequest, | |
| 30 | fssHandleUploadRequest, | |
| 31 | fssHandleEprt, | |
| 32 | fssHandleEpsv, | |
| 33 | fssHandleCwd, | |
| 34 | fssHandlePass, | |
| 35 | fssHandleCdup, | |
| 36 | fssError | |
| 37 | } ServerState; | |
| 38 | ||
| 39 | // TODO: This should become a part of MasterXaction when we start sending | |
| 40 | // master transactions to the clients/ code. | |
| 41 | /// Transaction information shared among our FTP client and server jobs. | |
| aea65fec | 42 | class MasterState: public RefCountable |
| 92ae4c86 AR |
43 | { |
| 44 | public: | |
| aea65fec AR |
45 | typedef RefCount<MasterState> Pointer; |
| 46 | ||
| a8d1312d | 47 | MasterState(): serverState(fssBegin), clientReadGreeting(false), userDataDone(0) {} |
| aea65fec | 48 | |
| 92ae4c86 | 49 | Ip::Address clientDataAddr; ///< address of our FTP client data connection |
| 43446566 | 50 | SBuf workingDir; ///< estimated current working directory for URI formation |
| 92ae4c86 AR |
51 | ServerState serverState; ///< what our FTP server is doing |
| 52 | bool clientReadGreeting; ///< whether our FTP client read their FTP server greeting | |
| 92cfc72f CT |
53 | /// Squid will send or has sent this final status code to the FTP client |
| 54 | int userDataDone; | |
| 92ae4c86 AR |
55 | }; |
| 56 | ||
| 57 | /// Manages a control connection from an FTP client. | |
| 58 | class Server: public ConnStateData | |
| 59 | { | |
| d836b06f | 60 | CBDATA_CHILD(Server); |
| 5c2f68b7 | 61 | |
| 92ae4c86 AR |
62 | public: |
| 63 | explicit Server(const MasterXaction::Pointer &xact); | |
| 337b9aa4 | 64 | ~Server() override; |
| d836b06f | 65 | |
| 0d253dfa | 66 | /* AsyncJob API */ |
| 337b9aa4 | 67 | void callException(const std::exception &e) override; |
| 92ae4c86 | 68 | |
| 3238b9b6 CT |
69 | /// Called by Ftp::Client class when it is start receiving or |
| 70 | /// sending data. | |
| 71 | void startWaitingForOrigin(); | |
| 72 | ||
| 92cfc72f CT |
73 | /// Called by Ftp::Client class when it is done receiving or |
| 74 | /// sending data. Waits for both agents to be done before | |
| 75 | /// responding to the FTP client and closing the data connection. | |
| 3238b9b6 | 76 | void stopWaitingForOrigin(int status); |
| 92cfc72f | 77 | |
| aea65fec AR |
78 | // This is a pointer in hope to minimize future changes when MasterState |
| 79 | // becomes a part of MasterXaction. Guaranteed not to be nil. | |
| 80 | MasterState::Pointer master; ///< info shared among our FTP client and server jobs | |
| 92ae4c86 AR |
81 | |
| 82 | protected: | |
| 83 | friend void StartListening(); | |
| 84 | ||
| eacfca83 | 85 | // errors detected before it is possible to create an HTTP request wrapper |
| 3aab028c FC |
86 | enum class EarlyErrorKind { |
| 87 | HugeRequest, | |
| 88 | MissingLogin, | |
| 89 | MissingUsername, | |
| 90 | MissingHost, | |
| 91 | UnsupportedCommand, | |
| 92 | InvalidUri, | |
| 93 | MalformedCommand | |
| 94 | }; | |
| eacfca83 | 95 | |
| 92ae4c86 | 96 | /* ConnStateData API */ |
| 337b9aa4 AR |
97 | Http::Stream *parseOneRequest() override; |
| 98 | void processParsedRequest(Http::StreamPointer &context) override; | |
| 99 | void notePeerConnection(Comm::ConnectionPointer conn) override; | |
| 100 | void clientPinnedConnectionClosed(const CommCloseCbParams &io) override; | |
| 101 | void handleReply(HttpReply *header, StoreIOBuffer receivedData) override; | |
| 102 | int pipelinePrefetchMax() const override; | |
| 103 | bool writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call) override; | |
| 104 | time_t idleTimeout() const override; | |
| 92ae4c86 AR |
105 | |
| 106 | /* BodyPipe API */ | |
| 337b9aa4 AR |
107 | void noteMoreBodySpaceAvailable(BodyPipe::Pointer) override; |
| 108 | void noteBodyConsumerAborted(BodyPipe::Pointer ptr) override; | |
| 92ae4c86 AR |
109 | |
| 110 | /* AsyncJob API */ | |
| 337b9aa4 | 111 | void start() override; |
| 92ae4c86 AR |
112 | |
| 113 | /* Comm callbacks */ | |
| 114 | static void AcceptCtrlConnection(const CommAcceptCbParams ¶ms); | |
| 115 | void acceptDataConnection(const CommAcceptCbParams ¶ms); | |
| 116 | void readUploadData(const CommIoCbParams &io); | |
| 117 | void wroteEarlyReply(const CommIoCbParams &io); | |
| 118 | void wroteReply(const CommIoCbParams &io); | |
| 119 | void wroteReplyData(const CommIoCbParams &io); | |
| 120 | void connectedForData(const CommConnectCbParams ¶ms); | |
| 121 | ||
| 122 | unsigned int listenForDataConnection(); | |
| 123 | bool createDataConnection(Ip::Address cltAddr); | |
| 124 | void closeDataConnection(); | |
| 125 | ||
| 2f8abb64 | 126 | /// Called after data transfer on client-to-squid data connection is |
| 92cfc72f CT |
127 | /// finished. |
| 128 | void userDataCompletionCheckpoint(int finalStatusCode); | |
| 129 | ||
| 130 | /// Writes the data-transfer status reply to the FTP client and | |
| 131 | /// closes the data connection. | |
| 3238b9b6 | 132 | void completeDataDownload(); |
| 92cfc72f | 133 | |
| 1ab04517 | 134 | void calcUri(const SBuf *file); |
| 92ae4c86 | 135 | void changeState(const Ftp::ServerState newState, const char *reason); |
| d3dddfb5 | 136 | Http::Stream *handleUserRequest(const SBuf &cmd, SBuf ¶ms); |
| 92ae4c86 AR |
137 | bool checkDataConnPost() const; |
| 138 | void replyDataWritingCheckpoint(); | |
| 139 | void maybeReadUploadData(); | |
| 140 | ||
| 141 | void setReply(const int code, const char *msg); | |
| aee3523a | 142 | void writeCustomReply(const int code, const char *msg, const HttpReply *reply = nullptr); |
| 92ae4c86 AR |
143 | void writeEarlyReply(const int code, const char *msg); |
| 144 | void writeErrorReply(const HttpReply *reply, const int status); | |
| 145 | void writeForwardedForeign(const HttpReply *reply); | |
| 146 | void writeForwardedReply(const HttpReply *reply); | |
| 147 | void writeForwardedReplyAndCall(const HttpReply *reply, AsyncCall::Pointer &call); | |
| 148 | void writeReply(MemBuf &mb); | |
| 149 | ||
| d3dddfb5 | 150 | Http::Stream *earlyError(const EarlyErrorKind eek); |
| eacfca83 | 151 | bool handleRequest(HttpRequest *); |
| 92ae4c86 AR |
152 | void setDataCommand(); |
| 153 | bool checkDataConnPre(); | |
| 154 | ||
| 155 | /// a method handling an FTP command; selected by handleRequest() | |
| 156 | typedef bool (Ftp::Server::*RequestHandler)(String &cmd, String ¶ms); | |
| 157 | bool handleFeatRequest(String &cmd, String ¶ms); | |
| 158 | bool handlePasvRequest(String &cmd, String ¶ms); | |
| 159 | bool handlePortRequest(String &cmd, String ¶ms); | |
| 160 | bool handleDataRequest(String &cmd, String ¶ms); | |
| 161 | bool handleUploadRequest(String &cmd, String ¶ms); | |
| 162 | bool handleEprtRequest(String &cmd, String ¶ms); | |
| 163 | bool handleEpsvRequest(String &cmd, String ¶ms); | |
| 164 | bool handleCwdRequest(String &cmd, String ¶ms); | |
| 165 | bool handlePassRequest(String &cmd, String ¶ms); | |
| 166 | bool handleCdupRequest(String &cmd, String ¶ms); | |
| 167 | ||
| 168 | /// a method handling an FTP response; selected by handleReply() | |
| 169 | typedef void (Ftp::Server::*ReplyHandler)(const HttpReply *reply, StoreIOBuffer data); | |
| 170 | void handleFeatReply(const HttpReply *header, StoreIOBuffer receivedData); | |
| 171 | void handlePasvReply(const HttpReply *header, StoreIOBuffer receivedData); | |
| 172 | void handlePortReply(const HttpReply *header, StoreIOBuffer receivedData); | |
| 173 | void handleErrorReply(const HttpReply *header, StoreIOBuffer receivedData); | |
| 174 | void handleDataReply(const HttpReply *header, StoreIOBuffer receivedData); | |
| 175 | void handleUploadReply(const HttpReply *header, StoreIOBuffer receivedData); | |
| 176 | void handleEprtReply(const HttpReply *header, StoreIOBuffer receivedData); | |
| 177 | void handleEpsvReply(const HttpReply *header, StoreIOBuffer receivedData); | |
| 178 | ||
| 179 | private: | |
| 180 | void doProcessRequest(); | |
| 181 | void shovelUploadData(); | |
| e7ce227f | 182 | void resetLogin(const char *reason); |
| 92ae4c86 | 183 | |
| 1ab04517 AR |
184 | SBuf uri; ///< a URI reconstructed from various FTP message details |
| 185 | SBuf host; ///< intended dest. of a transparently intercepted FTP conn | |
| 92ae4c86 AR |
186 | bool gotEpsvAll; ///< restrict data conn setup commands to just EPSV |
| 187 | AsyncCall::Pointer onDataAcceptCall; ///< who to call upon data conn acceptance | |
| 188 | Comm::ConnectionPointer dataListenConn; ///< data connection listening socket | |
| 189 | Comm::ConnectionPointer dataConn; ///< data connection | |
| 190 | char uploadBuf[CLIENT_REQ_BUF_SZ]; ///< data connection input buffer | |
| 191 | size_t uploadAvailSize; ///< number of yet unused uploadBuf bytes | |
| 192 | ||
| 193 | AsyncCall::Pointer listener; ///< set when we are passively listening | |
| 2b6b1bcb AR |
194 | |
| 195 | /// Waits for an FTP data connection to the client to be established/opened. | |
| 196 | /// This wait only happens in FTP active mode (via PORT or EPRT). | |
| 197 | JobWait<Comm::ConnOpener> dataConnWait; | |
| 198 | ||
| 92ae4c86 | 199 | AsyncCall::Pointer reader; ///< set when we are reading FTP data |
| 3238b9b6 CT |
200 | |
| 201 | /// whether we wait for the origin data transfer to end | |
| 202 | bool waitingForOrigin; | |
| 203 | /// whether the origin data transfer aborted | |
| 204 | bool originDataDownloadAbortedOnError; | |
| a8d1312d | 205 | |
| 3238b9b6 CT |
206 | /// a response which writing was postponed until stopWaitingForOrigin() |
| 207 | HttpReply::Pointer delayedReply; | |
| 92ae4c86 AR |
208 | }; |
| 209 | ||
| 210 | } // namespace Ftp | |
| 211 | ||
| ff9d9458 | 212 | #endif /* SQUID_SRC_SERVERS_FTPSERVER_H */ |
| f53969cc | 213 |