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