Retired the #ifdef DUMP_PACKETS stuff in ssh.c because I'm utterly
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 14 Dec 2001 14:57:50 +0000 (14:57 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 14 Dec 2001 14:57:50 +0000 (14:57 +0000)
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.

git-svn-id: svn://svn.tartarus.org/sgt/putty@1493 cda61777-01e9-0310-a592-d414129be87e

Makefile
doc/config.but
logging.c [new file with mode: 0644]
plink.c
psftp.c
putty.h
scp.c
ssh.c
terminal.c
windlg.c
window.c

index ea73ed4..38a3c61 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -88,7 +88,7 @@ RES=res
 
 ##-- objects putty puttytel
 GOBJS1 = window.$(OBJ) windlg.$(OBJ) winctrls.$(OBJ) terminal.$(OBJ)
 
 ##-- objects putty puttytel
 GOBJS1 = window.$(OBJ) windlg.$(OBJ) winctrls.$(OBJ) terminal.$(OBJ)
-GOBJS2 = sizetip.$(OBJ) wcwidth.$(OBJ) unicode.$(OBJ)
+GOBJS2 = sizetip.$(OBJ) wcwidth.$(OBJ) unicode.$(OBJ) logging.$(OBJ)
 ##-- objects putty puttytel plink
 LOBJS1 = telnet.$(OBJ) raw.$(OBJ) rlogin.$(OBJ) ldisc.$(OBJ) winnet.$(OBJ)
 ##-- objects putty plink
 ##-- objects putty puttytel plink
 LOBJS1 = telnet.$(OBJ) raw.$(OBJ) rlogin.$(OBJ) ldisc.$(OBJ) winnet.$(OBJ)
 ##-- objects putty plink
@@ -96,13 +96,13 @@ POBJS = be_all.$(OBJ)
 ##-- objects puttytel
 TOBJS = be_nossh.$(OBJ)
 ##-- objects plink
 ##-- objects puttytel
 TOBJS = be_nossh.$(OBJ)
 ##-- objects plink
-PLOBJS = plink.$(OBJ)
+PLOBJS = plink.$(OBJ) logging.$(OBJ)
 ##-- objects pscp
 SOBJS = scp.$(OBJ) winnet.$(OBJ) be_none.$(OBJ) wildcard.$(OBJ)
 ##-- objects psftp
 FOBJS = psftp.$(OBJ) winnet.$(OBJ) be_none.$(OBJ)
 ##-- objects pscp psftp
 ##-- objects pscp
 SOBJS = scp.$(OBJ) winnet.$(OBJ) be_none.$(OBJ) wildcard.$(OBJ)
 ##-- objects psftp
 FOBJS = psftp.$(OBJ) winnet.$(OBJ) be_none.$(OBJ)
 ##-- objects pscp psftp
-SFOBJS = sftp.$(OBJ) int64.$(OBJ)
+SFOBJS = sftp.$(OBJ) int64.$(OBJ) logging.$(OBJ)
 ##-- objects putty puttytel pscp psftp plink
 MOBJS = misc.$(OBJ) version.$(OBJ) winstore.$(OBJ) settings.$(OBJ)
 MOBJ2 = tree234.$(OBJ)
 ##-- objects putty puttytel pscp psftp plink
 MOBJS = misc.$(OBJ) version.$(OBJ) winstore.$(OBJ) settings.$(OBJ)
 MOBJ2 = tree234.$(OBJ)
@@ -321,6 +321,7 @@ sshzlib.$(OBJ): sshzlib.c network.h int64.h puttymem.h ssh.h
 ssl.$(OBJ): ssl.c network.h asnerror.h misc.h cert.h crypto.h ssl.h int64.h puttymem.h 
 telnet.$(OBJ): telnet.c network.h misc.h puttymem.h putty.h 
 terminal.$(OBJ): terminal.c network.h misc.h puttymem.h putty.h tree234.h 
 ssl.$(OBJ): ssl.c network.h asnerror.h misc.h cert.h crypto.h ssl.h int64.h puttymem.h 
 telnet.$(OBJ): telnet.c network.h misc.h puttymem.h putty.h 
 terminal.$(OBJ): terminal.c network.h misc.h puttymem.h putty.h tree234.h 
+logging.$(OBJ): logging.c misc.h puttymem.h putty.h
 test.$(OBJ): test.c network.h int64.h puttymem.h ssh.h 
 tree234.$(OBJ): tree234.c tree234.h 
 unicode.$(OBJ): unicode.c network.h misc.h puttymem.h putty.h 
 test.$(OBJ): test.c network.h int64.h puttymem.h ssh.h 
 tree234.$(OBJ): tree234.c tree234.h 
 unicode.$(OBJ): unicode.c network.h misc.h puttymem.h putty.h 
index 7e08473..2c14f69 100644 (file)
@@ -1,4 +1,4 @@
-\versionid $Id: config.but,v 1.20 2001/12/14 12:48:24 simon Exp $
+\versionid $Id: config.but,v 1.21 2001/12/14 14:57:50 simon Exp $
 
 \C{config} Configuring PuTTY
 
 
 \C{config} Configuring PuTTY
 
@@ -136,6 +136,14 @@ can record everything that went to the terminal, so that someone
 else can replay the session later in slow motion and watch to see
 what went wrong.
 
 else can replay the session later in slow motion and watch to see
 what went wrong.
 
+\b \q{Log SSH packet data}. In this mode (which is only used by SSH
+connections), the SSH message packets sent over the encrypted
+connection are written to the log file. You might need this to debug
+a network-level problem, or more likely to send to the PuTTY authors
+as part of a bug report. \e{BE WARNED} that if you log in using a
+password, the password will appear in the log file, so be sure to
+edit it out before sending the log file to anyone else!
+
 \S{config-logfilename} \q{Log file name}
 
 \cfg{winhelp-topic}{logging.filename}
 \S{config-logfilename} \q{Log file name}
 
 \cfg{winhelp-topic}{logging.filename}
diff --git a/logging.c b/logging.c
new file mode 100644 (file)
index 0000000..3caa94a
--- /dev/null
+++ b/logging.c
@@ -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';
+}
diff --git a/plink.c b/plink.c
index 7023f9d..6c21150 100644 (file)
--- a/plink.c
+++ b/plink.c
@@ -163,6 +163,44 @@ void askcipher(char *ciphername, int cs)
 }
 
 /*
 }
 
 /*
+ * Ask whether to wipe a session log file before writing to it.
+ * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
+ */
+int askappend(char *filename)
+{
+    HANDLE hin;
+    DWORD savemode, i;
+
+    static const char msgtemplate[] =
+       "The session log file \"%.*s\" already exists.\n"
+       "You can overwrite it with a new session log,\n"
+       "append your session log to the end of it,\n"
+       "or disable session logging for this session.\n"
+       "Enter \"y\" to wipe the file, \"n\" to append to it,\n"
+       "or just press Return to disable logging.\n"
+       "Wipe the log file? (y/n, Return cancels logging) ";
+
+    char line[32];
+
+    fprintf(stderr, msgtemplate, FILENAME_MAX, filename);
+    fflush(stderr);
+
+    hin = GetStdHandle(STD_INPUT_HANDLE);
+    GetConsoleMode(hin, &savemode);
+    SetConsoleMode(hin, (savemode | ENABLE_ECHO_INPUT |
+                        ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT));
+    ReadFile(hin, line, sizeof(line) - 1, &i, NULL);
+    SetConsoleMode(hin, savemode);
+
+    if (line[0] == 'y' || line[0] == 'Y')
+       return 2;
+    else if (line[0] == 'n' || line[0] == 'N')
+       return 1;
+    else
+       return 0;
+}
+
+/*
  * Warn about the obsolescent key file format.
  */
 void old_keyfile_warning(void)
  * Warn about the obsolescent key file format.
  */
 void old_keyfile_warning(void)
diff --git a/psftp.c b/psftp.c
index feefbbc..2923e73 100644 (file)
--- a/psftp.c
+++ b/psftp.c
@@ -1456,6 +1456,44 @@ void askcipher(char *ciphername, int cs)
 }
 
 /*
 }
 
 /*
+ * Ask whether to wipe a session log file before writing to it.
+ * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
+ */
+int askappend(char *filename)
+{
+    HANDLE hin;
+    DWORD savemode, i;
+
+    static const char msgtemplate[] =
+       "The session log file \"%.*s\" already exists.\n"
+       "You can overwrite it with a new session log,\n"
+       "append your session log to the end of it,\n"
+       "or disable session logging for this session.\n"
+       "Enter \"y\" to wipe the file, \"n\" to append to it,\n"
+       "or just press Return to disable logging.\n"
+       "Wipe the log file? (y/n, Return cancels logging) ";
+
+    char line[32];
+
+    fprintf(stderr, msgtemplate, FILENAME_MAX, filename);
+    fflush(stderr);
+
+    hin = GetStdHandle(STD_INPUT_HANDLE);
+    GetConsoleMode(hin, &savemode);
+    SetConsoleMode(hin, (savemode | ENABLE_ECHO_INPUT |
+                        ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT));
+    ReadFile(hin, line, sizeof(line) - 1, &i, NULL);
+    SetConsoleMode(hin, savemode);
+
+    if (line[0] == 'y' || line[0] == 'Y')
+       return 2;
+    else if (line[0] == 'n' || line[0] == 'N')
+       return 1;
+    else
+       return 0;
+}
+
+/*
  * Warn about the obsolescent key file format.
  */
 void old_keyfile_warning(void)
  * Warn about the obsolescent key file format.
  */
 void old_keyfile_warning(void)
diff --git a/putty.h b/putty.h
index 4302b84..27a6564 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -130,7 +130,8 @@ GLOBAL unsigned char unitab_ctrl[256];
 #define LGXF_ASK -1                   /* existing logfile ask */
 #define LGTYP_NONE  0                 /* logmode: no logging */
 #define LGTYP_ASCII 1                 /* logmode: pure ascii */
 #define LGXF_ASK -1                   /* existing logfile ask */
 #define LGTYP_NONE  0                 /* logmode: no logging */
 #define LGTYP_ASCII 1                 /* logmode: pure ascii */
-#define LGTYP_DEBUG 2                 /* logmode: all chars of taffic */
+#define LGTYP_DEBUG 2                 /* logmode: all chars of traffic */
+#define LGTYP_PACKETS 3                       /* logmode: SSH data packets */
 GLOBAL char *logfile;
 
 /*
 GLOBAL char *logfile;
 
 /*
@@ -486,6 +487,13 @@ void logfclose(void);
 void term_copyall(void);
 
 /*
 void term_copyall(void);
 
 /*
+ * Exports from logging.c.
+ */
+void logtraffic(unsigned char c, int logmode);
+enum { PKT_INCOMING, PKT_OUTGOING };
+void log_packet(int direction, int type, char *texttype, void *data, int len);
+
+/*
  * Exports from raw.c.
  */
 
  * Exports from raw.c.
  */
 
diff --git a/scp.c b/scp.c
index c40d7cc..45930c0 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -227,6 +227,44 @@ void askcipher(char *ciphername, int cs)
 }
 
 /*
 }
 
 /*
+ * Ask whether to wipe a session log file before writing to it.
+ * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
+ */
+int askappend(char *filename)
+{
+    HANDLE hin;
+    DWORD savemode, i;
+
+    static const char msgtemplate[] =
+       "The session log file \"%.*s\" already exists.\n"
+       "You can overwrite it with a new session log,\n"
+       "append your session log to the end of it,\n"
+       "or disable session logging for this session.\n"
+       "Enter \"y\" to wipe the file, \"n\" to append to it,\n"
+       "or just press Return to disable logging.\n"
+       "Wipe the log file? (y/n, Return cancels logging) ";
+
+    char line[32];
+
+    fprintf(stderr, msgtemplate, FILENAME_MAX, filename);
+    fflush(stderr);
+
+    hin = GetStdHandle(STD_INPUT_HANDLE);
+    GetConsoleMode(hin, &savemode);
+    SetConsoleMode(hin, (savemode | ENABLE_ECHO_INPUT |
+                        ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT));
+    ReadFile(hin, line, sizeof(line) - 1, &i, NULL);
+    SetConsoleMode(hin, savemode);
+
+    if (line[0] == 'y' || line[0] == 'Y')
+       return 2;
+    else if (line[0] == 'n' || line[0] == 'N')
+       return 1;
+    else
+       return 0;
+}
+
+/*
  * Warn about the obsolescent key file format.
  */
 void old_keyfile_warning(void)
  * Warn about the obsolescent key file format.
  */
 void old_keyfile_warning(void)
diff --git a/ssh.c b/ssh.c
index 9f27e3a..bc7f5bf 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -15,9 +15,6 @@
 #define TRUE 1
 #endif
 
 #define TRUE 1
 #endif
 
-/* uncomment this for packet level debugging */
-/* #define DUMP_PACKETS */
-
 #define logevent(s) { logevent(s); \
                       if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) \
                       { fprintf(stderr, "%s\n", s); fflush(stderr); } }
 #define logevent(s) { logevent(s); \
                       if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) \
                       { fprintf(stderr, "%s\n", s); fflush(stderr); } }
 #define SSH2_MSG_CHANNEL_SUCCESS                  99   /* 0x63 */
 #define SSH2_MSG_CHANNEL_FAILURE                  100  /* 0x64 */
 
 #define SSH2_MSG_CHANNEL_SUCCESS                  99   /* 0x63 */
 #define SSH2_MSG_CHANNEL_FAILURE                  100  /* 0x64 */
 
+/*
+ * Packet type contexts, so that ssh2_pkt_type can correctly decode
+ * the ambiguous type numbers back into the correct type strings.
+ */
+#define SSH2_PKTCTX_DHGROUP1         0x0001
+#define SSH2_PKTCTX_DHGEX            0x0002
+#define SSH2_PKTCTX_PUBLICKEY        0x0010
+#define SSH2_PKTCTX_PASSWORD         0x0020
+#define SSH2_PKTCTX_KBDINTER         0x0040
+#define SSH2_PKTCTX_AUTH_MASK        0x00F0
+
 #define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1  /* 0x1 */
 #define SSH2_DISCONNECT_PROTOCOL_ERROR            2    /* 0x2 */
 #define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED       3    /* 0x3 */
 #define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1  /* 0x1 */
 #define SSH2_DISCONNECT_PROTOCOL_ERROR            2    /* 0x2 */
 #define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED       3    /* 0x3 */
@@ -161,6 +169,97 @@ static const char *const ssh2_disconnect_reasons[] = {
 #define BUG_SSH2_HMAC                             2
 #define BUG_NEEDS_SSH1_PLAIN_PASSWORD            4
 
 #define BUG_SSH2_HMAC                             2
 #define BUG_NEEDS_SSH1_PLAIN_PASSWORD            4
 
+static int ssh_pkt_ctx = 0;
+
+#define translate(x) if (type == x) return #x
+#define translatec(x,ctx) if (type == x && (ssh_pkt_ctx & ctx)) return #x
+char *ssh1_pkt_type(int type)
+{
+    translate(SSH1_MSG_DISCONNECT);
+    translate(SSH1_SMSG_PUBLIC_KEY);
+    translate(SSH1_CMSG_SESSION_KEY);
+    translate(SSH1_CMSG_USER);
+    translate(SSH1_CMSG_AUTH_RSA);
+    translate(SSH1_SMSG_AUTH_RSA_CHALLENGE);
+    translate(SSH1_CMSG_AUTH_RSA_RESPONSE);
+    translate(SSH1_CMSG_AUTH_PASSWORD);
+    translate(SSH1_CMSG_REQUEST_PTY);
+    translate(SSH1_CMSG_WINDOW_SIZE);
+    translate(SSH1_CMSG_EXEC_SHELL);
+    translate(SSH1_CMSG_EXEC_CMD);
+    translate(SSH1_SMSG_SUCCESS);
+    translate(SSH1_SMSG_FAILURE);
+    translate(SSH1_CMSG_STDIN_DATA);
+    translate(SSH1_SMSG_STDOUT_DATA);
+    translate(SSH1_SMSG_STDERR_DATA);
+    translate(SSH1_CMSG_EOF);
+    translate(SSH1_SMSG_EXIT_STATUS);
+    translate(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION);
+    translate(SSH1_MSG_CHANNEL_OPEN_FAILURE);
+    translate(SSH1_MSG_CHANNEL_DATA);
+    translate(SSH1_MSG_CHANNEL_CLOSE);
+    translate(SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION);
+    translate(SSH1_SMSG_X11_OPEN);
+    translate(SSH1_CMSG_PORT_FORWARD_REQUEST);
+    translate(SSH1_MSG_PORT_OPEN);
+    translate(SSH1_CMSG_AGENT_REQUEST_FORWARDING);
+    translate(SSH1_SMSG_AGENT_OPEN);
+    translate(SSH1_MSG_IGNORE);
+    translate(SSH1_CMSG_EXIT_CONFIRMATION);
+    translate(SSH1_CMSG_X11_REQUEST_FORWARDING);
+    translate(SSH1_CMSG_AUTH_RHOSTS_RSA);
+    translate(SSH1_MSG_DEBUG);
+    translate(SSH1_CMSG_REQUEST_COMPRESSION);
+    translate(SSH1_CMSG_AUTH_TIS);
+    translate(SSH1_SMSG_AUTH_TIS_CHALLENGE);
+    translate(SSH1_CMSG_AUTH_TIS_RESPONSE);
+    translate(SSH1_CMSG_AUTH_CCARD);
+    translate(SSH1_SMSG_AUTH_CCARD_CHALLENGE);
+    translate(SSH1_CMSG_AUTH_CCARD_RESPONSE);
+    return "unknown";
+}
+char *ssh2_pkt_type(int type)
+{
+    translate(SSH2_MSG_DISCONNECT);
+    translate(SSH2_MSG_IGNORE);
+    translate(SSH2_MSG_UNIMPLEMENTED);
+    translate(SSH2_MSG_DEBUG);
+    translate(SSH2_MSG_SERVICE_REQUEST);
+    translate(SSH2_MSG_SERVICE_ACCEPT);
+    translate(SSH2_MSG_KEXINIT);
+    translate(SSH2_MSG_NEWKEYS);
+    translatec(SSH2_MSG_KEXDH_INIT, SSH2_PKTCTX_DHGROUP1);
+    translatec(SSH2_MSG_KEXDH_REPLY, SSH2_PKTCTX_DHGROUP1);
+    translatec(SSH2_MSG_KEX_DH_GEX_REQUEST, SSH2_PKTCTX_DHGEX);
+    translatec(SSH2_MSG_KEX_DH_GEX_GROUP, SSH2_PKTCTX_DHGEX);
+    translatec(SSH2_MSG_KEX_DH_GEX_INIT, SSH2_PKTCTX_DHGEX);
+    translatec(SSH2_MSG_KEX_DH_GEX_REPLY, SSH2_PKTCTX_DHGEX);
+    translate(SSH2_MSG_USERAUTH_REQUEST);
+    translate(SSH2_MSG_USERAUTH_FAILURE);
+    translate(SSH2_MSG_USERAUTH_SUCCESS);
+    translate(SSH2_MSG_USERAUTH_BANNER);
+    translatec(SSH2_MSG_USERAUTH_PK_OK, SSH2_PKTCTX_PUBLICKEY);
+    translatec(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, SSH2_PKTCTX_PASSWORD);
+    translatec(SSH2_MSG_USERAUTH_INFO_REQUEST, SSH2_PKTCTX_KBDINTER);
+    translatec(SSH2_MSG_USERAUTH_INFO_RESPONSE, SSH2_PKTCTX_KBDINTER);
+    translate(SSH2_MSG_GLOBAL_REQUEST);
+    translate(SSH2_MSG_REQUEST_SUCCESS);
+    translate(SSH2_MSG_REQUEST_FAILURE);
+    translate(SSH2_MSG_CHANNEL_OPEN);
+    translate(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
+    translate(SSH2_MSG_CHANNEL_OPEN_FAILURE);
+    translate(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
+    translate(SSH2_MSG_CHANNEL_DATA);
+    translate(SSH2_MSG_CHANNEL_EXTENDED_DATA);
+    translate(SSH2_MSG_CHANNEL_EOF);
+    translate(SSH2_MSG_CHANNEL_CLOSE);
+    translate(SSH2_MSG_CHANNEL_REQUEST);
+    translate(SSH2_MSG_CHANNEL_SUCCESS);
+    translate(SSH2_MSG_CHANNEL_FAILURE);
+    return "unknown";
+}
+#undef translate
+#undef translatec
 
 #define GET_32BIT(cp) \
     (((unsigned long)(unsigned char)(cp)[0] << 24) | \
 
 #define GET_32BIT(cp) \
     (((unsigned long)(unsigned char)(cp)[0] << 24) | \
@@ -626,10 +725,6 @@ static int ssh1_rdpkt(unsigned char **data, int *datalen)
 
     if (cipher)
        cipher->decrypt(pktin.data, st->biglen);
 
     if (cipher)
        cipher->decrypt(pktin.data, st->biglen);
-#ifdef DUMP_PACKETS
-    debug(("Got packet len=%d pad=%d\n", st->len, st->pad));
-    dmemdump(pktin.data, st->biglen);
-#endif
 
     st->realcrc = crc32(pktin.data, st->biglen - 4);
     st->gotcrc = GET_32BIT(pktin.data + st->biglen - 4);
 
     st->realcrc = crc32(pktin.data, st->biglen - 4);
     st->gotcrc = GET_32BIT(pktin.data + st->biglen - 4);
@@ -643,10 +738,6 @@ static int ssh1_rdpkt(unsigned char **data, int *datalen)
     if (ssh1_compressing) {
        unsigned char *decompblk;
        int decomplen;
     if (ssh1_compressing) {
        unsigned char *decompblk;
        int decomplen;
-#ifdef DUMP_PACKETS
-       debug(("Packet payload pre-decompression:\n"));
-       dmemdump(pktin.body - 1, pktin.length + 1);
-#endif
        zlib_decompress_block(pktin.body - 1, pktin.length + 1,
                              &decompblk, &decomplen);
 
        zlib_decompress_block(pktin.body - 1, pktin.length + 1,
                              &decompblk, &decomplen);
 
@@ -661,12 +752,13 @@ static int ssh1_rdpkt(unsigned char **data, int *datalen)
        memcpy(pktin.body - 1, decompblk, decomplen);
        sfree(decompblk);
        pktin.length = decomplen - 1;
        memcpy(pktin.body - 1, decompblk, decomplen);
        sfree(decompblk);
        pktin.length = decomplen - 1;
-#ifdef DUMP_PACKETS
-       debug(("Packet payload post-decompression:\n"));
-       dmemdump(pktin.body - 1, pktin.length + 1);
-#endif
     }
 
     }
 
+    pktin.type = pktin.body[-1];
+
+    log_packet(PKT_INCOMING, pktin.type, ssh1_pkt_type(pktin.type),
+              pktin.body, pktin.length);
+
     if (pktin.type == SSH1_SMSG_STDOUT_DATA ||
        pktin.type == SSH1_SMSG_STDERR_DATA ||
        pktin.type == SSH1_MSG_DEBUG ||
     if (pktin.type == SSH1_SMSG_STDOUT_DATA ||
        pktin.type == SSH1_SMSG_STDERR_DATA ||
        pktin.type == SSH1_MSG_DEBUG ||
@@ -679,8 +771,6 @@ static int ssh1_rdpkt(unsigned char **data, int *datalen)
        }
     }
 
        }
     }
 
-    pktin.type = pktin.body[-1];
-
     if (pktin.type == SSH1_MSG_DEBUG) {
        /* log debug message */
        char buf[80];
     if (pktin.type == SSH1_MSG_DEBUG) {
        /* log debug message */
        char buf[80];
@@ -807,11 +897,6 @@ static int ssh2_rdpkt(unsigned char **data, int *datalen)
        sccipher->decrypt(pktin.data + st->cipherblk,
                          st->packetlen - st->cipherblk);
 
        sccipher->decrypt(pktin.data + st->cipherblk,
                          st->packetlen - st->cipherblk);
 
-#ifdef DUMP_PACKETS
-    debug(("Got packet len=%d pad=%d\n", st->len, st->pad));
-    dmemdump(pktin.data, st->packetlen);
-#endif
-
     /*
      * Check the MAC.
      */
     /*
      * Check the MAC.
      */
@@ -844,11 +929,6 @@ static int ssh2_rdpkt(unsigned char **data, int *datalen)
            }
            pktin.length = 5 + newlen;
            memcpy(pktin.data + 5, newpayload, newlen);
            }
            pktin.length = 5 + newlen;
            memcpy(pktin.data + 5, newpayload, newlen);
-#ifdef DUMP_PACKETS
-           debug(("Post-decompression payload:\n"));
-           dmemdump(pktin.data + 5, newlen);
-#endif
-
            sfree(newpayload);
        }
     }
            sfree(newpayload);
        }
     }
@@ -856,6 +936,9 @@ static int ssh2_rdpkt(unsigned char **data, int *datalen)
     pktin.savedpos = 6;
     pktin.type = pktin.data[5];
 
     pktin.savedpos = 6;
     pktin.type = pktin.data[5];
 
+    log_packet(PKT_INCOMING, pktin.type, ssh2_pkt_type(pktin.type),
+              pktin.data+6, pktin.length-6);
+
     if (pktin.type == SSH2_MSG_IGNORE || pktin.type == SSH2_MSG_DEBUG)
        goto next_packet;              /* FIXME: print DEBUG message */
 
     if (pktin.type == SSH2_MSG_IGNORE || pktin.type == SSH2_MSG_DEBUG)
        goto next_packet;              /* FIXME: print DEBUG message */
 
@@ -930,13 +1013,12 @@ static int s_wrpkt_prepare(void)
 
     pktout.body[-1] = pktout.type;
 
 
     pktout.body[-1] = pktout.type;
 
+    log_packet(PKT_OUTGOING, pktout.type, ssh1_pkt_type(pktout.type),
+              pktout.body, pktout.length);
+
     if (ssh1_compressing) {
        unsigned char *compblk;
        int complen;
     if (ssh1_compressing) {
        unsigned char *compblk;
        int complen;
-#ifdef DUMP_PACKETS
-       debug(("Packet payload pre-compression:\n"));
-       dmemdump(pktout.body - 1, pktout.length + 1);
-#endif
        zlib_compress_block(pktout.body - 1, pktout.length + 1,
                            &compblk, &complen);
        ssh1_pktout_size(complen - 1);
        zlib_compress_block(pktout.body - 1, pktout.length + 1,
                            &compblk, &complen);
        ssh1_pktout_size(complen - 1);
@@ -954,10 +1036,6 @@ static int s_wrpkt_prepare(void)
     PUT_32BIT(pktout.data + biglen, crc);
     PUT_32BIT(pktout.data, len);
 
     PUT_32BIT(pktout.data + biglen, crc);
     PUT_32BIT(pktout.data, len);
 
-#ifdef DUMP_PACKETS
-    debug(("Sending packet len=%d\n", biglen + 4));
-    dmemdump(pktout.data, biglen + 4);
-#endif
     if (cipher)
        cipher->encrypt(pktout.data + 4, biglen);
 
     if (cipher)
        cipher->encrypt(pktout.data + 4, biglen);
 
@@ -1221,18 +1299,15 @@ static int ssh2_pkt_construct(void)
     int cipherblk, maclen, padding, i;
     static unsigned long outgoing_sequence = 0;
 
     int cipherblk, maclen, padding, i;
     static unsigned long outgoing_sequence = 0;
 
+    log_packet(PKT_OUTGOING, pktout.data[5], ssh2_pkt_type(pktout.data[5]),
+              pktout.data + 6, pktout.length - 6);
+
     /*
      * Compress packet payload.
      */
     {
        unsigned char *newpayload;
        int newlen;
     /*
      * Compress packet payload.
      */
     {
        unsigned char *newpayload;
        int newlen;
-#ifdef DUMP_PACKETS
-       if (cscomp && cscomp != &ssh_comp_none) {
-           debug(("Pre-compression payload:\n"));
-           dmemdump(pktout.data + 5, pktout.length - 5);
-       }
-#endif
        if (cscomp && cscomp->compress(pktout.data + 5, pktout.length - 5,
                                       &newpayload, &newlen)) {
            pktout.length = 5;
        if (cscomp && cscomp->compress(pktout.data + 5, pktout.length - 5,
                                       &newpayload, &newlen)) {
            pktout.length = 5;
@@ -1261,11 +1336,6 @@ static int ssh2_pkt_construct(void)
                        outgoing_sequence);
     outgoing_sequence++;              /* whether or not we MACed */
 
                        outgoing_sequence);
     outgoing_sequence++;              /* whether or not we MACed */
 
-#ifdef DUMP_PACKETS
-    debug(("Sending packet len=%d\n", pktout.length + padding));
-    dmemdump(pktout.data, pktout.length + padding);
-#endif
-
     if (cscipher)
        cscipher->encrypt(pktout.data, pktout.length + padding);
 
     if (cscipher)
        cscipher->encrypt(pktout.data, pktout.length + padding);
 
@@ -3435,6 +3505,7 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
      */
     if (kex == &ssh_diffiehellman_gex) {
        logevent("Doing Diffie-Hellman group exchange");
      */
     if (kex == &ssh_diffiehellman_gex) {
        logevent("Doing Diffie-Hellman group exchange");
+       ssh_pkt_ctx |= SSH2_PKTCTX_DHGEX;
        /*
         * Work out how big a DH group we will need to allow that
         * much data.
        /*
         * Work out how big a DH group we will need to allow that
         * much data.
@@ -3455,6 +3526,7 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
        kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
        kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
     } else {
        kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
        kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
     } else {
+       ssh_pkt_ctx |= SSH2_PKTCTX_DHGROUP1;
        dh_setup_group1();
        kex_init_value = SSH2_MSG_KEXDH_INIT;
        kex_reply_value = SSH2_MSG_KEXDH_REPLY;
        dh_setup_group1();
        kex_init_value = SSH2_MSG_KEXDH_INIT;
        kex_reply_value = SSH2_MSG_KEXDH_REPLY;
@@ -3798,6 +3870,8 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
         * just in case it succeeds, and (b) so that we know what
         * authentication methods we can usefully try next.
         */
         * just in case it succeeds, and (b) so that we know what
         * authentication methods we can usefully try next.
         */
+       ssh_pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
+
        ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
        ssh2_pkt_addstring(username);
        ssh2_pkt_addstring("ssh-connection");   /* service requested */
        ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
        ssh2_pkt_addstring(username);
        ssh2_pkt_addstring("ssh-connection");   /* service requested */
@@ -3919,6 +3993,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
            }
 
            method = 0;
            }
 
            method = 0;
+           ssh_pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
 
            if (!method && can_pubkey && agent_exists() && !tried_agent) {
                /*
 
            if (!method && can_pubkey && agent_exists() && !tried_agent) {
                /*
@@ -3930,6 +4005,8 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
                static int authed = FALSE;
                void *r;
 
                static int authed = FALSE;
                void *r;
 
+               ssh_pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
+
                tried_agent = TRUE;
 
                logevent("Pageant is running. Requesting keys.");
                tried_agent = TRUE;
 
                logevent("Pageant is running. Requesting keys.");
@@ -4066,6 +4143,8 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
 
                tried_pubkey_config = TRUE;
 
 
                tried_pubkey_config = TRUE;
 
+               ssh_pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
+
                /*
                 * Try the public key supplied in the configuration.
                 *
                /*
                 * Try the public key supplied in the configuration.
                 *
@@ -4118,6 +4197,8 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
                type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
                tried_keyb_inter = TRUE;
 
                type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
                tried_keyb_inter = TRUE;
 
+               ssh_pkt_ctx |= SSH2_PKTCTX_KBDINTER;
+
                ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
                ssh2_pkt_addstring(username);
                ssh2_pkt_addstring("ssh-connection");   /* service requested */
                ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
                ssh2_pkt_addstring(username);
                ssh2_pkt_addstring("ssh-connection");   /* service requested */
@@ -4143,6 +4224,8 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
                type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
                tried_keyb_inter = TRUE;
 
                type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
                tried_keyb_inter = TRUE;
 
+               ssh_pkt_ctx |= SSH2_PKTCTX_KBDINTER;
+
                /* We've got packet with that "interactive" info
                   dump banners, and set its prompt as ours */
                {
                /* We've got packet with that "interactive" info
                   dump banners, and set its prompt as ours */
                {
@@ -4169,6 +4252,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
 
            if (!method && can_passwd) {
                method = AUTH_PASSWORD;
 
            if (!method && can_passwd) {
                method = AUTH_PASSWORD;
+               ssh_pkt_ctx |= SSH2_PKTCTX_PASSWORD;
                sprintf(pwprompt, "%.90s@%.90s's password: ", username,
                        savedhost);
                need_pw = TRUE;
                sprintf(pwprompt, "%.90s@%.90s's password: ", username,
                        savedhost);
                need_pw = TRUE;
index 77bb390..2962b0a 100644 (file)
@@ -206,10 +206,6 @@ static void erase_lots(int, int, int);
 static void swap_screen(int);
 static void update_sbar(void);
 static void deselect(void);
 static void swap_screen(int);
 static void update_sbar(void);
 static void deselect(void);
-/* log session to file stuff ... */
-static FILE *lgfp = NULL;
-static void logtraffic(unsigned char c, int logmode);
-static void xlatlognam(char *d, char *s, char *hostname, struct tm *tm);
 
 /*
  * Resize a line to make it `cols' columns wide.
 
 /*
  * Resize a line to make it `cols' columns wide.
@@ -3630,138 +3626,3 @@ int from_backend(int is_stderr, char *data, int len)
      */
     return 0;
 }
      */
     return 0;
 }
-
-/*
- * 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);
-       }
-    }
-}
-
-void settimstr(char *ta, int no_sec);
-char *subslfcode(char *dest, char *src, char *dstrt);
-char *stpncpy(char *dst, const char *src, size_t maxlen);
-char timdatbuf[20];
-char currlogfilename[FILENAME_MAX];
-
-/* 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';
-}
index 9da0225..c3f13b7 100644 (file)
--- a/windlg.c
+++ b/windlg.c
@@ -257,6 +257,7 @@ enum { IDCX_ABOUT =
     IDC_LSTATOFF,
     IDC_LSTATASCII,
     IDC_LSTATRAW,
     IDC_LSTATOFF,
     IDC_LSTATASCII,
     IDC_LSTATRAW,
+    IDC_LSTATPACKET,
     IDC_LGFSTATIC,
     IDC_LGFEDIT,
     IDC_LGFBUTTON,
     IDC_LGFSTATIC,
     IDC_LGFEDIT,
     IDC_LGFBUTTON,
@@ -621,6 +622,7 @@ char *help_context_cmd(int id)
       case IDC_LSTATOFF:
       case IDC_LSTATASCII:
       case IDC_LSTATRAW:
       case IDC_LSTATOFF:
       case IDC_LSTATASCII:
       case IDC_LSTATRAW:
+      case IDC_LSTATPACKET:
         return "JI(`',`logging.main')";
       case IDC_LGFSTATIC:
       case IDC_LGFEDIT:
         return "JI(`',`logging.main')";
       case IDC_LGFSTATIC:
       case IDC_LGFEDIT:
@@ -1032,9 +1034,11 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
     SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
     SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
     SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
     SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
     SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
     SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
-    CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
-                    cfg.logtype == 0 ? IDC_LSTATOFF :
-                    cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
+    CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATPACKET,
+                    cfg.logtype == LGTYP_NONE ? IDC_LSTATOFF :
+                    cfg.logtype == LGTYP_ASCII ? IDC_LSTATASCII :
+                    cfg.logtype == LGTYP_DEBUG ? IDC_LSTATRAW :
+                    IDC_LSTATPACKET);
     CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
                     cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
                     cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
     CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
                     cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
                     cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
@@ -1254,7 +1258,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
     }
 
     if (panel == loggingpanelstart) {
     }
 
     if (panel == loggingpanelstart) {
-       /* The Logging panel. Accelerators used: [acgo] tplfwe */
+       /* The Logging panel. Accelerators used: [acgo] tplsfwe */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Options controlling session logging",
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Options controlling session logging",
@@ -1264,7 +1268,9 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
                 "Session logging:", IDC_LSTATSTATIC,
                 "Logging &turned off completely", IDC_LSTATOFF,
                 "Log &printable output only", IDC_LSTATASCII,
                 "Session logging:", IDC_LSTATSTATIC,
                 "Logging &turned off completely", IDC_LSTATOFF,
                 "Log &printable output only", IDC_LSTATASCII,
-                "&Log all session output", IDC_LSTATRAW, NULL);
+                "&Log all session output", IDC_LSTATRAW,
+                "Log &SSH packet data", IDC_LSTATPACKET,
+                NULL);
        editbutton(&cp, "Log &file name:",
                   IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
                   IDC_LGFBUTTON);
        editbutton(&cp, "Log &file name:",
                   IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
                   IDC_LGFBUTTON);
@@ -2608,14 +2614,17 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
              case IDC_LSTATOFF:
              case IDC_LSTATASCII:
              case IDC_LSTATRAW:
              case IDC_LSTATOFF:
              case IDC_LSTATASCII:
              case IDC_LSTATRAW:
+             case IDC_LSTATPACKET:
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED) {
                    if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED) {
                    if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
-                       cfg.logtype = 0;
+                       cfg.logtype = LGTYP_NONE;
                    if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
                    if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
-                       cfg.logtype = 1;
+                       cfg.logtype = LGTYP_ASCII;
                    if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
                    if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
-                       cfg.logtype = 2;
+                       cfg.logtype = LGTYP_DEBUG;
+                   if (IsDlgButtonChecked(hwnd, IDC_LSTATPACKET))
+                       cfg.logtype = LGTYP_PACKETS;
                }
                break;
              case IDC_LSTATXASK:
                }
                break;
              case IDC_LSTATXASK:
index 52af23e..54665c9 100644 (file)
--- a/window.c
+++ b/window.c
@@ -633,15 +633,15 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
     set_input_locale(GetKeyboardLayout(0));
 
     /*
     set_input_locale(GetKeyboardLayout(0));
 
     /*
-     * Finally show the window!
+     * Open the initial log file if there is one.
      */
      */
-    ShowWindow(hwnd, show);
-    SetForegroundWindow(hwnd);
+    logfopen();
 
     /*
 
     /*
-     * Open the initial log file if there is one.
+     * Finally show the window!
      */
      */
-    logfopen();
+    ShowWindow(hwnd, show);
+    SetForegroundWindow(hwnd);
 
     /*
      * Set the palette up.
 
     /*
      * Set the palette up.