1 /*
2  * lftp - file transfer program
3  *
4  * Copyright (c) 1996-2016 by Alexander V. Lukyanov (lav@yars.free.net)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef FTPCLASS_H
21 #define FTPCLASS_H
22 
23 #include "trio.h"
24 #include <time.h>
25 
26 #include "NetAccess.h"
27 
28 #if USE_SSL
29 # include "lftp_ssl.h"
30 #endif
31 
32 class TelnetEncode : public DataTranslator {
33    void PutTranslated(Buffer *target,const char *buf,int size);
34 };
35 class TelnetDecode : public DataTranslator {
36    void PutTranslated(Buffer *target,const char *buf,int size);
37 };
38 class IOBufferTelnet : public IOBufferStacked
39 {
40 public:
IOBufferTelnet(IOBuffer * b)41    IOBufferTelnet(IOBuffer *b) : IOBufferStacked(b) {
42       if(mode==PUT)
43 	 SetTranslator(new TelnetEncode());
44       else
45 	 SetTranslator(new TelnetDecode());
46    }
47 };
48 
49 class Ftp : public NetAccess
50 {
51    enum automate_state
52    {
53       EOF_STATE,	   // control connection is open, idle state
54       INITIAL_STATE,	   // all connections are closed
55       CONNECTING_STATE,	   // we are connecting the control socket
56       HTTP_PROXY_CONNECTED,// connected to http proxy, but have no reply yet
57       CONNECTED_STATE,	   // just after connect
58       WAITING_STATE,	   // we're waiting for a response with data
59       ACCEPTING_STATE,	   // we're waiting for an incoming data connection
60       DATA_OPEN_STATE,	   // data connection is open, for read or write
61       CWD_CWD_WAITING_STATE,  // waiting until 'CWD $cwd' finishes
62       USER_RESP_WAITING_STATE,// waiting until 'USER $user' finishes
63       DATASOCKET_CONNECTING_STATE, // waiting for data_sock to connect
64       WAITING_150_STATE,   // waiting for 150 message
65       WAITING_CCC_SHUTDOWN // waiting for the server to shutdown SSL connection
66    };
67 
68    class Connection
69    {
70       xstring_c closure;
71    public:
72       int control_sock;
73       SMTaskRef<IOBuffer> control_recv;
74       SMTaskRef<IOBuffer> control_send;
75       IOBufferTelnet *telnet_layer_send;
76       DirectedBuffer send_cmd_buffer; // holds unsent commands.
77       int data_sock;
78       SMTaskRef<IOBuffer> data_iobuf;
79       int aborted_data_sock;
80       sockaddr_u peer_sa;
81       sockaddr_u data_sa; // address for data accepting
82       bool quit_sent;
83       bool fixed_pasv;	  // had to fix PASV address.
84       bool translation_activated;
85       bool proxy_is_http; // true when connection was established via http proxy.
86       bool may_show_password;
87       bool can_do_pasv;
88 
89       int multiline_code; // the code of multiline response.
90       int sync_wait;	  // number of commands in flight.
91       bool ignore_pass;	  // logged in just with user
92       bool try_feat_after_login;
93       bool tune_after_login;
94       bool utf8_activated; // server is switched to UTF8 mode.
95       bool received_150;
96 
97       char type;  // type of transfer: 'A'scii or 'I'mage
98       char t_mode; // transfer mode: 'S'tream, 'Z'ipped
99 
100       bool dos_path;
101       bool vms_path;
102 
103       bool have_feat_info;
104       bool mdtm_supported;
105       bool size_supported;
106       bool rest_supported;
107       bool site_chmod_supported;
108       bool site_utime_supported;
109       bool site_utime2_supported;   // two-argument SITE UTIME
110       bool site_symlink_supported;
111       bool site_mkdir_supported;
112       bool pret_supported;
113       bool utf8_supported;
114       bool lang_supported;
115       bool mlst_supported;
116       bool clnt_supported;
117       bool host_supported;
118       bool mfmt_supported;
119       bool mff_supported;
120       bool epsv_supported;
121       bool tvfs_supported;
122       bool mode_z_supported;
123       bool cepr_supported;
124 
125       bool ssl_after_proxy;
126 
127       off_t last_rest;	// last successful REST position.
128       off_t rest_pos;	// the number sent with REST command.
129 
130       Timer abor_close_timer;	 // timer for closing aborted connection.
131       Timer stat_timer;		 // timer for sending periodic STAT commands.
132       Timer waiting_150_timer;   // limit time to wait for 150 reply.
133       Timer waiting_ssl_timer;	 // limit time to wait for ssl shutdown
134 
135       time_t nop_time;
136       off_t  nop_offset;
137       int    nop_count;
138 
139 #if USE_SSL
140       Ref<lftp_ssl> control_ssl;
141       char prot;  // current data protection scheme 'C'lear or 'P'rivate
142       bool auth_sent;
143       bool auth_supported;
144       bool cpsv_supported;
145       bool sscn_supported;
146       bool sscn_on;
147       xstring auth_args_supported;
ssl_is_activated()148       bool ssl_is_activated() { return control_ssl!=0; }
149       Timer waiting_ssl_shutdown;
150 #else
ssl_is_activated()151       bool ssl_is_activated() { return false; }
152 #endif
153 
154       xstring_c mlst_attr_supported;
155       xstring_c mode_z_opts_supported;
156 
157       Connection(const char *c);
158       ~Connection();
159 
160       bool data_address_ok(const sockaddr_u *d,bool verify_address,bool verify_port);
161 
162       void MakeBuffers();
163       void MakeSSLBuffers(const char *h);
164       void InitTelnetLayer();
165       void SetControlConnectionTranslation(const char *cs);
166 
167       void CloseDataSocket(); // only closes socket, does not delete iobuf.
168       void CloseDataConnection();
169       void AbortDataConnection();
170       void CloseAbortedDataConnection();
171 
172       void Send(const char *cmd);
173       void SendURI(const char *u,const char *home);
174       void SendCRNL();
175       void SendEncoded(const char *url);
176       void SendCmd(const char *cmd);
177       void SendCmd2(const char *cmd,const char *f,const char *u=0,const char *home=0);
178       void SendCmd2(const char *cmd,int v);
179       void SendCmdF(const char *fmt,...) PRINTF_LIKE(2,3);
180       int FlushSendQueueOneCmd(); // sends single command from send_cmd_buffer
181 
182       void AddDataTranslator(DataTranslator *t);
183       void AddDataTranslation(const char *charset,bool translit);
184 
SuspendInternal()185       void SuspendInternal()
186       {
187 	 if(control_send) control_send->SuspendSlave();
188 	 if(control_recv && !data_iobuf) control_recv->SuspendSlave();
189 	 if(data_iobuf)	data_iobuf->SuspendSlave();
190       }
ResumeInternal()191       void ResumeInternal()
192       {
193 	 if(control_send) control_send->ResumeSlave();
194 	 if(control_recv) control_recv->ResumeSlave();
195 	 if(data_iobuf)	data_iobuf->ResumeSlave();
196       }
197 
198       void CheckFEAT(char *reply,const char *line,bool trust);
199    };
200 
201    Ref<Connection> conn;
202    bool last_connection_failed;
203 
204    struct Expect
205    {
206       enum expect_t
207       {
208 	 NONE,		// no special check, reconnect if reply>=400.
209 	 IGNORE,	// ignore response
210 	 READY,		// check response after connect
211 	 REST,		// check response for REST
212 	 TYPE,		// check response for TYPE
213 	 MODE,
214 	 CWD,		// check response for CWD
215 	 CWD_CURR,	// check response for CWD into current directory
216 	 CWD_STALE,	// check response for CWD when it's not critical
217 	 ABOR,		// check response for ABOR
218 	 SIZE,		// check response for SIZE
219 	 SIZE_OPT,	// check response for SIZE and save size to *opt_size
220 	 MDTM,		// check response for MDTM
221 	 MDTM_OPT,	// check response for MDTM and save size to *opt_date
222 	 PRET,
223 	 PASV,		// check response for PASV and save address
224 	 EPSV,		// check response for EPSV and save address
225 	 PORT,		// check response for PORT or EPRT
226 	 FILE_ACCESS,	// generic check for file access
227 	 PWD,		// check response for PWD and save it to home
228 	 RNFR,
229 	 USER,		// check response for USER
230 	 USER_PROXY,	// check response for USER sent to proxy
231 	 PASS,		// check response for PASS
232 	 PASS_PROXY,	// check response for PASS sent to proxy
233 	 OPEN_PROXY,	// special UserGate proxy command
234 	 ACCT_PROXY,	// special ACCT with proxy password
235 	 TRANSFER,	// generic check for transfer
236 	 TRANSFER_CLOSED, // check for transfer complete when Close()d.
237 	 FEAT,
238 	 OPTS_UTF8,
239 	 LANG,
240 	 SITE_UTIME,
241 	 SITE_UTIME2,
242 	 ALLO,
243 	 QUOTED		// check response for any command submitted by QUOTE_CMD
244 #if USE_SSL
245 	 ,AUTH_TLS,PROT,SSCN,CCC
246 #endif
247       };
248 
249       expect_t check_case;
250       xstring_c cmd;
251       xstring_c arg;
252       Expect *next;
253 
check_caseExpect254       Expect(expect_t e,const char *a=0,const char *c=0) : check_case(e), cmd(c), arg(a) {}
ExpectExpect255       Expect(expect_t e,char c) : check_case(e)
256 	 {
257 	    char cc[2]={c,0};
258 	    arg.set(cc);
259 	 }
260    };
261    class ExpectQueue;
262    friend class Ftp::ExpectQueue; // grant access to Expect
263    class ExpectQueue
264    {
265       Expect *first; // next to expect
266       Expect **last;  // for appending
267       int count;
268 
269    public:
270       ExpectQueue();
271       ~ExpectQueue();
272 
273       void Push(Expect *e);
274       void Push(Expect::expect_t e);
275       Expect *Pop();
276       Expect *FindLastCWD() const;
Count()277       int Count() const { return count; }
IsEmpty()278       bool IsEmpty() const { return count==0; }
279       bool Has(Expect::expect_t) const;
280       bool FirstIs(Expect::expect_t) const;
281       void Close();
282    };
283 
284    Ref<ExpectQueue> expect;
285 
286    void  CheckResp(int resp);
287    int	 ReplyLogPriority(int code) const;
288 
289    void	 RestCheck(int);
290    void  NoFileCheck(int);
291    void	 TransferCheck(int);
292    bool	 Retry530() const;
293    void	 LoginCheck(int);
294    void	 NoPassReqCheck(int);
295    void	 proxy_LoginCheck(int);
296    void	 proxy_NoPassReqCheck(int);
297    char *ExtractPWD();
298    int   SendCWD(const char *path,const char *path_url,Expect::expect_t c);
299    void	 CatchDATE(int);
300    void	 CatchDATE_opt(int);
301    void	 CatchSIZE(int);
302    void	 CatchSIZE_opt(int);
303    void	 TurnOffStatForList();
304 
305    enum pasv_state_t
306    {
307       PASV_NO_ADDRESS_YET,
308       PASV_HAVE_ADDRESS,
309       PASV_DATASOCKET_CONNECTING,
310       PASV_HTTP_PROXY_CONNECTED
311    };
312    pasv_state_t pasv_state;	// state of PASV, when state==DATASOCKET_CONNECTING_STATE
313 
314    pasv_state_t Handle_PASV();
315    pasv_state_t Handle_EPSV();
316    pasv_state_t Handle_EPSV_CEPR();
317 
318    bool ServerSaid(const char *) const;
319    bool NonError5XX(int act) const;
320    bool Transient5XX(int act) const;
321 
322    void	 InitFtp();
323 
324    void	 HandleTimeout();
325 
326 #if USE_SSL
327 protected:
328    bool	 ftps;	  // ssl and prot='P' by default (port 990)
329 private:
330 #else
331    static const bool ftps; // for convenience
332 #endif
333 
334    void	DataAbort();
335    void DataClose();
336    void ControlClose();
337 
338    void SendUrgentCmd(const char *cmd);
339    int	FlushSendQueueOneCmd();
340    int	FlushSendQueue(bool all=false);
341    void	SendArrayInfoRequests();
342    void	SendSiteIdle();
343    void	SendAcct();
344    void	SendSiteGroup();
345    void	SendSiteCommands();
346    void	SendUTimeRequest();
347    void SendAuth(const char *auth);
348    void TuneConnectionAfterFEAT();
349    void SendOPTS_MLST();
350    void SendPROT(char want_prot);
351 
352    const char *QueryStringWithUserAtHost(const char *);
353 
354    int	 ReceiveOneLine();
355    // If a response is received, it checks it for accordance with
356    // response_queue and switch to a state if necessary
357    int	 ReceiveResp();
358 
359    bool ProxyIsHttp();
360    int	 http_proxy_status_code;
361    // Send CONNECT method to http proxy.
362    void	 HttpProxySendConnect();
363    void	 HttpProxySendConnectData();
364    // Send http proxy auth.
365    void	 HttpProxySendAuth(const SMTaskRef<IOBuffer>&);
366    // Check if proxy returned a reply, returns true if reply is ok.
367    // May disconnect.
368    bool	 HttpProxyReplyCheck(const SMTaskRef<IOBuffer>&);
369 
370    bool	 AbsolutePath(const char *p) const;
371 
372    void MoveConnectionHere(Ftp *o);
373    bool GetBetterConnection(int level,bool limit_reached);
374    bool SameConnection(const Ftp *o) const;
375 
376    // state
377    automate_state state;
378    int flags;
379    bool eof;
380    Timer retry_timer;
381 
382    xstring line;	// last line of last server reply
383    xstring all_lines;   // all lines of last server reply
384 
385    void	 SetError(int code,const char *mess=0);
386 
387    // settings
388    xstring_c anon_user;
389    xstring_c anon_pass;
390    xstring_c charset;
391    xstring_c list_options;
392    int nop_interval;
393    bool verify_data_address;
394    bool verify_data_port;
395    bool	rest_list;
396 
397    xstring_c skey_pass;
398    bool allow_skey;
399    bool force_skey;
400    const char *make_skey_reply();
401 
402    xstring netkey_pass;
403    bool allow_netkey;
404    const char *make_netkey_reply();
405 
406    bool disconnect_on_close;
407 
408 public:
409    enum copy_mode_t { COPY_NONE, COPY_SOURCE, COPY_DEST };
410 private:
411    copy_mode_t copy_mode;
412    sockaddr_u copy_addr;
413    bool copy_addr_valid;
414    bool copy_passive;
415    bool copy_protect;
416    bool copy_ssl_connect;
417    bool	copy_done;
418    bool	copy_connection_open;
419    bool copy_allow_store;
420    bool copy_failed;
421 
422    bool use_stat;
423    bool use_stat_for_list;
424    bool use_mdtm;
425    bool use_size;
426    bool use_feat;
427    bool use_mlsd;
428 
429    bool use_telnet_iac;
430 
431    int max_buf;
432 
433    const char *get_protect_res();
434    const char *encode_eprt(const sockaddr_u *);
435 
436    typedef FileInfo *(*FtpLineParser)(char *line,int *err,const char *tz);
437    static FtpLineParser line_parsers[];
438 
439    int CanRead();
440 
441    const char *path_to_send();
442 
443 protected:
444    void PrepareToDie();
445 
446 public:
447    static void ClassInit();
448 
449    Ftp();
450    Ftp(const Ftp *);
451 
GetProto()452    const char *GetProto() const { return "ftp"; }
453 
Clone()454    FileAccess *Clone() const { return new Ftp(this); }
455    static FileAccess *New();
456 
457    const char *ProtocolSubstitution(const char *host);
458 
459    bool	 SameLocationAs(const FileAccess *) const;
460    bool	 SameSiteAs(const FileAccess *) const;
461 
462    void	 ResetLocationData();
463 
464    enum ConnectLevel
465    {
466       CL_NOT_CONNECTED,
467       CL_CONNECTING,
468       CL_JUST_CONNECTED,
469       CL_NOT_LOGGED_IN,
470       CL_LOGGED_IN,
471       CL_JUST_BEFORE_DISCONNECT
472    };
473    ConnectLevel GetConnectLevel() const;
IsConnected()474    int IsConnected() const
475    {
476       return GetConnectLevel()!=CL_NOT_CONNECTED;
477    }
478 
479    int   Read(Buffer *buf,int size);
480    int   Write(const void *buf,int size);
481    int   Buffered();
482    void  Close();
483    bool	 IOReady();
484 
485 	 // When you are putting a file, call SendEOT to terminate
486 	 // transfer and then call StoreStatus until OK or error.
487    int	 SendEOT();
488    int	 StoreStatus();
489 
490    int	 Do();
491    void  DisconnectLL();
492    void  DisconnectNow();
493 
494    void	 SetFlag(int flag,bool val);
GetFlag(int flag)495    int	 GetFlag(int flag) const { return flags&flag; }
496 
497    static time_t ConvertFtpDate(const char *);
498 
499    const char *CurrentStatus();
500 
501    int	 Done();
502 
503    enum flag_mask
504    {
505       SYNC_MODE=1,
506       NOREST_MODE=4,
507       IO_FLAG=8,
508       PASSIVE_MODE=32,
509 
510       MODES_MASK=SYNC_MODE|PASSIVE_MODE
511    };
512 
513    void Reconfig(const char *name=0);
514 
515    ListInfo *MakeListInfo(const char *path);
516    Glob *MakeGlob(const char *pattern);
517    DirList *MakeDirList(ArgV *args);
518    FileSet *ParseLongList(const char *buf,int len,int *err=0) const;
519 
SetCopyMode(copy_mode_t cm,bool rp,bool prot,bool sscn,int rnum,time_t tt)520    void SetCopyMode(copy_mode_t cm,bool rp,bool prot,bool sscn,int rnum,time_t tt)
521       {
522 	 copy_mode=cm;
523 	 copy_passive=rp;
524 	 copy_protect=prot;
525 	 copy_ssl_connect=sscn;
526 	 retries=rnum;
527 	 SetTryTime(tt);
528       }
SetCopyAddress(const Ftp * o)529    bool SetCopyAddress(const Ftp *o)
530       {
531 	 if(copy_addr_valid || !o->copy_addr_valid)
532 	    return false;
533 	 memcpy(&copy_addr,&o->copy_addr,sizeof(copy_addr));
534 	 copy_addr_valid=true;
535 	 return true;
536       }
CopyFailed()537    bool CopyFailed() const { return copy_failed; }
RestartFailed()538    bool RestartFailed() const { return flags&NOREST_MODE; }
IsPassive()539    bool IsPassive() const { return flags&PASSIVE_MODE; }
IsCopyPassive()540    bool IsCopyPassive() const { return copy_passive; }
CopyAllowStore()541    void CopyAllowStore()
542       {
543 	 conn->SendCmd2("STOR",file);
544 	 expect->Push(new Expect(Expect::TRANSFER));
545 	 copy_allow_store=true;
546       }
CopyStoreAllowed()547    bool CopyStoreAllowed() const { return copy_allow_store; }
CopyIsReadyForStore()548    bool CopyIsReadyForStore()
549       {
550 	 if(!expect)
551 	    return false;
552 	 if(copy_mode==COPY_SOURCE)
553 	    return copy_addr_valid && expect->FirstIs(Expect::TRANSFER);
554 	 return state==WAITING_STATE && expect->IsEmpty();
555       }
CopyCheckTimeout(const Ftp * o)556    void CopyCheckTimeout(const Ftp *o)
557       {
558 	 timeout_timer.Reset(o->timeout_timer);
559 	 CheckTimeout();
560       }
561    bool AnonymousQuietMode();
562 
563    void SuspendInternal();
564    void ResumeInternal();
565 };
566 
567 class FtpS : public Ftp
568 {
569 public:
570    FtpS();
571    FtpS(const FtpS *);
572    ~FtpS();
573 
GetProto()574    const char *GetProto() const { return "ftps"; }
575 
Clone()576    FileAccess *Clone() const { return new FtpS(this); }
577    static FileAccess *New();
578 };
579 
580 #endif /* FTPCLASS_H */
581