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); } }
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; }
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); } }