rendered paste bodysbserver8:/home/chester/openssh-4.2p1 # more script.c
#include "includes.h"
#include "log.h"
#include "script.h"
/*
* Log tty output in script format with additional timing information.
* Log file timing format:
* ss.hh cc
* Where:
* ss: seconds since Jan 1, 1970.
* hh: hundredths of seconds
* cc: character count
* Inspired by http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=68556
*/
#define SCRIPTDIR "/var/log/openssh"
#define LOG_IMMEDIATE
static FILE *scriptfd = NULL;
static FILE *timingfd = NULL;
static long int oldseconds = 0, oldhundredthsofseconds = 0, charcount = 0;
void
script_open(char *username)
{
time_t tvec;
char fname[FILENAME_MAX + 1];
char logname[FILENAME_MAX + 1];
u_int32_t rnd;
struct stat st;
int oldmask;
if (username == NULL) {
username = "Error";
}
/*
* Create log directory if necessary
*/
if (stat(SCRIPTDIR, &st) < 0) {
if (mkdir(SCRIPTDIR, 0700) < 0)
error("Could not create directory '%s'.", SCRIPTDIR);
}
/*
* Create unique filename
*/
if ((tvec = time(NULL)) == -1) {
fatal("%s", strerror(errno));
}
strftime(logname, sizeof(logname), "%F.%T", gmtime(&tvec));
rnd = arc4random();
oldmask = umask(077);
snprintf(fname, sizeof(fname), "%s/openssh.%s.%s.%08x.typescript", SCRIPTDIR, logname,
username, rnd);
if ((scriptfd = fopen(fname, "a")) == NULL) {
error("Could not create script file '%s': %s", fname, strerror(errno));
umask(oldmask);
return;
}
fprintf(scriptfd, "Script started on %s\n", ctime(&tvec));
snprintf(fname, sizeof(fname), "%s/openssh.%s.%s.%08x.timing", SCRIPTDIR, logname,
username, rnd);
if ((timingfd = fopen(fname, "a")) == NULL) {
error("Could not create timing file '%s': %s", fname, strerror(errno));
umask(oldmask);
return;
}
umask(oldmask);
#ifdef LOG_IMMEDIATE
/*
* Even if sshd crashes or is killed, we still have logs
*/
setvbuf(scriptfd, NULL, _IONBF, 0);
setvbuf(timingfd, NULL, _IONBF, 0);
#endif
}
void
script_close()
{
time_t tvec;
if (scriptfd != NULL) {
if ((tvec = time(NULL)) != -1) {
fprintf(scriptfd, "Script ended on %s\n", ctime(&tvec));
}
fclose(scriptfd);
scriptfd = NULL;
}
if (timingfd != NULL) {
if (charcount != 0) {
fprintf(timingfd, "%li.%02li %li\n", oldseconds,
oldhundredthsofseconds, charcount);
}
fclose(timingfd);
timingfd = NULL;
}
}
/*
* Log string 'buf' of length 'len'
*/
void
script(char *buf, int len)
{
struct timeval tv;
long int seconds;
long int hundredthsofseconds;
if ((buf != NULL) && (len > 0)) {
/*
* .timing file: timestamp and character count
*/
if (timingfd != NULL) {
if ((gettimeofday(&tv, NULL)) == -1) {
fatal("%s", strerror(errno));
}
seconds = tv.tv_sec;
hundredthsofseconds = tv.tv_usec / 10000;
if ((seconds == oldseconds)
&& (hundredthsofseconds == oldhundredthsofseconds)) {
charcount += len;
} else {
if (charcount != 0) {
fprintf(timingfd, "%li.%02li %li\n", oldseconds,
oldhundredthsofseconds, charcount);
}
oldseconds = seconds;
oldhundredthsofseconds = hundredthsofseconds;
charcount = len;
}
}
/*
* .typescript file: string
*/
if (scriptfd != NULL) {
fwrite(buf, 1, len, scriptfd);
}
}
}
/* not truncated */
sbserver8:/home/chester/openssh-4.2p1 #