1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00: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:
Simon Tatham 2001-12-14 14:57:50 +00:00
parent 789bb1e727
commit 3ed0d44f16
11 changed files with 465 additions and 203 deletions

View File

@ -88,7 +88,7 @@ RES=res
##-- 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
@ -96,13 +96,13 @@ POBJS = be_all.$(OBJ)
##-- 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
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)
@ -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
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

View 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
@ -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.
\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}

177
logging.c Normal file
View 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';
}

38
plink.c
View File

@ -162,6 +162,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.
*/

38
psftp.c
View File

@ -1455,6 +1455,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.
*/

10
putty.h
View File

@ -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 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;
/*
@ -485,6 +486,13 @@ void logfopen(void);
void logfclose(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.
*/

38
scp.c
View File

@ -226,6 +226,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.
*/

176
ssh.c
View File

@ -15,9 +15,6 @@
#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); } }
@ -112,6 +109,17 @@
#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 */
@ -161,6 +169,97 @@ static const char *const ssh2_disconnect_reasons[] = {
#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) | \
@ -626,10 +725,6 @@ static int ssh1_rdpkt(unsigned char **data, int *datalen)
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);
@ -643,10 +738,6 @@ static int ssh1_rdpkt(unsigned char **data, int *datalen)
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);
@ -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;
#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 ||
@ -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];
@ -807,11 +897,6 @@ static int ssh2_rdpkt(unsigned char **data, int *datalen)
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.
*/
@ -844,11 +929,6 @@ static int ssh2_rdpkt(unsigned char **data, int *datalen)
}
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);
}
}
@ -856,6 +936,9 @@ static int ssh2_rdpkt(unsigned char **data, int *datalen)
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 */
@ -930,13 +1013,12 @@ static int s_wrpkt_prepare(void)
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;
#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);
@ -954,10 +1036,6 @@ static int s_wrpkt_prepare(void)
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);
@ -1221,18 +1299,15 @@ static int ssh2_pkt_construct(void)
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;
#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;
@ -1261,11 +1336,6 @@ static int ssh2_pkt_construct(void)
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);
@ -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");
ssh_pkt_ctx |= SSH2_PKTCTX_DHGEX;
/*
* 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 {
ssh_pkt_ctx |= SSH2_PKTCTX_DHGROUP1;
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.
*/
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 */
@ -3919,6 +3993,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
}
method = 0;
ssh_pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
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;
ssh_pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
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;
ssh_pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
/*
* 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;
ssh_pkt_ctx |= SSH2_PKTCTX_KBDINTER;
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;
ssh_pkt_ctx |= SSH2_PKTCTX_KBDINTER;
/* 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;
ssh_pkt_ctx |= SSH2_PKTCTX_PASSWORD;
sprintf(pwprompt, "%.90s@%.90s's password: ", username,
savedhost);
need_pw = TRUE;

View 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);
/* 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.
@ -3630,138 +3626,3 @@ int from_backend(int is_stderr, char *data, int len)
*/
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';
}

View File

@ -257,6 +257,7 @@ enum { IDCX_ABOUT =
IDC_LSTATOFF,
IDC_LSTATASCII,
IDC_LSTATRAW,
IDC_LSTATPACKET,
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_LSTATPACKET:
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);
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 :
@ -1254,7 +1258,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
}
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",
@ -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,
"&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);
@ -2608,14 +2614,17 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
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))
cfg.logtype = 0;
cfg.logtype = LGTYP_NONE;
if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
cfg.logtype = 1;
cfg.logtype = LGTYP_ASCII;
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:

View File

@ -632,17 +632,17 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
*/
set_input_locale(GetKeyboardLayout(0));
/*
* Open the initial log file if there is one.
*/
logfopen();
/*
* Finally show the window!
*/
ShowWindow(hwnd, show);
SetForegroundWindow(hwnd);
/*
* Open the initial log file if there is one.
*/
logfopen();
/*
* Set the palette up.
*/