⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 postlogin.c

📁 文件传输协议linux 下vsftpd2.1.0.tar.gz
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (p_raw == 0)  {    vsf_cmdio_write(p_sess, FTP_BADCMD, "Illegal PORT command.");    return;  }  the_port = vals[4] << 8;  the_port |= vals[5];  vsf_sysutil_sockaddr_clone(&p_sess->p_port_sockaddr, p_sess->p_local_addr);  vsf_sysutil_sockaddr_set_ipv4addr(p_sess->p_port_sockaddr, vals);  vsf_sysutil_sockaddr_set_port(p_sess->p_port_sockaddr, the_port);  /* SECURITY:   * 1) Reject requests not connecting to the control socket IP   * 2) Reject connects to privileged ports   */  if (!tunable_port_promiscuous)  {    if (!vsf_sysutil_sockaddr_addr_equal(p_sess->p_remote_addr,                                         p_sess->p_port_sockaddr) ||        vsf_sysutil_is_port_reserved(the_port))    {      vsf_cmdio_write(p_sess, FTP_BADCMD, "Illegal PORT command.");      port_cleanup(p_sess);      return;    }  }  vsf_cmdio_write(p_sess, FTP_PORTOK,                  "PORT command successful. Consider using PASV.");}static voidhandle_stor(struct vsf_session* p_sess){  handle_upload_common(p_sess, 0, 0);}static voidhandle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique){  static struct vsf_sysutil_statbuf* s_p_statbuf;  static struct mystr s_filename;  struct mystr* p_filename;  struct vsf_transfer_ret trans_ret;  int new_file_fd;  int remote_fd;  int success = 0;  int created = 0;  int do_truncate = 0;  filesize_t offset = p_sess->restart_pos;  p_sess->restart_pos = 0;  if (!data_transfer_checks_ok(p_sess))  {    return;  }  resolve_tilde(&p_sess->ftp_arg_str, p_sess);  p_filename = &p_sess->ftp_arg_str;  if (is_unique)  {    get_unique_filename(&s_filename, p_filename);    p_filename = &s_filename;  }  vsf_log_start_entry(p_sess, kVSFLogEntryUpload);  str_copy(&p_sess->log_str, &p_sess->ftp_arg_str);  prepend_path_to_filename(&p_sess->log_str);  if (!vsf_access_check_file(p_filename))  {    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");    return;  }  /* NOTE - actual file permissions will be governed by the tunable umask */  /* XXX - do we care about race between create and chown() of anonymous   * upload?   */  if (is_unique || (p_sess->is_anonymous && !tunable_anon_other_write_enable))  {    new_file_fd = str_create(p_filename);  }  else  {    /* For non-anonymous, allow open() to overwrite or append existing files */    new_file_fd = str_create_append(p_filename);    if (!is_append && offset == 0)    {      do_truncate = 1;    }  }  if (vsf_sysutil_retval_is_error(new_file_fd))  {    vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, "Could not create file.");    return;  }  created = 1;  vsf_sysutil_fstat(new_file_fd, &s_p_statbuf);  if (vsf_sysutil_statbuf_is_regfile(s_p_statbuf))  {    /* Now deactive O_NONBLOCK, otherwise we have a problem on DMAPI filesystems     * such as XFS DMAPI.     */    vsf_sysutil_deactivate_noblock(new_file_fd);  }  /* Are we required to chown() this file for security? */  if (p_sess->is_anonymous && tunable_chown_uploads)  {    vsf_sysutil_fchmod(new_file_fd, tunable_chown_upload_mode);    if (tunable_one_process_model)    {      vsf_one_process_chown_upload(p_sess, new_file_fd);    }    else    {      vsf_two_process_chown_upload(p_sess, new_file_fd);    }  }  /* Are we required to lock this file? */  if (tunable_lock_upload_files)  {    vsf_sysutil_lock_file_write(new_file_fd);  }  /* Must truncate the file AFTER locking it! */  if (do_truncate)  {    vsf_sysutil_ftruncate(new_file_fd);    vsf_sysutil_lseek_to(new_file_fd, 0);  }  if (!is_append && offset != 0)  {    /* XXX - warning, allows seek past end of file! Check for seek > size? */    /* XXX - also, currently broken as the O_APPEND flag will always write     * at the end of file. No known complaints yet; can easily fix if one     * comes in.     */    vsf_sysutil_lseek_to(new_file_fd, offset);  }  if (is_unique)  {    struct mystr resp_str = INIT_MYSTR;    str_alloc_text(&resp_str, "FILE: ");    str_append_str(&resp_str, p_filename);    remote_fd = get_remote_transfer_fd(p_sess, str_getbuf(&resp_str));    str_free(&resp_str);  }  else  {    remote_fd = get_remote_transfer_fd(p_sess, "Ok to send data.");  }  if (vsf_sysutil_retval_is_error(remote_fd))  {    goto port_pasv_cleanup_out;  }  if (tunable_ascii_upload_enable && p_sess->is_ascii)  {    trans_ret = vsf_ftpdataio_transfer_file(p_sess, remote_fd,                                            new_file_fd, 1, 1);  }  else  {    trans_ret = vsf_ftpdataio_transfer_file(p_sess, remote_fd,                                            new_file_fd, 1, 0);  }  if (vsf_ftpdataio_dispose_transfer_fd(p_sess) != 1 && trans_ret.retval == 0)  {    trans_ret.retval = -2;  }  p_sess->transfer_size = trans_ret.transferred;  if (trans_ret.retval == 0)  {    success = 1;    vsf_log_do_log(p_sess, 1);  }  if (trans_ret.retval == -1)  {    vsf_cmdio_write(p_sess, FTP_BADSENDFILE, "Failure writing to local file.");  }  else if (trans_ret.retval == -2 || p_sess->abor_received)  {    vsf_cmdio_write(p_sess, FTP_BADSENDNET, "Failure reading network stream.");  }  else  {    vsf_cmdio_write(p_sess, FTP_TRANSFEROK, "File receive OK.");  }  check_abor(p_sess);port_pasv_cleanup_out:  port_cleanup(p_sess);  pasv_cleanup(p_sess);  if (tunable_delete_failed_uploads && created && !success)  {    str_unlink(p_filename);  }  vsf_sysutil_close(new_file_fd);}static voidhandle_mkd(struct vsf_session* p_sess){  int retval;  resolve_tilde(&p_sess->ftp_arg_str, p_sess);  vsf_log_start_entry(p_sess, kVSFLogEntryMkdir);  str_copy(&p_sess->log_str, &p_sess->ftp_arg_str);  prepend_path_to_filename(&p_sess->log_str);  if (!vsf_access_check_file(&p_sess->ftp_arg_str))  {    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");    return;  }  /* NOTE! Actual permissions will be governed by the tunable umask */  retval = str_mkdir(&p_sess->ftp_arg_str, 0777);  if (retval != 0)  {    vsf_cmdio_write(p_sess, FTP_FILEFAIL,                    "Create directory operation failed.");    return;  }  vsf_log_do_log(p_sess, 1);  {    static struct mystr s_mkd_res;    static struct mystr s_tmp_str;    str_copy(&s_tmp_str, &p_sess->ftp_arg_str);    prepend_path_to_filename(&s_tmp_str);    /* Double up double quotes */    str_replace_text(&s_tmp_str, "\"", "\"\"");    /* Build result string */    str_alloc_text(&s_mkd_res, "\"");    str_append_str(&s_mkd_res, &s_tmp_str);    str_append_text(&s_mkd_res, "\" created");    vsf_cmdio_write_str(p_sess, FTP_MKDIROK, &s_mkd_res);  }}static voidhandle_rmd(struct vsf_session* p_sess){  int retval;  resolve_tilde(&p_sess->ftp_arg_str, p_sess);  vsf_log_start_entry(p_sess, kVSFLogEntryRmdir);  str_copy(&p_sess->log_str, &p_sess->ftp_arg_str);  prepend_path_to_filename(&p_sess->log_str);  if (!vsf_access_check_file(&p_sess->ftp_arg_str))  {    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");    return;  }  retval = str_rmdir(&p_sess->ftp_arg_str);  if (retval != 0)  {    vsf_cmdio_write(p_sess, FTP_FILEFAIL,                    "Remove directory operation failed.");  }  else  {    vsf_log_do_log(p_sess, 1);    vsf_cmdio_write(p_sess, FTP_RMDIROK,                    "Remove directory operation successful.");  }}static voidhandle_dele(struct vsf_session* p_sess){  int retval;  resolve_tilde(&p_sess->ftp_arg_str, p_sess);  vsf_log_start_entry(p_sess, kVSFLogEntryDelete);  str_copy(&p_sess->log_str, &p_sess->ftp_arg_str);  prepend_path_to_filename(&p_sess->log_str);  if (!vsf_access_check_file(&p_sess->ftp_arg_str))  {    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");    return;  }  retval = str_unlink(&p_sess->ftp_arg_str);  if (retval != 0)  {    vsf_cmdio_write(p_sess, FTP_FILEFAIL, "Delete operation failed.");  }  else  {    vsf_log_do_log(p_sess, 1);    vsf_cmdio_write(p_sess, FTP_DELEOK, "Delete operation successful.");  }}static voidhandle_rest(struct vsf_session* p_sess){  static struct mystr s_rest_str;  filesize_t val = str_a_to_filesize_t(&p_sess->ftp_arg_str);  if (val < 0)  {    val = 0;  }  p_sess->restart_pos = val;  str_alloc_text(&s_rest_str, "Restart position accepted (");  str_append_filesize_t(&s_rest_str, val);  str_append_text(&s_rest_str, ").");  vsf_cmdio_write_str(p_sess, FTP_RESTOK, &s_rest_str);}static voidhandle_rnfr(struct vsf_session* p_sess){  static struct vsf_sysutil_statbuf* p_statbuf;  int retval;  /* Clear old value */  str_free(&p_sess->rnfr_filename_str);  resolve_tilde(&p_sess->ftp_arg_str, p_sess);  if (!vsf_access_check_file(&p_sess->ftp_arg_str))  {    vsf_log_start_entry(p_sess, kVSFLogEntryRename);    str_copy(&p_sess->log_str, &p_sess->ftp_arg_str);    prepend_path_to_filename(&p_sess->log_str);    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");    return;  }  /* Does it exist? */  retval = str_stat(&p_sess->ftp_arg_str, &p_statbuf);  if (retval == 0)  {    /* Yes */    str_copy(&p_sess->rnfr_filename_str, &p_sess->ftp_arg_str);    vsf_cmdio_write(p_sess, FTP_RNFROK, "Ready for RNTO.");  }  else  {    vsf_log_start_entry(p_sess, kVSFLogEntryRename);    str_copy(&p_sess->log_str, &p_sess->ftp_arg_str);    prepend_path_to_filename(&p_sess->log_str);    vsf_cmdio_write(p_sess, FTP_FILEFAIL, "RNFR command failed.");  }}static voidhandle_rnto(struct vsf_session* p_sess){  static struct mystr s_tmp_str;  int retval;  /* If we didn't get a RNFR, throw a wobbly */  if (str_isempty(&p_sess->rnfr_filename_str))  {    vsf_cmdio_write(p_sess, FTP_NEEDRNFR,                    "RNFR required first.");    return;  }  resolve_tilde(&p_sess->ftp_arg_str, p_sess);  vsf_log_start_entry(p_sess, kVSFLogEntryRename);  str_copy(&p_sess->log_str, &p_sess->rnfr_filename_str);  prepend_path_to_filename(&p_sess->log_str);  str_append_char(&p_sess->log_str, ' ');  str_copy(&s_tmp_str, &p_sess->ftp_arg_str);  prepend_path_to_filename(&s_tmp_str);  str_append_str(&p_sess->log_str, &s_tmp_str);  if (!vsf_access_check_file(&p_sess->ftp_arg_str))  {    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");    return;  }  /* NOTE - might overwrite destination file. Not a concern because the same   * could be accomplished with DELE.   */  retval = str_rename(&p_sess->rnfr_filename_str, &p_sess->ftp_arg_str);  /* Clear the RNFR filename; start the two stage process again! */  str_free(&p_sess->rnfr_filename_str);  if (retval == 0)  {    vsf_log_do_log(p_sess, 1);    vsf_cmdio_write(p_sess, FTP_RENAMEOK, "Rename successful.");  }  else  {    vsf_cmdio_write(p_sess, FTP_FILEFAIL, "Rename failed.");  }}static voidhandle_nlst(struct vsf_session* p_sess){  handle_dir_common(p_sess, 0, 0);}static voidprepend_path_to_filename(struct mystr* p_str){  static struct mystr s_tmp_str;  /* Only prepend current working directory if the incoming filename is   * relative   */  str_empty(&s_tmp_str);  if (str_isempty(p_str) || str_get_char_at(p_str, 0) != '/')  {    str_getcwd(&s_tmp_str);    /* Careful to not emit // if we are in directory / (common with chroot) */    if (str_isempty(&s_tmp_str) ||        str_get_char_at(&s_tmp_str, str_getlen(&s_tmp_str) - 1) != '/')    {      str_append_char(&s_tmp_str, '/');    }  }  str_append_str(&s_tmp_str, p_str);  str_copy(p_str, &s_tmp_str);}static voidhandle_sigurg(void* p_private){  struct mystr async_cmd_str = INIT_MYSTR;  struct mystr async_arg_str = INIT_MYSTR;  struct mystr real_cmd_str = INIT_MYSTR;  unsigned int len;  struct vsf_session* p_sess = (struct vsf_session*) p_private;  /* Did stupid client sent something OOB without a data connection? */  if (p_sess->data_fd == -1)  {    return;  }  /* Get the async command - blocks (use data timeout alarm) */  vsf_cmdio_get_cmd_and_arg(p_sess, &async_cmd_str, &async_arg_str, 0);  /* Chop off first four characters; they are telnet characters. The client   * should have sent the first two normally and the second two as urgent   * data.   */  len = str_getlen(&async_cmd_str);  if (len >= 4)  {    str_right(&async_cmd_str, &real_cmd_str, len - 4);  }  if (str_equal_text(&real_cmd_str, "ABOR"))  {    p_sess->abor_received = 1;    /* This is failok because of a small race condition; the SIGURG might     * be raised after the data socket is closed, but before data_fd is     * set to -1.     */    vsf_sysutil_shutdown_failok(p_sess->data_fd);  }  else  {    /* Sorry! */    vsf_cmdio_write(p_sess, FTP_BADCMD, "Unknown command.");  }  str_free(&async_cmd_str);  str_free(&async_arg_str);  str_free(&real_cmd_str);}static intget_remote_transfer_fd(struct vsf_session* p_sess, const char* p_status_msg){  int remote_fd;  if (!pasv_active(p_sess) && !port_active(p_sess))  {    bug("neither PORT nor PASV active in get_remote_transfer_fd");  }  p_sess->abor_received = 0;  if (pasv_active(p_sess))  {    remote_fd = vsf_ftpdataio_get_pasv_fd(p_sess);  }  else  {    remote_fd = vsf_ftpdataio_get_port_fd(p_sess);  }  if (vsf_sysutil_retval_is_error(remote_fd))  {    return remote_fd;  }  vsf_cmdio_write(p_sess, FTP_DATACONN, p_status_msg);  if (vsf_ftpdataio_post_mark_connect(p_sess) != 1)  {    vsf_ftpdataio_dispose_transfer_fd(p_sess);    return -1;  }  return remote_fd;}static voidcheck_abor(struct vsf_session* p_sess){  /* If the client sent ABOR, respond to it here */  if (p_sess->abor_received)  {    p_sess->abor_received = 0;    vsf_cmdio_write(p_sess, FTP_ABOROK, "ABOR successful.");  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -