sbserver8:/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 #