Exemplo n.º 1
0
static void
handle_io(int retval, int fd, void* p_private)
{
  long curr_sec;
  long curr_usec;
  unsigned int bw_rate;
  double elapsed;
  double pause_time;
  double rate_ratio;
  struct vsf_session* p_sess = (struct vsf_session*) p_private;
  if (p_sess->data_fd != fd || vsf_sysutil_retval_is_error(retval) ||
      retval == 0)
  {
    return;
  }
  /* Note that the session hasn't stalled, i.e. don't time it out */
  p_sess->data_progress = 1;
  /* Apply bandwidth quotas via a little pause, if necessary */
  if (p_sess->bw_rate_max == 0)
  {
    return;
  }
  /* Calculate bandwidth rate */
  vsf_sysutil_update_cached_time();
  curr_sec = vsf_sysutil_get_cached_time_sec();
  curr_usec = vsf_sysutil_get_cached_time_usec();
  elapsed = (double) (curr_sec - p_sess->bw_send_start_sec);
  elapsed += (double) (curr_usec - p_sess->bw_send_start_usec) /
             (double) 1000000;
  if (elapsed <= (double) 0)
  {
    elapsed = (double) 0.01;
  }
  bw_rate = (unsigned int) ((double) retval / elapsed);
  if (bw_rate <= p_sess->bw_rate_max)
  {
    p_sess->bw_send_start_sec = curr_sec;
    p_sess->bw_send_start_usec = curr_usec;
    return;
  }
  /* Tut! Rate exceeded, calculate a pause to bring things back into line */
  rate_ratio = (double) bw_rate / (double) p_sess->bw_rate_max;
  pause_time = (rate_ratio - (double) 1) * elapsed;
  vsf_sysutil_sleep(pause_time);
  vsf_sysutil_update_cached_time();
  p_sess->bw_send_start_sec = vsf_sysutil_get_cached_time_sec();
  p_sess->bw_send_start_usec = vsf_sysutil_get_cached_time_usec();
}
Exemplo n.º 2
0
void
vsf_log_start_entry(struct vsf_session* p_sess, enum EVSFLogEntryType what)
{
  if (p_sess->log_type != 0)
  {
    bug("non null log_type in vsf_log_start_entry");
  }
  p_sess->log_type = (unsigned long) what;
  p_sess->log_start_sec = 0;
  p_sess->log_start_usec = 0;
  p_sess->transfer_size = 0;
  str_empty(&p_sess->log_str);
  if (vsf_log_type_is_transfer(what))
  {
    vsf_sysutil_update_cached_time();
    p_sess->log_start_sec = vsf_sysutil_get_cached_time_sec();
    p_sess->log_start_usec = vsf_sysutil_get_cached_time_usec();
  }
}
Exemplo n.º 3
0
static void
vsf_remove_uwtmp(void)
{
  if (!s_uwtmp_inserted)
  {
    return;
  }
  s_uwtmp_inserted = 0;
  s_utent.ut_type = DEAD_PROCESS;
  vsf_sysutil_memclr(s_utent.ut_user, sizeof(s_utent.ut_user));
  vsf_sysutil_memclr(s_utent.ut_host, sizeof(s_utent.ut_host));
  s_utent.ut_tv.tv_sec = 0;
  setutxent();
  (void) pututxline(&s_utent);
  endutxent();
  vsf_sysutil_update_cached_time();
  s_utent.ut_tv.tv_sec = vsf_sysutil_get_cached_time_sec();
  updwtmpx(WTMPX_FILE, &s_utent);
}
Exemplo n.º 4
0
static void
vsf_insert_uwtmp(const struct mystr* p_user_str,
                 const struct mystr* p_host_str)
{
  if (sizeof(s_utent.ut_line) < 16)
  {
    return;
  }
  if (s_uwtmp_inserted)
  {
    bug("vsf_insert_uwtmp");
  }
  {
    struct mystr line_str = INIT_MYSTR;
    str_alloc_text(&line_str, "vsftpd:");
    str_append_ulong(&line_str, vsf_sysutil_getpid());
    if (str_getlen(&line_str) >= sizeof(s_utent.ut_line))
    {
      str_free(&line_str);
      return;
    }
    vsf_sysutil_strcpy(s_utent.ut_line, str_getbuf(&line_str),
                       sizeof(s_utent.ut_line));
    str_free(&line_str);
  }
  s_uwtmp_inserted = 1;
  s_utent.ut_type = USER_PROCESS;
  s_utent.ut_pid = vsf_sysutil_getpid();
  vsf_sysutil_strcpy(s_utent.ut_user, str_getbuf(p_user_str),
                     sizeof(s_utent.ut_user));
  vsf_sysutil_strcpy(s_utent.ut_host, str_getbuf(p_host_str),
                     sizeof(s_utent.ut_host));
  vsf_sysutil_update_cached_time();
  s_utent.ut_tv.tv_sec = vsf_sysutil_get_cached_time_sec();
  setutxent();
  (void) pututxline(&s_utent);
  endutxent();
  updwtmpx(WTMPX_FILE, &s_utent);
}
Exemplo n.º 5
0
int
vsf_sysdep_check_auth(const struct mystr* p_user_str,
                      const struct mystr* p_pass_str,
                      const struct mystr* p_remote_host)
{
  const char* p_crypted;
  const struct passwd* p_pwd = getpwnam(str_getbuf(p_user_str));
  (void) p_remote_host;
  if (p_pwd == NULL)
  {
    return 0;
  }
  #ifdef VSF_SYSDEP_HAVE_USERSHELL
  if (tunable_check_shell)
  {
    const char* p_shell;
    while ((p_shell = getusershell()) != NULL)
    {
      if (!vsf_sysutil_strcmp(p_shell, p_pwd->pw_shell))
      {
        break;
      }
    }
    endusershell();
    if (p_shell == NULL)
    {
      return 0;
    }
  }
  #endif
  #ifdef VSF_SYSDEP_HAVE_SHADOW
  {
    const struct spwd* p_spwd = getspnam(str_getbuf(p_user_str));
    if (p_spwd != NULL)
    {
      long curr_time;
      int days;
      vsf_sysutil_update_cached_time();
      curr_time = vsf_sysutil_get_cached_time_sec();
      days = curr_time / (60 * 60 * 24);
      if (p_spwd->sp_expire > 0 && p_spwd->sp_expire < days)
      {
        return 0;
      }
      if (p_spwd->sp_lstchg > 0 && p_spwd->sp_max > 0 &&
          p_spwd->sp_lstchg + p_spwd->sp_max < days)
      {
        return 0;
      }
      p_crypted = crypt(str_getbuf(p_pass_str), p_spwd->sp_pwdp);
      if (!vsf_sysutil_strcmp(p_crypted, p_spwd->sp_pwdp))
      {
        return 1;
      }
    }
  }
  #endif /* VSF_SYSDEP_HAVE_SHADOW */
  p_crypted = crypt(str_getbuf(p_pass_str), p_pwd->pw_passwd);
  if (!vsf_sysutil_strcmp(p_crypted, p_pwd->pw_passwd))
  {
    return 1;
  }
  return 0;
}
Exemplo n.º 6
0
void
vsf_ls_populate_dir_list(struct mystr_list* p_list,
                         struct mystr_list* p_subdir_list,
                         struct vsf_sysutil_dir* p_dir,
                         const struct mystr* p_base_dir_str,
                         const struct mystr* p_option_str,
                         const struct mystr* p_filter_str,
                         int is_verbose)
{
  struct mystr dirline_str = INIT_MYSTR;
  struct mystr normalised_base_dir_str = INIT_MYSTR;
  struct str_locate_result loc_result;
  int a_option;
  int r_option;
  int t_option;
  int F_option;
  int do_stat = 0;
  loc_result = str_locate_char(p_option_str, 'a');
  a_option = loc_result.found;
  loc_result = str_locate_char(p_option_str, 'r');
  r_option = loc_result.found;
  loc_result = str_locate_char(p_option_str, 't');
  t_option = loc_result.found;
  loc_result = str_locate_char(p_option_str, 'F');
  F_option = loc_result.found;
  loc_result = str_locate_char(p_option_str, 'l');
  if (loc_result.found)
  {
    is_verbose = 1;
  }
  /* Invert "reverse" arg for "-t", the time sorting */
  if (t_option)
  {
    r_option = !r_option;
  }
  if (is_verbose || t_option || F_option || p_subdir_list != 0)
  {
    do_stat = 1;
  }
  /* If the filter starts with a . then implicitly enable -a */
  if (!str_isempty(p_filter_str) && str_get_char_at(p_filter_str, 0) == '.')
  {
    a_option = 1;
  }
  /* "Normalise" the incoming base directory string by making sure it
   * ends in a '/' if it is nonempty
   */
  if (!str_equal_text(p_base_dir_str, "."))
  {
    str_copy(&normalised_base_dir_str, p_base_dir_str);
  }
  if (!str_isempty(&normalised_base_dir_str))
  {
    unsigned int len = str_getlen(&normalised_base_dir_str);
    if (str_get_char_at(&normalised_base_dir_str, len - 1) != '/')
    {
      str_append_char(&normalised_base_dir_str, '/');
    }
  }
  /* If we're going to need to do time comparisions, cache the local time */
  if (is_verbose)
  {
    vsf_sysutil_update_cached_time();
  }
  while (1)
  {
    int len;
    static struct mystr s_next_filename_str;
    static struct mystr s_next_path_and_filename_str;
    static struct vsf_sysutil_statbuf* s_p_statbuf;
    str_next_dirent(&s_next_filename_str, p_dir);
    if (str_isempty(&s_next_filename_str))
    {
      break;
    }
    len = str_getlen(&s_next_filename_str);
    if (len > 0 && str_get_char_at(&s_next_filename_str, 0) == '.')
    {
      if (!a_option && !tunable_force_dot_files)
      {
        continue;
      }
      if (!a_option &&
          ((len == 2 && str_get_char_at(&s_next_filename_str, 1) == '.') ||
           len == 1))
      {
        continue;
      }
    }
    /* Don't show hidden directory entries */
    if (!vsf_access_check_file_visible(&s_next_filename_str))
    {
      continue;
    }
    /* If we have an ls option which is a filter, apply it */
    if (!str_isempty(p_filter_str))
    {
      if (!vsf_filename_passes_filter(&s_next_filename_str, p_filter_str))
      {
        continue;
      }
    }
    /* Calculate the full path (relative to CWD) for lstat() and
     * output purposes
     */
    str_copy(&s_next_path_and_filename_str, &normalised_base_dir_str);
    str_append_str(&s_next_path_and_filename_str, &s_next_filename_str);
    if (do_stat)
    {
      /* lstat() the file. Of course there's a race condition - the
       * directory entry may have gone away whilst we read it, so
       * ignore failure to stat
       */
      int retval = str_lstat(&s_next_path_and_filename_str, &s_p_statbuf);
      if (vsf_sysutil_retval_is_error(retval))
      {
        continue;
      }
    }
    if (is_verbose)
    {
      static struct mystr s_final_file_str;
      /* If it's a damn symlink, we need to append the target */
      str_copy(&s_final_file_str, &s_next_filename_str);
      if (vsf_sysutil_statbuf_is_symlink(s_p_statbuf))
      {
        static struct mystr s_temp_str;
        int retval = str_readlink(&s_temp_str, &s_next_path_and_filename_str);
        if (retval == 0 && !str_isempty(&s_temp_str))
        {
          str_append_text(&s_final_file_str, " -> ");
          str_append_str(&s_final_file_str, &s_temp_str);
        }
      }
      if (F_option && vsf_sysutil_statbuf_is_dir(s_p_statbuf))
      {
        str_append_char(&s_final_file_str, '/');
      }
      build_dir_line(&dirline_str, &s_final_file_str, s_p_statbuf);
    }
    else
    {
      /* Just emit the filenames - note, we prepend the directory for NLST
       * but not for LIST
       */
      str_copy(&dirline_str, &s_next_path_and_filename_str);
      if (F_option)
      {
        if (vsf_sysutil_statbuf_is_dir(s_p_statbuf))
        {
          str_append_char(&dirline_str, '/');
        }
        else if (vsf_sysutil_statbuf_is_symlink(s_p_statbuf))
        {
          str_append_char(&dirline_str, '@');
        }
      }
      str_append_text(&dirline_str, "\r\n");
    }
    /* Add filename into our sorted list - sorting by filename or time. Also,
     * if we are required to, maintain a distinct list of direct
     * subdirectories.
     */
    {
      static struct mystr s_temp_str;
      const struct mystr* p_sort_str = 0;
      const struct mystr* p_sort_subdir_str = 0;
      if (!t_option)
      {
        p_sort_str = &s_next_filename_str;
      }
      else
      {
        str_alloc_text(&s_temp_str,
                       vsf_sysutil_statbuf_get_sortkey_mtime(s_p_statbuf));
        p_sort_str = &s_temp_str;
        p_sort_subdir_str = &s_temp_str;
      }
      str_list_add(p_list, &dirline_str, p_sort_str);
      if (p_subdir_list != 0 && vsf_sysutil_statbuf_is_dir(s_p_statbuf))
      {
        str_list_add(p_subdir_list, &s_next_filename_str, p_sort_subdir_str);
      }
    }
  } /* END: while(1) */
  str_list_sort(p_list, r_option);
  if (p_subdir_list != 0)
  {
    str_list_sort(p_subdir_list, r_option);
  }
  str_free(&dirline_str);
  str_free(&normalised_base_dir_str);
}