This patch adds an xferlog to openssh 5.1pl1 Linux with the total numbers of bytes transferred during each session. Dirty + Evil! --- sshd.c 2009-01-21 13:15:30.000000000 +0100 +++ sshd.c.xferlog 2009-01-21 13:18:41.000000000 +0100 @@ -257,6 +257,51 @@ static void do_ssh1_kex(void); static void do_ssh2_kex(void); +/* start xferlog patch */ +static int xferlogfd = -1; +static unsigned int xferstart = 0; + +static void xferlog_init() { + char buf[1024] = {'\0'}; + + xferstart = (int)time(NULL); + + xferlogfd = open("/var/log/xferlog", O_CREAT|O_APPEND|O_WRONLY, 0640); + if (xferlogfd == -1) { + verbose("Failed to open xferlog"); + strerror_r(errno, buf, strlen(buf)); + perror(buf); + } +} + +static void xferlog_finish(u_int64_t inbytes, u_int64_t outbytes, const char *remote_ip, char *username) { + char buf[1024] = {'\0'}; + char tbuf[128] = {'\0'}; + time_t now; + const struct tm *tm; + int sz = 0; + int xferdur = 0; + + if (xferlogfd != -1) { + time(&now); + tm = localtime(&now); + xferdur = (int)time(NULL) - xferstart; + + sz = strftime(tbuf, sizeof(tbuf), "%a %b %d %H:%M:%S %Y", tm); + if (sz == 0) tbuf[0] = '\0'; + snprintf(buf, sizeof(buf), "%s %d %.500s %llu - - - - - %s ssh - - -\n", + tbuf, xferdur, remote_ip, (inbytes + outbytes), username ); + write(xferlogfd, buf, strlen(buf)); + close (xferlogfd); + } else { + verbose("Failed to write xferlog"); + strerror_r(errno, buf, strlen(buf)); + perror(buf); + } +} + +/* end xferlog patch */ + /* * Close all listening sockets */ @@ -1902,6 +1947,9 @@ } #endif + /* open xferlog */ + xferlog_init(); + /* * In privilege separation, we fork another child and prepare * file descriptor passing. @@ -1924,6 +1972,9 @@ packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); verbose("Transferred: sent %llu, received %llu bytes", obytes, ibytes); + /* write + close xferlog */ + xferlog_finish(ibytes, obytes, remote_ip, authctxt->user); + verbose("Closing connection to %.500s port %d", remote_ip, remote_port); #ifdef USE_PAM