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();
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(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(tunable_vsftpd_log_file
, 0600);
56 if (vsf_sysutil_retval_is_error(retval
))
58 die2("failed to open vsftpd log file:", tunable_vsftpd_log_file
);
60 p_sess
->vsftpd_log_fd
= retval
;
66 vsf_log_type_is_transfer(enum EVSFLogEntryType type
)
68 return (type
== kVSFLogEntryDownload
|| type
== kVSFLogEntryUpload
);
72 vsf_log_start_entry(struct vsf_session
* p_sess
, enum EVSFLogEntryType what
)
74 if (p_sess
->log_type
!= 0)
76 bug("non null log_type in vsf_log_start_entry");
78 p_sess
->log_type
= (unsigned long) what
;
79 p_sess
->log_start_sec
= 0;
80 p_sess
->log_start_usec
= 0;
81 p_sess
->transfer_size
= 0;
82 str_empty(&p_sess
->log_str
);
83 if (vsf_log_type_is_transfer(what
))
85 vsf_sysutil_update_cached_time();
86 p_sess
->log_start_sec
= vsf_sysutil_get_cached_time_sec();
87 p_sess
->log_start_usec
= vsf_sysutil_get_cached_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
,
178 enum EVSFLogEntryType what
= (enum EVSFLogEntryType
) p_sess
->log_type
;
179 /* Date - vsf_sysutil_get_current_date updates cached time */
180 str_alloc_text(p_str
, vsf_sysutil_get_current_date());
181 str_append_char(p_str
, ' ');
182 /* Transfer time (in seconds) */
183 delta_sec
= vsf_sysutil_get_cached_time_sec() - p_sess
->log_start_sec
;
188 str_append_ulong(p_str
, (unsigned long) delta_sec
);
189 str_append_char(p_str
, ' ');
190 /* Remote host name */
191 str_append_str(p_str
, &p_sess
->remote_ip_str
);
192 str_append_char(p_str
, ' ');
193 /* Bytes transferred */
194 str_append_filesize_t(p_str
, p_sess
->transfer_size
);
195 str_append_char(p_str
, ' ');
197 str_append_str(p_str
, &p_sess
->log_str
);
198 str_append_char(p_str
, ' ');
199 /* Transfer type (ascii/binary) */
200 if (p_sess
->is_ascii
)
202 str_append_text(p_str
, "a ");
206 str_append_text(p_str
, "b ");
208 /* Special action flag - tar, gzip etc. */
209 str_append_text(p_str
, "_ ");
210 /* Direction of transfer */
211 if (what
== kVSFLogEntryUpload
)
213 str_append_text(p_str
, "i ");
217 str_append_text(p_str
, "o ");
219 /* Access mode: anonymous/real user, and identity */
220 if (p_sess
->is_anonymous
&& !p_sess
->is_guest
)
222 str_append_text(p_str
, "a ");
223 str_append_str(p_str
, &p_sess
->anon_pass_str
);
227 if (p_sess
->is_guest
)
229 str_append_text(p_str
, "g ");
233 str_append_text(p_str
, "r ");
235 str_append_str(p_str
, &p_sess
->user_str
);
237 str_append_char(p_str
, ' ');
238 /* Service name, authentication method, authentication user id */
239 str_append_text(p_str
, "ftp 0 * ");
240 /* Completion status */
243 str_append_char(p_str
, 'c');
247 str_append_char(p_str
, 'i');
252 vsf_log_do_log_vsftpd_format(struct vsf_session
* p_sess
, struct mystr
* p_str
,
253 int succeeded
, enum EVSFLogEntryType what
,
254 const struct mystr
* p_log_str
)
256 /* Date - vsf_sysutil_get_current_date updates cached time */
257 str_alloc_text(p_str
, vsf_sysutil_get_current_date());
259 str_append_text(p_str
, " [pid ");
260 str_append_ulong(p_str
, vsf_sysutil_getpid());
261 str_append_text(p_str
, "] ");
263 if (!str_isempty(&p_sess
->user_str
))
265 str_append_char(p_str
, '[');
266 str_append_str(p_str
, &p_sess
->user_str
);
267 str_append_text(p_str
, "] ");
270 if (what
!= kVSFLogEntryFTPInput
&& what
!= kVSFLogEntryFTPOutput
&&
271 what
!= kVSFLogEntryConnection
&& what
!= kVSFLogEntryDebug
)
275 str_append_text(p_str
, "OK ");
279 str_append_text(p_str
, "FAIL ");
284 case kVSFLogEntryDownload
:
285 str_append_text(p_str
, "DOWNLOAD");
287 case kVSFLogEntryUpload
:
288 str_append_text(p_str
, "UPLOAD");
290 case kVSFLogEntryMkdir
:
291 str_append_text(p_str
, "MKDIR");
293 case kVSFLogEntryLogin
:
294 str_append_text(p_str
, "LOGIN");
296 case kVSFLogEntryFTPInput
:
297 str_append_text(p_str
, "FTP command");
299 case kVSFLogEntryFTPOutput
:
300 str_append_text(p_str
, "FTP response");
302 case kVSFLogEntryConnection
:
303 str_append_text(p_str
, "CONNECT");
305 case kVSFLogEntryDelete
:
306 str_append_text(p_str
, "DELETE");
308 case kVSFLogEntryRename
:
309 str_append_text(p_str
, "RENAME");
311 case kVSFLogEntryRmdir
:
312 str_append_text(p_str
, "RMDIR");
314 case kVSFLogEntryChmod
:
315 str_append_text(p_str
, "CHMOD");
317 case kVSFLogEntryDebug
:
318 str_append_text(p_str
, "DEBUG");
321 bug("bad entry_type in vsf_log_do_log");
324 str_append_text(p_str
, ": Client \"");
325 str_append_str(p_str
, &p_sess
->remote_ip_str
);
326 str_append_char(p_str
, '"');
327 if (what
== kVSFLogEntryLogin
&& !str_isempty(&p_sess
->anon_pass_str
))
329 str_append_text(p_str
, ", anon password \"");
330 str_append_str(p_str
, &p_sess
->anon_pass_str
);
331 str_append_char(p_str
, '"');
333 if (!str_isempty(p_log_str
))
335 str_append_text(p_str
, ", \"");
336 str_append_str(p_str
, p_log_str
);
337 str_append_char(p_str
, '"');
339 if (what
!= kVSFLogEntryFTPInput
&& what
!= kVSFLogEntryFTPOutput
&&
340 what
!= kVSFLogEntryDebug
)
342 if (p_sess
->transfer_size
)
344 str_append_text(p_str
, ", ");
345 str_append_filesize_t(p_str
, p_sess
->transfer_size
);
346 str_append_text(p_str
, " bytes");
348 if (vsf_log_type_is_transfer(what
))
350 long delta_sec
= vsf_sysutil_get_cached_time_sec() -
351 p_sess
->log_start_sec
;
352 long delta_usec
= vsf_sysutil_get_cached_time_usec() -
353 p_sess
->log_start_usec
;
354 double time_delta
= (double) delta_sec
+ ((double) delta_usec
/
362 ((double) p_sess
->transfer_size
/ time_delta
) / (double) 1024;
363 str_append_text(p_str
, ", ");
364 str_append_double(p_str
, kbyte_rate
);
365 str_append_text(p_str
, "Kbyte/sec");