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