123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- /*
- * Part of Very Secure FTPd
- * Licence: GPL v2
- * Author: Chris Evans
- *
- * logging.c
- */
- #include "logging.h"
- #include "tunables.h"
- #include "utility.h"
- #include "str.h"
- #include "sysutil.h"
- #include "sysstr.h"
- #include "session.h"
- /* File local functions */
- static int vsf_log_type_is_transfer(enum EVSFLogEntryType type);
- static void vsf_log_common(struct vsf_session* p_sess, int succeeded,
- enum EVSFLogEntryType what,
- const struct mystr* p_str);
- static void vsf_log_do_log_vsftpd_format(struct vsf_session* p_sess,
- struct mystr* p_str, int succeeded,
- enum EVSFLogEntryType what,
- const struct mystr* p_log_str);
- static void vsf_log_do_log_wuftpd_format(struct vsf_session* p_sess,
- struct mystr* p_str, int succeeded);
- static void vsf_log_do_log_to_file(int fd, struct mystr* p_str);
- void
- vsf_log_init(struct vsf_session* p_sess)
- {
- if (tunable_syslog_enable || tunable_tcp_wrappers)
- {
- vsf_sysutil_openlog(1);
- }
- if (!tunable_xferlog_enable && !tunable_dual_log_enable)
- {
- return;
- }
- if (tunable_dual_log_enable || tunable_xferlog_std_format)
- {
- int retval = -1;
- if (tunable_xferlog_file)
- {
- retval = vsf_sysutil_create_or_open_file_append(tunable_xferlog_file,
- 0600);
- }
- if (vsf_sysutil_retval_is_error(retval))
- {
- die2("failed to open xferlog log file:", tunable_xferlog_file);
- }
- p_sess->xferlog_fd = retval;
- }
- if (tunable_dual_log_enable || !tunable_xferlog_std_format)
- {
- if (!tunable_syslog_enable)
- {
- int retval = -1;
- if (tunable_vsftpd_log_file)
- {
- retval = vsf_sysutil_create_or_open_file_append(tunable_vsftpd_log_file,
- 0600);
- }
- if (vsf_sysutil_retval_is_error(retval))
- {
- die2("failed to open zftpd log file:", tunable_vsftpd_log_file);
- }
- p_sess->vsftpd_log_fd = retval;
- }
- }
- }
- static int
- vsf_log_type_is_transfer(enum EVSFLogEntryType type)
- {
- return (type == kVSFLogEntryDownload || type == kVSFLogEntryUpload);
- }
- 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))
- {
- p_sess->log_start_sec = vsf_sysutil_get_time_sec();
- p_sess->log_start_usec = vsf_sysutil_get_time_usec();
- }
- }
- void
- vsf_log_line(struct vsf_session* p_sess, enum EVSFLogEntryType what,
- struct mystr* p_str)
- {
- vsf_log_common(p_sess, 1, what, p_str);
- }
- int
- vsf_log_entry_pending(struct vsf_session* p_sess)
- {
- if (p_sess->log_type == 0)
- {
- return 0;
- }
- return 1;
- }
- void
- vsf_log_clear_entry(struct vsf_session* p_sess)
- {
- p_sess->log_type = 0;
- }
- void
- vsf_log_do_log(struct vsf_session* p_sess, int succeeded)
- {
- vsf_log_common(p_sess, succeeded, (enum EVSFLogEntryType) p_sess->log_type,
- &p_sess->log_str);
- p_sess->log_type = 0;
- }
- static void
- vsf_log_common(struct vsf_session* p_sess, int succeeded,
- enum EVSFLogEntryType what, const struct mystr* p_str)
- {
- static struct mystr s_log_str;
- /* Handle xferlog line if appropriate */
- if (p_sess->xferlog_fd != -1 && vsf_log_type_is_transfer(what))
- {
- vsf_log_do_log_wuftpd_format(p_sess, &s_log_str, succeeded);
- vsf_log_do_log_to_file(p_sess->xferlog_fd, &s_log_str);
- }
- /* Handle vsftpd.log line if appropriate */
- if (p_sess->vsftpd_log_fd != -1)
- {
- vsf_log_do_log_vsftpd_format(p_sess, &s_log_str, succeeded, what, p_str);
- vsf_log_do_log_to_file(p_sess->vsftpd_log_fd, &s_log_str);
- }
- /* Handle syslog() line if appropriate */
- if (tunable_syslog_enable)
- {
- int severe = 0;
- vsf_log_do_log_vsftpd_format(p_sess, &s_log_str, succeeded, what, p_str);
- if (what == kVSFLogEntryLogin && !succeeded)
- {
- severe = 1;
- }
- str_syslog(&s_log_str, severe);
- }
- }
- static void
- vsf_log_do_log_to_file(int fd, struct mystr* p_str)
- {
- if (!tunable_no_log_lock)
- {
- int retval = vsf_sysutil_lock_file_write(fd);
- if (vsf_sysutil_retval_is_error(retval))
- {
- return;
- }
- }
- str_replace_unprintable(p_str, '?');
- str_append_char(p_str, '\n');
- /* Ignore write failure; maybe the disk filled etc. */
- (void) str_write_loop(p_str, fd);
- if (!tunable_no_log_lock)
- {
- vsf_sysutil_unlock_file(fd);
- }
- }
- static void
- vsf_log_do_log_wuftpd_format(struct vsf_session* p_sess, struct mystr* p_str,
- int succeeded)
- {
- static struct mystr s_filename_str;
- long delta_sec;
- enum EVSFLogEntryType what = (enum EVSFLogEntryType) p_sess->log_type;
- /* Date - vsf_sysutil_get_current_date updates cached time */
- str_alloc_text(p_str, vsf_sysutil_get_current_date());
- str_append_char(p_str, ' ');
- /* Transfer time (in seconds) */
- delta_sec = vsf_sysutil_get_time_sec() - p_sess->log_start_sec;
- if (delta_sec <= 0)
- {
- delta_sec = 1;
- }
- str_append_ulong(p_str, (unsigned long) delta_sec);
- str_append_char(p_str, ' ');
- /* Remote host name */
- str_append_str(p_str, &p_sess->remote_ip_str);
- str_append_char(p_str, ' ');
- /* Bytes transferred */
- str_append_filesize_t(p_str, p_sess->transfer_size);
- str_append_char(p_str, ' ');
- /* Filename */
- str_copy(&s_filename_str, &p_sess->log_str);
- str_replace_char(&s_filename_str, ' ', '_');
- str_append_str(p_str, &s_filename_str);
- str_append_char(p_str, ' ');
- /* Transfer type (ascii/binary) */
- if (p_sess->is_ascii)
- {
- str_append_text(p_str, "a ");
- }
- else
- {
- str_append_text(p_str, "b ");
- }
- /* Special action flag - tar, gzip etc. */
- str_append_text(p_str, "_ ");
- /* Direction of transfer */
- if (what == kVSFLogEntryUpload)
- {
- str_append_text(p_str, "i ");
- }
- else
- {
- str_append_text(p_str, "o ");
- }
- /* Access mode: anonymous/real user, and identity */
- if (p_sess->is_anonymous && !p_sess->is_guest)
- {
- str_append_text(p_str, "a ");
- str_append_str(p_str, &p_sess->anon_pass_str);
- }
- else
- {
- if (p_sess->is_guest)
- {
- str_append_text(p_str, "g ");
- }
- else
- {
- str_append_text(p_str, "r ");
- }
- str_append_str(p_str, &p_sess->user_str);
- }
- str_append_char(p_str, ' ');
- /* Service name, authentication method, authentication user id */
- str_append_text(p_str, "ftp 0 * ");
- /* Completion status */
- if (succeeded)
- {
- str_append_char(p_str, 'c');
- }
- else
- {
- str_append_char(p_str, 'i');
- }
- }
- static void
- vsf_log_do_log_vsftpd_format(struct vsf_session* p_sess, struct mystr* p_str,
- int succeeded, enum EVSFLogEntryType what,
- const struct mystr* p_log_str)
- {
- str_empty(p_str);
- if (!tunable_syslog_enable)
- {
- /* Date - vsf_sysutil_get_current_date updates cached time */
- str_append_text(p_str, vsf_sysutil_get_current_date());
- /* Pid */
- str_append_text(p_str, " [pid ");
- str_append_ulong(p_str, vsf_sysutil_getpid());
- str_append_text(p_str, "] ");
- }
- /* User */
- if (!str_isempty(&p_sess->user_str))
- {
- str_append_char(p_str, '[');
- str_append_str(p_str, &p_sess->user_str);
- str_append_text(p_str, "] ");
- }
- /* And the action */
- if (what != kVSFLogEntryFTPInput && what != kVSFLogEntryFTPOutput &&
- what != kVSFLogEntryConnection && what != kVSFLogEntryDebug)
- {
- if (succeeded)
- {
- str_append_text(p_str, "OK ");
- }
- else
- {
- str_append_text(p_str, "FAIL ");
- }
- }
- switch (what)
- {
- case kVSFLogEntryDownload:
- str_append_text(p_str, "DOWNLOAD");
- break;
- case kVSFLogEntryUpload:
- str_append_text(p_str, "UPLOAD");
- break;
- case kVSFLogEntryMkdir:
- str_append_text(p_str, "MKDIR");
- break;
- case kVSFLogEntryLogin:
- str_append_text(p_str, "LOGIN");
- break;
- case kVSFLogEntryFTPInput:
- str_append_text(p_str, "FTP command");
- break;
- case kVSFLogEntryFTPOutput:
- str_append_text(p_str, "FTP response");
- break;
- case kVSFLogEntryConnection:
- str_append_text(p_str, "CONNECT");
- break;
- case kVSFLogEntryDelete:
- str_append_text(p_str, "DELETE");
- break;
- case kVSFLogEntryRename:
- str_append_text(p_str, "RENAME");
- break;
- case kVSFLogEntryRmdir:
- str_append_text(p_str, "RMDIR");
- break;
- case kVSFLogEntryChmod:
- str_append_text(p_str, "CHMOD");
- break;
- case kVSFLogEntryDebug:
- str_append_text(p_str, "DEBUG");
- break;
- case kVSFLogEntryNull:
- /* Fall through */
- default:
- bug("bad entry_type in sf_log_do_log");
- break;
- }
- str_append_text(p_str, ": Client \"");
- str_append_str(p_str, &p_sess->remote_ip_str);
- str_append_char(p_str, '"');
- if (what == kVSFLogEntryLogin && !str_isempty(&p_sess->anon_pass_str))
- {
- str_append_text(p_str, ", anon password \"");
- str_append_str(p_str, &p_sess->anon_pass_str);
- str_append_char(p_str, '"');
- }
- if (!str_isempty(p_log_str))
- {
- str_append_text(p_str, ", \"");
- str_append_str(p_str, p_log_str);
- str_append_char(p_str, '"');
- }
- if (what != kVSFLogEntryFTPInput && what != kVSFLogEntryFTPOutput &&
- what != kVSFLogEntryDebug)
- {
- if (p_sess->transfer_size)
- {
- str_append_text(p_str, ", ");
- str_append_filesize_t(p_str, p_sess->transfer_size);
- str_append_text(p_str, " bytes");
- }
- if (vsf_log_type_is_transfer(what))
- {
- long delta_sec = vsf_sysutil_get_time_sec() - p_sess->log_start_sec;
- long delta_usec = vsf_sysutil_get_time_usec() - p_sess->log_start_usec;
- double time_delta = (double) delta_sec + ((double) delta_usec /
- (double) 1000000);
- double kbyte_rate;
- if (time_delta <= 0)
- {
- time_delta = 0.1;
- }
- kbyte_rate =
- ((double) p_sess->transfer_size / time_delta) / (double) 1024;
- str_append_text(p_str, ", ");
- str_append_double(p_str, kbyte_rate);
- str_append_text(p_str, "Kbyte/sec");
- }
- }
- }
|