2 * Part of Very Secure FTPd
17 /* File local functions */
18 static int vsf_log_type_is_transfer(enum EVSFLogEntryType type
);
19 static void vsf_log_common(struct vsf_session
* p_sess
, int succeeded
,
20 enum EVSFLogEntryType what
,
21 const struct mystr
* p_str
);
22 static void vsf_log_do_log_vsftpd_format(struct vsf_session
* p_sess
,
23 struct mystr
* p_str
, int succeeded
,
24 enum EVSFLogEntryType what
,
25 const struct mystr
* p_log_str
);
26 static void vsf_log_do_log_wuftpd_format(struct vsf_session
* p_sess
,
27 struct mystr
* p_str
, int succeeded
);
28 static void vsf_log_do_log_to_file(int fd
, struct mystr
* p_str
);
31 vsf_log_init(struct vsf_session
* p_sess
)
34 if (tunable_syslog_enable
|| tunable_tcp_wrappers
)
36 vsf_sysutil_openlog(1);
38 if (!tunable_xferlog_enable
&& !tunable_dual_log_enable
)
42 if (tunable_dual_log_enable
|| tunable_xferlog_std_format
)
44 retval
= vsf_sysutil_create_or_open_file_append(tunable_xferlog_file
, 0600);
45 if (vsf_sysutil_retval_is_error(retval
))
47 die2("failed to open xferlog log file:", tunable_xferlog_file
);
49 p_sess
->xferlog_fd
= retval
;
51 if (tunable_dual_log_enable
|| !tunable_xferlog_std_format
)
53 if (!tunable_syslog_enable
)
55 retval
= vsf_sysutil_create_or_open_file_append(tunable_vsftpd_log_file
,
57 if (vsf_sysutil_retval_is_error(retval
))
59 die2("failed to open vsftpd log file:", tunable_vsftpd_log_file
);
61 p_sess
->vsftpd_log_fd
= retval
;
67 vsf_log_type_is_transfer(enum EVSFLogEntryType type
)
69 return (type
== kVSFLogEntryDownload
|| type
== kVSFLogEntryUpload
);
73 vsf_log_start_entry(struct vsf_session
* p_sess
, enum EVSFLogEntryType what
)
75 if (p_sess
->log_type
!= 0)
77 bug("non null log_type in vsf_log_start_entry");
79 p_sess
->log_type
= (unsigned long) what
;
80 p_sess
->log_start_sec
= 0;
81 p_sess
->log_start_usec
= 0;
82 p_sess
->transfer_size
= 0;
83 str_empty(&p_sess
->log_str
);
84 if (vsf_log_type_is_transfer(what
))
86 p_sess
->log_start_sec
= vsf_sysutil_get_time_sec();
87 p_sess
->log_start_usec
= vsf_sysutil_get_time_usec();
92 vsf_log_line(struct vsf_session
* p_sess
, enum EVSFLogEntryType what
,
95 vsf_log_common(p_sess
, 1, what
, p_str
);
99 vsf_log_entry_pending(struct vsf_session
* p_sess
)
101 if (p_sess
->log_type
== 0)
109 vsf_log_clear_entry(struct vsf_session
* p_sess
)
111 p_sess
->log_type
= 0;
115 vsf_log_do_log(struct vsf_session
* p_sess
, int succeeded
)
117 vsf_log_common(p_sess
, succeeded
, (enum EVSFLogEntryType
) p_sess
->log_type
,
119 p_sess
->log_type
= 0;
123 vsf_log_common(struct vsf_session
* p_sess
, int succeeded
,
124 enum EVSFLogEntryType what
, const struct mystr
* p_str
)
126 static struct mystr s_log_str
;
127 /* Handle xferlog line if appropriate */
128 if (p_sess
->xferlog_fd
!= -1 && vsf_log_type_is_transfer(what
))
130 vsf_log_do_log_wuftpd_format(p_sess
, &s_log_str
, succeeded
);
131 vsf_log_do_log_to_file(p_sess
->xferlog_fd
, &s_log_str
);
133 /* Handle vsftpd.log line if appropriate */
134 if (p_sess
->vsftpd_log_fd
!= -1)
136 vsf_log_do_log_vsftpd_format(p_sess
, &s_log_str
, succeeded
, what
, p_str
);
137 vsf_log_do_log_to_file(p_sess
->vsftpd_log_fd
, &s_log_str
);
139 /* Handle syslog() line if appropriate */
140 if (tunable_syslog_enable
)
143 vsf_log_do_log_vsftpd_format(p_sess
, &s_log_str
, succeeded
, what
, p_str
);
144 if (what
== kVSFLogEntryLogin
&& !succeeded
)
148 str_syslog(&s_log_str
, severe
);
153 vsf_log_do_log_to_file(int fd
, struct mystr
* p_str
)
155 if (!tunable_no_log_lock
)
157 int retval
= vsf_sysutil_lock_file_write(fd
);
158 if (vsf_sysutil_retval_is_error(retval
))
163 str_replace_unprintable(p_str
, '?');
164 str_append_char(p_str
, '\n');
165 /* Ignore write failure; maybe the disk filled etc. */
166 (void) str_write_loop(p_str
, fd
);
167 if (!tunable_no_log_lock
)
169 vsf_sysutil_unlock_file(fd
);
174 vsf_log_do_log_wuftpd_format(struct vsf_session
* p_sess
, struct mystr
* p_str
,
177 static struct mystr s_filename_str
;
179 enum EVSFLogEntryType what
= (enum EVSFLogEntryType
) p_sess
->log_type
;
180 /* Date - vsf_sysutil_get_current_date updates cached time */
181 str_alloc_text(p_str
, vsf_sysutil_get_current_date());
182 str_append_char(p_str
, ' ');
183 /* Transfer time (in seconds) */
184 delta_sec
= vsf_sysutil_get_time_sec() - p_sess
->log_start_sec
;
189 str_append_ulong(p_str
, (unsigned long) delta_sec
);
190 str_append_char(p_str
, ' ');
191 /* Remote host name */
192 str_append_str(p_str
, &p_sess
->remote_ip_str
);
193 str_append_char(p_str
, ' ');
194 /* Bytes transferred */
195 str_append_filesize_t(p_str
, p_sess
->transfer_size
);
196 str_append_char(p_str
, ' ');
198 str_copy(&s_filename_str
, &p_sess
->log_str
);
199 str_replace_char(&s_filename_str
, ' ', '_');
200 str_append_str(p_str
, &s_filename_str
);
201 str_append_char(p_str
, ' ');
202 /* Transfer type (ascii/binary) */
203 if (p_sess
->is_ascii
)
205 str_append_text(p_str
, "a ");
209 str_append_text(p_str
, "b ");
211 /* Special action flag - tar, gzip etc. */
212 str_append_text(p_str
, "_ ");
213 /* Direction of transfer */
214 if (what
== kVSFLogEntryUpload
)
216 str_append_text(p_str
, "i ");
220 str_append_text(p_str
, "o ");
222 /* Access mode: anonymous/real user, and identity */
223 if (p_sess
->is_anonymous
&& !p_sess
->is_guest
)
225 str_append_text(p_str
, "a ");
226 str_append_str(p_str
, &p_sess
->anon_pass_str
);
230 if (p_sess
->is_guest
)
232 str_append_text(p_str
, "g ");
236 str_append_text(p_str
, "r ");
238 str_append_str(p_str
, &p_sess
->user_str
);
240 str_append_char(p_str
, ' ');
241 /* Service name, authentication method, authentication user id */
242 str_append_text(p_str
, "ftp 0 * ");
243 /* Completion status */
246 str_append_char(p_str
, 'c');
250 str_append_char(p_str
, 'i');
255 vsf_log_do_log_vsftpd_format(struct vsf_session
* p_sess
, struct mystr
* p_str
,
256 int succeeded
, enum EVSFLogEntryType what
,
257 const struct mystr
* p_log_str
)
260 if (!tunable_syslog_enable
)
262 /* Date - vsf_sysutil_get_current_date updates cached time */
263 str_append_text(p_str
, vsf_sysutil_get_current_date());
265 str_append_text(p_str
, " [pid ");
266 str_append_ulong(p_str
, vsf_sysutil_getpid());
267 str_append_text(p_str
, "] ");
270 if (!str_isempty(&p_sess
->user_str
))
272 str_append_char(p_str
, '[');
273 str_append_str(p_str
, &p_sess
->user_str
);
274 str_append_text(p_str
, "] ");
277 if (what
!= kVSFLogEntryFTPInput
&& what
!= kVSFLogEntryFTPOutput
&&
278 what
!= kVSFLogEntryConnection
&& what
!= kVSFLogEntryDebug
)
282 str_append_text(p_str
, "OK ");
286 str_append_text(p_str
, "FAIL ");
291 case kVSFLogEntryDownload
:
292 str_append_text(p_str
, "DOWNLOAD");
294 case kVSFLogEntryUpload
:
295 str_append_text(p_str
, "UPLOAD");
297 case kVSFLogEntryMkdir
:
298 str_append_text(p_str
, "MKDIR");
300 case kVSFLogEntryLogin
:
301 str_append_text(p_str
, "LOGIN");
303 case kVSFLogEntryFTPInput
:
304 str_append_text(p_str
, "FTP command");
306 case kVSFLogEntryFTPOutput
:
307 str_append_text(p_str
, "FTP response");
309 case kVSFLogEntryConnection
:
310 str_append_text(p_str
, "CONNECT");
312 case kVSFLogEntryDelete
:
313 str_append_text(p_str
, "DELETE");
315 case kVSFLogEntryRename
:
316 str_append_text(p_str
, "RENAME");
318 case kVSFLogEntryRmdir
:
319 str_append_text(p_str
, "RMDIR");
321 case kVSFLogEntryChmod
:
322 str_append_text(p_str
, "CHMOD");
324 case kVSFLogEntryDebug
:
325 str_append_text(p_str
, "DEBUG");
328 bug("bad entry_type in vsf_log_do_log");
331 str_append_text(p_str
, ": Client \"");
332 str_append_str(p_str
, &p_sess
->remote_ip_str
);
333 str_append_char(p_str
, '"');
334 if (what
== kVSFLogEntryLogin
&& !str_isempty(&p_sess
->anon_pass_str
))
336 str_append_text(p_str
, ", anon password \"");
337 str_append_str(p_str
, &p_sess
->anon_pass_str
);
338 str_append_char(p_str
, '"');
340 if (!str_isempty(p_log_str
))
342 str_append_text(p_str
, ", \"");
343 str_append_str(p_str
, p_log_str
);
344 str_append_char(p_str
, '"');
346 if (what
!= kVSFLogEntryFTPInput
&& what
!= kVSFLogEntryFTPOutput
&&
347 what
!= kVSFLogEntryDebug
)
349 if (p_sess
->transfer_size
)
351 str_append_text(p_str
, ", ");
352 str_append_filesize_t(p_str
, p_sess
->transfer_size
);
353 str_append_text(p_str
, " bytes");
355 if (vsf_log_type_is_transfer(what
))
357 long delta_sec
= vsf_sysutil_get_time_sec() - p_sess
->log_start_sec
;
358 long delta_usec
= vsf_sysutil_get_time_usec() - p_sess
->log_start_usec
;
359 double time_delta
= (double) delta_sec
+ ((double) delta_usec
/
367 ((double) p_sess
->transfer_size
/ time_delta
) / (double) 1024;
368 str_append_text(p_str
, ", ");
369 str_append_double(p_str
, kbyte_rate
);
370 str_append_text(p_str
, "Kbyte/sec");