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(©_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