mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-05 21:42:47 -05:00
Retired the #ifdef DUMP_PACKETS stuff in ssh.c because I'm utterly
sick of recompiling to enable packet dumps. SSH packet dumping is now provided as a logging option, and dumps to putty.log like all the other logging options. While I'm at it I cleaned up the format so that packet types are translated into strings for easy browsing. POSSIBLE SIDE EFFECT: in the course of this work I had to re-enable the SSH1 packet length checks which it turns out hadn't actually been active for some time, so it's possible things might break as a result. If need be I can always disable those checks for the 0.52 release and think about it more carefully later. [originally from svn r1493]
This commit is contained in:
177
logging.c
Normal file
177
logging.c
Normal file
@ -0,0 +1,177 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "putty.h"
|
||||
|
||||
/* log session to file stuff ... */
|
||||
static FILE *lgfp = NULL;
|
||||
static char timdatbuf[20];
|
||||
static char currlogfilename[FILENAME_MAX];
|
||||
|
||||
static void xlatlognam(char *d, char *s, char *hostname, struct tm *tm);
|
||||
|
||||
/*
|
||||
* Log session traffic.
|
||||
*/
|
||||
void logtraffic(unsigned char c, int logmode)
|
||||
{
|
||||
if (cfg.logtype > 0) {
|
||||
if (cfg.logtype == logmode) {
|
||||
/* deferred open file from pgm start? */
|
||||
if (!lgfp)
|
||||
logfopen();
|
||||
if (lgfp)
|
||||
fputc(c, lgfp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Log an SSH packet.
|
||||
*/
|
||||
void log_packet(int direction, int type, char *texttype, void *data, int len)
|
||||
{
|
||||
int i, j, c;
|
||||
char dumpdata[80], smalldata[5];
|
||||
|
||||
if (cfg.logtype != LGTYP_PACKETS)
|
||||
return;
|
||||
if (!lgfp)
|
||||
logfopen();
|
||||
if (lgfp) {
|
||||
fprintf(lgfp, "%s packet type %d / 0x%02x (%s)\n",
|
||||
direction == PKT_INCOMING ? "Incoming" : "Outgoing",
|
||||
type, type, texttype);
|
||||
for (i = 0; i < len; i += 16) {
|
||||
sprintf(dumpdata, " %08x%*s\n", i, 1+3*16+2+16, "");
|
||||
for (j = 0; j < 16 && i+j < len; j++) {
|
||||
int c = ((unsigned char *)data)[i+j];
|
||||
sprintf(smalldata, "%02x", c);
|
||||
dumpdata[10+2+3*j] = smalldata[0];
|
||||
dumpdata[10+2+3*j+1] = smalldata[1];
|
||||
dumpdata[10+1+3*16+2+j] = (isprint(c) ? c : '.');
|
||||
}
|
||||
strcpy(dumpdata + 10+1+3*16+2+j, "\n");
|
||||
fputs(dumpdata, lgfp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* open log file append/overwrite mode */
|
||||
void logfopen(void)
|
||||
{
|
||||
char buf[256];
|
||||
time_t t;
|
||||
struct tm tm;
|
||||
char writemod[4];
|
||||
|
||||
if (!cfg.logtype)
|
||||
return;
|
||||
sprintf(writemod, "wb"); /* default to rewrite */
|
||||
|
||||
time(&t);
|
||||
tm = *localtime(&t);
|
||||
|
||||
/* substitute special codes in file name */
|
||||
xlatlognam(currlogfilename,cfg.logfilename,cfg.host, &tm);
|
||||
|
||||
lgfp = fopen(currlogfilename, "r"); /* file already present? */
|
||||
if (lgfp) {
|
||||
int i;
|
||||
fclose(lgfp);
|
||||
i = askappend(currlogfilename);
|
||||
if (i == 1)
|
||||
writemod[0] = 'a'; /* set append mode */
|
||||
else if (i == 0) { /* cancelled */
|
||||
lgfp = NULL;
|
||||
cfg.logtype = 0; /* disable logging */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lgfp = fopen(currlogfilename, writemod);
|
||||
if (lgfp) { /* enter into event log */
|
||||
sprintf(buf, "%s session log (%s mode) to file : ",
|
||||
(writemod[0] == 'a') ? "Appending" : "Writing new",
|
||||
(cfg.logtype == LGTYP_ASCII ? "ASCII" :
|
||||
cfg.logtype == LGTYP_DEBUG ? "raw" : "<ukwn>"));
|
||||
/* Make sure we do not exceed the output buffer size */
|
||||
strncat(buf, currlogfilename, 128);
|
||||
buf[strlen(buf)] = '\0';
|
||||
logevent(buf);
|
||||
|
||||
/* --- write header line into log file */
|
||||
fputs("=~=~=~=~=~=~=~=~=~=~=~= PuTTY log ", lgfp);
|
||||
strftime(buf, 24, "%Y.%m.%d %H:%M:%S", &tm);
|
||||
fputs(buf, lgfp);
|
||||
fputs(" =~=~=~=~=~=~=~=~=~=~=~=\r\n", lgfp);
|
||||
}
|
||||
}
|
||||
|
||||
void logfclose(void)
|
||||
{
|
||||
if (lgfp) {
|
||||
fclose(lgfp);
|
||||
lgfp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* translate format codes into time/date strings
|
||||
* and insert them into log file name
|
||||
*
|
||||
* "&Y":YYYY "&m":MM "&d":DD "&T":hhmm "&h":<hostname> "&&":&
|
||||
*/
|
||||
static void xlatlognam(char *d, char *s, char *hostname, struct tm *tm) {
|
||||
char buf[10], *bufp;
|
||||
int size;
|
||||
char *ds = d; /* save start pos. */
|
||||
int len = FILENAME_MAX-1;
|
||||
|
||||
while (*s) {
|
||||
/* Let (bufp, len) be the string to append. */
|
||||
bufp = buf; /* don't usually override this */
|
||||
if (*s == '&') {
|
||||
char c;
|
||||
s++;
|
||||
if (*s) switch (c = *s++, tolower(c)) {
|
||||
case 'y':
|
||||
size = strftime(buf, sizeof(buf), "%Y", tm);
|
||||
break;
|
||||
case 'm':
|
||||
size = strftime(buf, sizeof(buf), "%m", tm);
|
||||
break;
|
||||
case 'd':
|
||||
size = strftime(buf, sizeof(buf), "%d", tm);
|
||||
break;
|
||||
case 't':
|
||||
size = strftime(buf, sizeof(buf), "%H%M%S", tm);
|
||||
break;
|
||||
case 'h':
|
||||
bufp = hostname;
|
||||
size = strlen(bufp);
|
||||
break;
|
||||
default:
|
||||
buf[0] = '&';
|
||||
size = 1;
|
||||
if (c != '&')
|
||||
buf[size++] = c;
|
||||
}
|
||||
} else {
|
||||
buf[0] = *s++;
|
||||
size = 1;
|
||||
}
|
||||
if (size > len)
|
||||
size = len;
|
||||
memcpy(d, bufp, size);
|
||||
d += size;
|
||||
len -= size;
|
||||
}
|
||||
*d = '\0';
|
||||
}
|
Reference in New Issue
Block a user