]> git.ipfire.org Git - thirdparty/squid.git/blame - src/clients/FtpClient.h
Simplify appending SBuf to String (#2108)
[thirdparty/squid.git] / src / clients / FtpClient.h
CommitLineData
434a79b0 1/*
1f7b830e 2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
434a79b0 3 *
bbc27441
AJ
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.
434a79b0
DK
7 */
8
bbc27441
AJ
9/* DEBUG: section 09 File Transfer Protocol (FTP) */
10
ff9d9458
FC
11#ifndef SQUID_SRC_CLIENTS_FTPCLIENT_H
12#define SQUID_SRC_CLIENTS_FTPCLIENT_H
434a79b0 13
fccd4a86 14#include "clients/Client.h"
83b053a0 15#include "error/Detail.h"
434a79b0 16
54a6c0cd 17class String;
27c841f6
AR
18namespace Ftp
19{
434a79b0
DK
20
21extern const char *const crlf;
22
83b053a0
CT
23/// Holds FTP server reply error code
24/// Squid needs to interpret internally FTP reply codes and respond with
25/// custom error (eg in the case of Ftp::Gateway), however still we need
26/// to log the exact FTP server error reply code as the reason of error.
27class ErrorDetail: public ::ErrorDetail {
28 MEMPROXY_CLASS(Ftp::ErrorDetail);
29
30public:
31 explicit ErrorDetail(const int code): completionCode(code) {}
32
33 /* ErrorDetail API */
337b9aa4
AR
34 SBuf brief() const override;
35 SBuf verbose(const HttpRequestPointer &) const override;
83b053a0
CT
36
37private:
38 int completionCode; ///< FTP reply completion code
39};
40
e7ce227f
AR
41/// Common code for FTP server control and data channels.
42/// Does not own the channel descriptor, which is managed by Ftp::Client.
5517260a 43class Channel
434a79b0
DK
44{
45public:
46 /// called after the socket is opened, sets up close handler
47 void opened(const Comm::ConnectionPointer &conn, const AsyncCall::Pointer &aCloser);
48
49 /** Handles all operations needed to properly close the active channel FD.
50 * clearing the close handler, clearing the listen socket properly, and calling comm_close
51 */
52 void close();
53
54 void forget(); /// remove the close handler, leave connection open
55
56 void clear(); ///< just drops conn and close handler. does not close active connections.
57
58 Comm::ConnectionPointer conn; ///< channel descriptor
59
60 /** A temporary handle to the connection being listened on.
61 * Closing this will also close the waiting Data channel acceptor.
62 * If a data connection has already been accepted but is still waiting in the event queue
63 * the callback will still happen and needs to be handled (usually dropped).
64 */
65 Comm::ConnectionPointer listenConn;
66
434a79b0
DK
67private:
68 AsyncCall::Pointer closer; ///< Comm close handler callback
69};
70
e7ce227f
AR
71/// FTP channel for control commands.
72/// This channel is opened once per transaction.
73class CtrlChannel: public Ftp::Channel
74{
75public:
76 CtrlChannel();
77 ~CtrlChannel();
78
79 char *buf;
80 size_t size;
81 size_t offset;
82 wordlist *message;
83 char *last_command;
84 char *last_reply;
85 int replycode;
86
87private:
88 CtrlChannel(const CtrlChannel &); // not implemented
89 CtrlChannel &operator =(const CtrlChannel &); // not implemented
90};
91
92/// FTP channel for data exchanges.
93/// This channel may be opened/closed a few times.
94class DataChannel: public Ftp::Channel
95{
96public:
97 DataChannel();
98 ~DataChannel();
99
100 void addr(const Ip::Address &addr); ///< import host and port
101
102public:
103 MemBuf *readBuf;
104 char *host;
105 unsigned short port;
106 bool read_pending;
107};
108
43446566 109/// FTP client functionality shared among FTP Gateway and Relay clients.
fccd4a86 110class Client: public ::Client
434a79b0 111{
7bcdc74b
AR
112 CBDATA_INTERMEDIATE();
113
434a79b0 114public:
5517260a 115 explicit Client(FwdState *fwdState);
337b9aa4 116 ~Client() override;
434a79b0 117
5517260a 118 /// handle a fatal transaction error, closing the control connection
cd4d5d45
VL
119 virtual void failed(err_type error = ERR_NONE, int xerrno = 0,
120 ErrorState *ftperr = nullptr);
5517260a
AR
121
122 /// read timeout handler
434a79b0 123 virtual void timeout(const CommTimeoutCbParams &io);
5517260a 124
fccd4a86 125 /* Client API */
337b9aa4 126 void maybeReadVirginBody() override;
5517260a 127
434a79b0 128 void writeCommand(const char *buf);
73950ceb
AR
129
130 /// extracts remoteAddr from PASV response, validates it,
131 /// sets data address details, and returns true on success
132 bool handlePasvReply(Ip::Address &remoteAddr);
000e664b
AR
133 bool handleEpsvReply(Ip::Address &remoteAddr);
134
135 bool sendEprt();
136 bool sendPort();
137 bool sendPassive();
434a79b0 138 void connectDataChannel();
000e664b 139 bool openListenSocket();
434a79b0
DK
140 void switchTimeoutToDataChannel();
141
e7ce227f
AR
142 CtrlChannel ctrl; ///< FTP control channel state
143 DataChannel data; ///< FTP data channel state
434a79b0 144
000e664b
AR
145 enum {
146 BEGIN,
147 SENT_USER,
148 SENT_PASS,
149 SENT_TYPE,
150 SENT_MDTM,
151 SENT_SIZE,
152 SENT_EPRT,
153 SENT_PORT,
154 SENT_EPSV_ALL,
155 SENT_EPSV_1,
156 SENT_EPSV_2,
157 SENT_PASV,
158 SENT_CWD,
159 SENT_LIST,
160 SENT_NLST,
161 SENT_REST,
162 SENT_RETR,
163 SENT_STOR,
164 SENT_QUIT,
165 READING_DATA,
166 WRITING_DATA,
167 SENT_MKDIR,
168 SENT_FEAT,
54a6c0cd
CT
169 SENT_PWD,
170 SENT_CDUP,
000e664b
AR
171 SENT_DATA_REQUEST, // LIST, NLST or RETR requests..
172 SENT_COMMAND, // General command
173 END
174 } ftp_state_t;
175
434a79b0
DK
176 int state;
177 char *old_request;
178 char *old_reply;
179
180protected:
5517260a 181 /* AsyncJob API */
337b9aa4 182 void start() override;
434a79b0 183
fccd4a86 184 /* Client API */
337b9aa4
AR
185 void closeServer() override;
186 bool doneWithServer() const override;
187 const Comm::ConnectionPointer & dataConnection() const override;
188 void abortAll(const char *reason) override;
189 void noteDelayAwareReadChance() override;
5517260a 190
434a79b0
DK
191 virtual Http::StatusCode failedHttpStatus(err_type &error);
192 void ctrlClosed(const CommCloseCbParams &io);
193 void scheduleReadControlReply(int buffered_ok);
194 void readControlReply(const CommIoCbParams &io);
195 virtual void handleControlReply();
196 void writeCommandCallback(const CommIoCbParams &io);
43446566 197 virtual void dataChannelConnected(const CommConnectCbParams &io) = 0;
434a79b0
DK
198 void dataRead(const CommIoCbParams &io);
199 void dataComplete();
200 AsyncCall::Pointer dataCloser();
201 virtual void dataClosed(const CommCloseCbParams &io);
5517260a 202 void initReadBuf();
434a79b0
DK
203
204 // sending of the request body to the server
337b9aa4
AR
205 void sentRequestBody(const CommIoCbParams &io) override;
206 void doneSendingRequestBody() override;
434a79b0 207
2b6b1bcb
AR
208 /// Waits for an FTP data connection to the server to be established/opened.
209 /// This wait only happens in FTP passive mode (via PASV or EPSV).
210 JobWait<Comm::ConnOpener> dataConnWait;
211
434a79b0 212private:
a2c7f09a 213 bool parseControlReply(size_t &bytesUsed);
434a79b0 214
e7ce227f
AR
215 /// XXX: An old hack for FTP servers like ftp.netscape.com that may not
216 /// respond to PASV. Use faster connect timeout instead of read timeout.
217 bool shortenReadTimeout;
434a79b0
DK
218};
219
92ae4c86 220} // namespace Ftp
434a79b0 221
ff9d9458 222#endif /* SQUID_SRC_CLIENTS_FTPCLIENT_H */
f53969cc 223