static void
handle_sigterm(void* duff)
{
  (void) duff;
  /* Blow away the connection to make sure no process lingers. */
  vsf_sysutil_shutdown_failok(VSFTP_COMMAND_FD);
  /* Will call the registered exit function to clean up u/wtmp if needed. */
  vsf_sysutil_exit(1);
}
Beispiel #2
0
void
vsf_cmdio_write_exit(struct vsf_session* p_sess, int status, const char* p_text)
{
  /* Unblock any readers on the dying control channel. This is needed for SSL
   * connections, where the SSL control channel slave is in a separate
   * process.
   */
  vsf_sysutil_shutdown_read_failok(VSFTP_COMMAND_FD);
  ftp_write_text_common(p_sess, status, p_text, 1, ' ');
  vsf_sysutil_shutdown_failok(VSFTP_COMMAND_FD);
  vsf_sysutil_exit(0);
}
Beispiel #3
0
static void
handle_sigalrm(void* p_private)
{
  struct vsf_session* p_sess = (struct vsf_session*) p_private;
  if (!p_sess->data_progress)
  {
    p_sess->data_timeout = 1;
    vsf_sysutil_shutdown_failok(p_sess->data_fd);
    vsf_sysutil_shutdown_read_failok(VSFTP_COMMAND_FD);
    vsf_sysutil_activate_noblock(VSFTP_COMMAND_FD);
  }
  else
  {
    p_sess->data_progress = 0;
    start_data_alarm(p_sess);
  }
}
Beispiel #4
0
static void
handle_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;
    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);
}
Beispiel #5
0
void
vsf_cmdio_get_cmd_and_arg(struct vsf_session* p_sess, struct mystr* p_cmd_str,
                          struct mystr* p_arg_str, int set_alarm)
{
  int ret;
  /* Prepare an alarm to timeout the session.. */
  if (set_alarm)
  {
    vsf_cmdio_set_alarm(p_sess);
  }
  /* Blocks */
  ret = control_getline(p_cmd_str, p_sess);
  if (p_sess->idle_timeout)
  {
    vsf_cmdio_write_exit(p_sess, FTP_IDLE_TIMEOUT, "Timeout.", 1);
  }
  if (ret == 0)
  {
    /* Remote end hung up without a polite QUIT. The shutdown is to make
     * sure buggy clients don't ever see an OOPS message.
     */
    vsf_sysutil_shutdown_failok(VSFTP_COMMAND_FD);
    vsf_sysutil_exit(1);
  }
  /* View a single space as a command of " ", which although a useless command,
   * permits the caller to distinguish input of "" from " ".
   */
  if (str_getlen(p_cmd_str) == 1 && str_get_char_at(p_cmd_str, 0) == ' ')
  {
    str_empty(p_arg_str);
  }
  else
  {
    str_split_char(p_cmd_str, p_arg_str, ' ');
  }
  str_upper(p_cmd_str);
  if (!str_isempty(p_arg_str)) {
    char *tmp_str;
    tmp_str = remote2local(str_getbuf(p_arg_str));
    if (tmp_str != NULL) {
      str_empty(p_arg_str);
      str_append_text(p_arg_str, tmp_str);
      vsf_sysutil_free(tmp_str);
    }
  }
  if (tunable_log_ftp_protocol)
  {
    static struct mystr s_log_str;
    if (str_equal_text(p_cmd_str, "PASS"))
    {
      str_alloc_text(&s_log_str, "PASS <password>");
    }
    else
    {
      str_copy(&s_log_str, p_cmd_str);
      if (!str_isempty(p_arg_str))
      {
        str_append_char(&s_log_str, ' ');
        str_append_str(&s_log_str, p_arg_str);
      }
    }
    vsf_log_line(p_sess, kVSFLogEntryFTPInput, &s_log_str);
  }
}