Пример #1
0
static void
ftp_write_str_common(struct vsf_session* p_sess, int status, char sep,
                     const struct mystr* p_str, int noblock)
{
  static struct mystr s_write_buf_str;
  static struct mystr s_text_mangle_str;
  int retval;
  if (tunable_log_ftp_protocol)
  {
    str_alloc_ulong(&s_write_buf_str, (unsigned long) status);
    str_append_char(&s_write_buf_str, sep);
    str_append_str(&s_write_buf_str, p_str);
    vsf_log_line(p_sess, kVSFLogEntryFTPOutput, &s_write_buf_str);
  }
  str_copy(&s_text_mangle_str, p_str);
  /* Process the output response according to the specifications.. */
  /* Escape telnet characters properly */
  str_replace_text(&s_text_mangle_str, "\377", "\377\377");
  /* Change \n for \0 in response */
  str_replace_char(&s_text_mangle_str, '\n', '\0');
  /* Build string to squirt down network */
  str_alloc_ulong(&s_write_buf_str, (unsigned long) status);
  str_append_char(&s_write_buf_str, sep);
  str_append_str(&s_write_buf_str, &s_text_mangle_str);
  str_append_text(&s_write_buf_str, "\r\n");
  if (noblock)
  {
    vsf_sysutil_activate_noblock(VSFTP_COMMAND_FD);
  }
  retval = ftp_write_str(p_sess, &s_write_buf_str, kVSFRWControl);
  if (retval != 0 && !noblock)
  {
    die("ftp_write");
  }
  if (noblock)
  {
    vsf_sysutil_deactivate_noblock(VSFTP_COMMAND_FD);
  }
}
Пример #2
0
static SSL*
get_ssl(struct vsf_session* p_sess, int fd)
{
  SSL* p_ssl = SSL_new(p_sess->p_ssl_ctx);
  if (p_ssl == NULL)
  {
    if (tunable_debug_ssl)
    {
      str_alloc_text(&debug_str, "SSL_new failed");
      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
    }
    return NULL;
  }
  if (!SSL_set_fd(p_ssl, fd))
  {
    if (tunable_debug_ssl)
    {
      str_alloc_text(&debug_str, "SSL_set_fd failed");
      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
    }
    SSL_free(p_ssl);
    return NULL;
  }

  int retval;
  if (p_sess->is_ssl_client)
  {
    /* Connect to a remote FXP server in SSL client mode */
    retval = SSL_connect(p_ssl);
    str_alloc_text(&debug_str, "SSL_connect failed: ");
  }
  else
  {
    /* Accept a SSL connection from a client or remote FXP server */
    retval = SSL_accept(p_ssl);
    str_alloc_text(&debug_str, "SSL_accept failed: ");
  }

  if (retval != 1)
  {
    const char* p_err = get_ssl_error();
    if (tunable_debug_ssl)
    {
      str_append_text(&debug_str, p_err);
      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
    }
    /* The RFC is quite clear that we can just close the control channel
     * here.
     */
     die(p_err);
  }
  if (tunable_debug_ssl)
  {
    const char* p_ssl_version = SSL_get_cipher_version(p_ssl);
    SSL_CIPHER* p_ssl_cipher = SSL_get_current_cipher(p_ssl);
    const char* p_cipher_name = SSL_CIPHER_get_name(p_ssl_cipher);
    X509* p_ssl_cert = SSL_get_peer_certificate(p_ssl);
    int reused = SSL_session_reused(p_ssl);
    str_alloc_text(&debug_str, "SSL version: ");
    str_append_text(&debug_str, p_ssl_version);
    str_append_text(&debug_str, ", SSL cipher: ");
    str_append_text(&debug_str, p_cipher_name);
    if (reused)
    {
      str_append_text(&debug_str, ", reused");
    }
    else
    {
      str_append_text(&debug_str, ", not reused");
    }
    if (p_ssl_cert != NULL)
    {
      str_append_text(&debug_str, ", CERT PRESENTED");
      X509_free(p_ssl_cert);
    }
    else
    {
      str_append_text(&debug_str, ", no cert");
    }
    vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
  }
  return p_ssl;
}
Пример #3
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);
  }
}