1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-25 01:02:24 +00:00

`ssh-log-pw-blank': known password fields are now omitted from SSH packet logs

by default (although they can be included). There's also an option to remove
session data, which is good both for privacy and for reducing the size of
logfiles.

[originally from svn r4593]
This commit is contained in:
Jacob Nevins 2004-10-02 00:33:27 +00:00
parent fb92f118bd
commit e375ba107d
7 changed files with 311 additions and 39 deletions

View File

@ -885,6 +885,18 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
"Always append to the end of it", I(LGXF_APN), "Always append to the end of it", I(LGXF_APN),
"Ask the user every time", I(LGXF_ASK), NULL); "Ask the user every time", I(LGXF_ASK), NULL);
if ((midsession && protocol == PROT_SSH) ||
(!midsession && backends[3].name != NULL)) {
s = ctrl_getset(b, "Session/Logging", "ssh",
"Options specific to SSH packet logging");
ctrl_checkbox(s, "Omit known password fields", 'k',
HELPCTX(logging_ssh_omit_password),
dlg_stdcheckbox_handler, I(offsetof(Config,logomitpass)));
ctrl_checkbox(s, "Omit session data", 'd',
HELPCTX(logging_ssh_omit_data),
dlg_stdcheckbox_handler, I(offsetof(Config,logomitdata)));
}
/* /*
* The Terminal panel. * The Terminal panel.
*/ */

View File

@ -1,4 +1,4 @@
\versionid $Id: config.but,v 1.90 2004/09/22 22:15:25 jacob Exp $ \versionid $Id: config.but,v 1.91 2004/10/02 00:33:27 jacob Exp $
\C{config} Configuring PuTTY \C{config} Configuring PuTTY
@ -148,8 +148,9 @@ connections), the SSH message packets sent over the encrypted
connection are written to the log file. You might need this to debug 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 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 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 password, the password can appear in the log file; see
edit it out before sending the log file to anyone else! \k{config-logssh} for options that may help to remove sensitive
material from the log file before you send it to anyone else.
\S{config-logfilename} \q{Log file name} \S{config-logfilename} \q{Log file name}
@ -198,6 +199,44 @@ Finally (the default option), you might not want to have any
automatic behaviour, but to ask the user every time the problem automatic behaviour, but to ask the user every time the problem
comes up. comes up.
\S{config-logssh} Options specific to SSH packet logging
These options only apply if SSH packet data is being logged.
The following options allow particularly sensitive portions of
unencrypted packets to be automatically left out of the log file.
They are only intended to deter casual nosiness; an attacker could
glean a lot of useful information from even these obfuscated logs
(e.g., length of password).
\S2{config-logssh-omitpw} \q{Omit known password fields}
\cfg{winhelp-topic}{logging.ssh.omitpassword}
When checked, password fields are removed from the log of transmitted
packets. (This includes any user responses to challenge-response
authentication methods such as \q{keyboard-interactive}.) This does
not include X11 authentication data if using X11 forwarding.
Note that this will only omit data that PuTTY \e{knows} to be a
password. However, if you start another login session within your
PuTTY session, for instance, any password used will appear in the
clear in the packet log. The next option may be of use to protect
against this.
This option is enabled by default.
\S2{config-logssh-omitdata} \q{Omit session data}
\cfg{winhelp-topic}{logging.ssh.omitdata}
When checked, all \q{session data} is omitted; this is defined as data
in terminal sessions and in forwarded channels (TCP, X11, and
authentication agent). This will usually substantially reduce the size
of the resulting log file.
This option is disabled by default.
\H{config-terminal} The Terminal panel \H{config-terminal} The Terminal panel
The Terminal configuration panel allows you to control the behaviour The Terminal configuration panel allows you to control the behaviour

View File

@ -70,12 +70,14 @@ void log_eventlog(void *handle, const char *event)
/* /*
* Log an SSH packet. * Log an SSH packet.
* If n_blanks != 0, blank or omit some parts.
* Set of blanking areas must be in increasing order.
*/ */
void log_packet(void *handle, int direction, int type, void log_packet(void *handle, int direction, int type,
char *texttype, void *data, int len) char *texttype, void *data, int len,
int n_blanks, const struct logblank_t *blanks)
{ {
struct LogContext *ctx = (struct LogContext *)handle; struct LogContext *ctx = (struct LogContext *)handle;
int i, j;
char dumpdata[80], smalldata[5]; char dumpdata[80], smalldata[5];
if (ctx->cfg.logtype != LGTYP_PACKETS) if (ctx->cfg.logtype != LGTYP_PACKETS)
@ -83,21 +85,81 @@ void log_packet(void *handle, int direction, int type,
if (!ctx->lgfp) if (!ctx->lgfp)
logfopen(ctx); logfopen(ctx);
if (ctx->lgfp) { if (ctx->lgfp) {
int p = 0, b = 0, omitted = 0;
int output_pos = 0; /* NZ if pending output in dumpdata */
/* Packet header. */
fprintf(ctx->lgfp, "%s packet type %d / 0x%02x (%s)\r\n", fprintf(ctx->lgfp, "%s packet type %d / 0x%02x (%s)\r\n",
direction == PKT_INCOMING ? "Incoming" : "Outgoing", direction == PKT_INCOMING ? "Incoming" : "Outgoing",
type, type, texttype); type, type, texttype);
for (i = 0; i < len; i += 16) {
sprintf(dumpdata, " %08x%*s\r\n", i, 1+3*16+2+16, ""); /*
for (j = 0; j < 16 && i+j < len; j++) { * Output a hex/ASCII dump of the packet body, blanking/omitting
int c = ((unsigned char *)data)[i+j]; * parts as specified.
*/
while (p < len) {
int blktype;
/* Move to a current entry in the blanking array. */
while ((b < n_blanks) &&
(p >= blanks[b].offset + blanks[b].len))
b++;
/* Work out what type of blanking to apply to
* this byte. */
blktype = PKTLOG_EMIT; /* default */
if ((b < n_blanks) &&
(p >= blanks[b].offset) &&
(p < blanks[b].offset + blanks[b].len))
blktype = blanks[b].type;
/* If we're about to stop omitting, it's time to say how
* much we omitted. */
if ((blktype != PKTLOG_OMIT) && omitted) {
fprintf(ctx->lgfp, " (%d byte%s omitted)\r\n",
omitted, (omitted==1?"":"s"));
omitted = 0;
}
/* (Re-)initialise dumpdata as necessary
* (start of row, or if we've just stopped omitting) */
if (!output_pos && !omitted)
sprintf(dumpdata, " %08x%*s\r\n", p-(p%16), 1+3*16+2+16, "");
/* Deal with the current byte. */
if (blktype == PKTLOG_OMIT) {
omitted++;
} else {
int c;
if (blktype == PKTLOG_BLANK) {
c = 'X';
sprintf(smalldata, "XX");
} else { /* PKTLOG_EMIT */
c = ((unsigned char *)data)[p];
sprintf(smalldata, "%02x", c); 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, "\r\n"); dumpdata[10+2+3*(p%16)] = smalldata[0];
dumpdata[10+2+3*(p%16)+1] = smalldata[1];
dumpdata[10+1+3*16+2+(p%16)] = (isprint(c) ? c : '.');
output_pos = (p%16) + 1;
}
p++;
/* Flush row if necessary */
if (((p % 16) == 0) || (p == len) || omitted) {
if (output_pos) {
strcpy(dumpdata + 10+1+3*16+2+output_pos, "\r\n");
fputs(dumpdata, ctx->lgfp); fputs(dumpdata, ctx->lgfp);
output_pos = 0;
} }
}
}
/* Tidy up */
if (omitted)
fprintf(ctx->lgfp, " (%d byte%s omitted)\r\n",
omitted, (omitted==1?"":"s"));
fflush(ctx->lgfp); fflush(ctx->lgfp);
} }
} }

11
putty.h
View File

@ -425,6 +425,8 @@ struct config_tag {
Filename logfilename; Filename logfilename;
int logtype; int logtype;
int logxfovr; int logxfovr;
int logomitpass;
int logomitdata;
int hide_mouseptr; int hide_mouseptr;
int sunken_edge; int sunken_edge;
int window_border; int window_border;
@ -658,8 +660,15 @@ void logtraffic(void *logctx, unsigned char c, int logmode);
void logflush(void *logctx); void logflush(void *logctx);
void log_eventlog(void *logctx, const char *string); void log_eventlog(void *logctx, const char *string);
enum { PKT_INCOMING, PKT_OUTGOING }; enum { PKT_INCOMING, PKT_OUTGOING };
enum { PKTLOG_EMIT, PKTLOG_BLANK, PKTLOG_OMIT };
struct logblank_t {
int offset;
int len;
int type;
};
void log_packet(void *logctx, int direction, int type, void log_packet(void *logctx, int direction, int type,
char *texttype, void *data, int len); char *texttype, void *data, int len,
int n_blanks, const struct logblank_t *blanks);
/* /*
* Exports from testback.c * Exports from testback.c

View File

@ -167,6 +167,8 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
write_setting_filename(sesskey, "LogFileName", cfg->logfilename); write_setting_filename(sesskey, "LogFileName", cfg->logfilename);
write_setting_i(sesskey, "LogType", cfg->logtype); write_setting_i(sesskey, "LogType", cfg->logtype);
write_setting_i(sesskey, "LogFileClash", cfg->logxfovr); write_setting_i(sesskey, "LogFileClash", cfg->logxfovr);
write_setting_i(sesskey, "SSHLogOmitPasswords", cfg->logomitpass);
write_setting_i(sesskey, "SSHLogOmitData", cfg->logomitdata);
p = "raw"; p = "raw";
for (i = 0; backends[i].name != NULL; i++) for (i = 0; backends[i].name != NULL; i++)
if (backends[i].protocol == cfg->protocol) { if (backends[i].protocol == cfg->protocol) {
@ -389,6 +391,8 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
gppfile(sesskey, "LogFileName", &cfg->logfilename); gppfile(sesskey, "LogFileName", &cfg->logfilename);
gppi(sesskey, "LogType", 0, &cfg->logtype); gppi(sesskey, "LogType", 0, &cfg->logtype);
gppi(sesskey, "LogFileClash", LGXF_ASK, &cfg->logxfovr); gppi(sesskey, "LogFileClash", LGXF_ASK, &cfg->logxfovr);
gppi(sesskey, "SSHLogOmitPasswords", 1, &cfg->logomitpass);
gppi(sesskey, "SSHLogOmitData", 0, &cfg->logomitdata);
gpps(sesskey, "Protocol", "default", prot, 10); gpps(sesskey, "Protocol", "default", prot, 10);
cfg->protocol = default_protocol; cfg->protocol = default_protocol;

190
ssh.c
View File

@ -267,7 +267,13 @@ static char *ssh2_pkt_type(int pkt_ctx, int type)
(cp)[2] = (unsigned char)((value) >> 8); \ (cp)[2] = (unsigned char)((value) >> 8); \
(cp)[3] = (unsigned char)(value); } (cp)[3] = (unsigned char)(value); }
enum { PKT_END, PKT_INT, PKT_CHAR, PKT_DATA, PKT_STR, PKT_BIGNUM }; /* Enumeration values for fields in SSH-1 packets */
enum {
PKT_END, PKT_INT, PKT_CHAR, PKT_DATA, PKT_STR, PKT_BIGNUM,
/* These values are for communicating relevant semantics of
* fields to the packet logging code. */
PKTT_OTHER, PKTT_PASSWORD, PKTT_DATA
};
/* /*
* Coroutine mechanics for the sillier bits of the code. If these * Coroutine mechanics for the sillier bits of the code. If these
@ -597,6 +603,13 @@ struct ssh_tag {
unsigned char *deferred_send_data; unsigned char *deferred_send_data;
int deferred_len, deferred_size; int deferred_len, deferred_size;
/*
* State associated with packet logging
*/
int pktout_logmode;
int pktout_nblanks;
struct logblank_t *pktout_blanks;
/* /*
* Gross hack: pscp will try to start SFTP but fall back to * Gross hack: pscp will try to start SFTP but fall back to
* scp1 if that fails. This variable is the means by which * scp1 if that fails. This variable is the means by which
@ -684,6 +697,25 @@ static void logeventf(Ssh ssh, const char *fmt, ...)
sfree(text); \ sfree(text); \
} while (0) } while (0)
/* Functions to leave bits out of the SSH packet log file. */
static void dont_log_password(Ssh ssh, int blanktype)
{
if (ssh->cfg.logomitpass)
ssh->pktout_logmode = blanktype;
}
static void dont_log_data(Ssh ssh, int blanktype)
{
if (ssh->cfg.logomitdata)
ssh->pktout_logmode = blanktype;
}
static void end_log_omission(Ssh ssh)
{
ssh->pktout_logmode = PKTLOG_EMIT;
}
static int ssh_channelcmp(void *av, void *bv) static int ssh_channelcmp(void *av, void *bv)
{ {
struct ssh_channel *a = (struct ssh_channel *) av; struct ssh_channel *a = (struct ssh_channel *) av;
@ -898,11 +930,34 @@ static int ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen)
ssh->pktin.type = ssh->pktin.body[-1]; ssh->pktin.type = ssh->pktin.body[-1];
if (ssh->logctx) /*
* Log incoming packet, possibly omitting sensitive fields.
*/
if (ssh->logctx) {
int nblanks = 0;
struct logblank_t blank;
if (ssh->cfg.logomitdata) {
int do_blank = FALSE, blank_prefix = 0;
/* "Session data" packets - omit the data field */
if ((ssh->pktin.type == SSH1_SMSG_STDOUT_DATA) ||
(ssh->pktin.type == SSH1_SMSG_STDERR_DATA)) {
do_blank = TRUE; blank_prefix = 0;
} else if (ssh->pktin.type == SSH1_MSG_CHANNEL_DATA) {
do_blank = TRUE; blank_prefix = 4;
}
if (do_blank) {
blank.offset = blank_prefix;
blank.len = ssh->pktin.length;
blank.type = PKTLOG_OMIT;
nblanks = 1;
}
}
log_packet(ssh->logctx, log_packet(ssh->logctx,
PKT_INCOMING, ssh->pktin.type, PKT_INCOMING, ssh->pktin.type,
ssh1_pkt_type(ssh->pktin.type), ssh1_pkt_type(ssh->pktin.type),
ssh->pktin.body, ssh->pktin.length); ssh->pktin.body, ssh->pktin.length,
nblanks, &blank);
}
if (ssh->pktin.type == SSH1_SMSG_STDOUT_DATA || if (ssh->pktin.type == SSH1_SMSG_STDOUT_DATA ||
ssh->pktin.type == SSH1_SMSG_STDERR_DATA || ssh->pktin.type == SSH1_SMSG_STDERR_DATA ||
@ -1079,10 +1134,32 @@ static int ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen)
ssh->pktin.body = ssh->pktin.data; ssh->pktin.body = ssh->pktin.data;
ssh->pktin.type = ssh->pktin.data[5]; ssh->pktin.type = ssh->pktin.data[5];
if (ssh->logctx) /*
* Log incoming packet, possibly omitting sensitive fields.
*/
if (ssh->logctx) {
int nblanks = 0;
struct logblank_t blank;
if (ssh->cfg.logomitdata) {
int do_blank = FALSE, blank_prefix = 0;
/* "Session data" packets - omit the data field */
if (ssh->pktin.type == SSH2_MSG_CHANNEL_DATA) {
do_blank = TRUE; blank_prefix = 4;
} else if (ssh->pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
do_blank = TRUE; blank_prefix = 8;
}
if (do_blank) {
blank.offset = blank_prefix;
blank.len = (ssh->pktin.length-6) - blank_prefix;
blank.type = PKTLOG_OMIT;
nblanks = 1;
}
}
log_packet(ssh->logctx, PKT_INCOMING, ssh->pktin.type, log_packet(ssh->logctx, PKT_INCOMING, ssh->pktin.type,
ssh2_pkt_type(ssh->pkt_ctx, ssh->pktin.type), ssh2_pkt_type(ssh->pkt_ctx, ssh->pktin.type),
ssh->pktin.data+6, ssh->pktin.length-6); ssh->pktin.data+6, ssh->pktin.length-6,
nblanks, &blank);
}
switch (ssh->pktin.type) { switch (ssh->pktin.type) {
/* /*
@ -1215,6 +1292,9 @@ static void s_wrpkt_start(Ssh ssh, int type, int len)
{ {
ssh1_pktout_size(ssh, len); ssh1_pktout_size(ssh, len);
ssh->pktout.type = type; ssh->pktout.type = type;
/* Initialise log omission state */
ssh->pktout_nblanks = 0;
ssh->pktout_blanks = NULL;
} }
static int s_wrpkt_prepare(Ssh ssh) static int s_wrpkt_prepare(Ssh ssh)
@ -1237,7 +1317,10 @@ static int s_wrpkt_prepare(Ssh ssh)
if (ssh->logctx) if (ssh->logctx)
log_packet(ssh->logctx, PKT_OUTGOING, ssh->pktout.type, log_packet(ssh->logctx, PKT_OUTGOING, ssh->pktout.type,
ssh1_pkt_type(ssh->pktout.type), ssh1_pkt_type(ssh->pktout.type),
ssh->pktout.body, ssh->pktout.length); ssh->pktout.body, ssh->pktout.length,
ssh->pktout_nblanks, ssh->pktout_blanks);
sfree(ssh->pktout_blanks); ssh->pktout_blanks = NULL;
ssh->pktout_nblanks = 0;
if (ssh->v1_compressing) { if (ssh->v1_compressing) {
unsigned char *compblk; unsigned char *compblk;
@ -1324,6 +1407,11 @@ static void construct_packet(Ssh ssh, int pkttype, va_list ap1, va_list ap2)
bn = va_arg(ap1, Bignum); bn = va_arg(ap1, Bignum);
pktlen += ssh1_bignum_length(bn); pktlen += ssh1_bignum_length(bn);
break; break;
case PKTT_PASSWORD:
case PKTT_DATA:
case PKTT_OTHER:
/* ignore this pass */
break;
default: default:
assert(0); assert(0);
} }
@ -1333,34 +1421,58 @@ static void construct_packet(Ssh ssh, int pkttype, va_list ap1, va_list ap2)
p = ssh->pktout.body; p = ssh->pktout.body;
while ((argtype = va_arg(ap2, int)) != PKT_END) { while ((argtype = va_arg(ap2, int)) != PKT_END) {
int offset = p - ssh->pktout.body, len = 0;
switch (argtype) { switch (argtype) {
/* Actual fields in the packet */
case PKT_INT: case PKT_INT:
argint = va_arg(ap2, int); argint = va_arg(ap2, int);
PUT_32BIT(p, argint); PUT_32BIT(p, argint);
p += 4; len = 4;
break; break;
case PKT_CHAR: case PKT_CHAR:
argchar = (unsigned char) va_arg(ap2, int); argchar = (unsigned char) va_arg(ap2, int);
*p = argchar; *p = argchar;
p++; len = 1;
break; break;
case PKT_DATA: case PKT_DATA:
argp = va_arg(ap2, unsigned char *); argp = va_arg(ap2, unsigned char *);
arglen = va_arg(ap2, int); arglen = va_arg(ap2, int);
memcpy(p, argp, arglen); memcpy(p, argp, arglen);
p += arglen; len = arglen;
break; break;
case PKT_STR: case PKT_STR:
argp = va_arg(ap2, unsigned char *); argp = va_arg(ap2, unsigned char *);
arglen = strlen((char *)argp); arglen = strlen((char *)argp);
PUT_32BIT(p, arglen); PUT_32BIT(p, arglen);
memcpy(p + 4, argp, arglen); memcpy(p + 4, argp, arglen);
p += 4 + arglen; len = arglen + 4;
break; break;
case PKT_BIGNUM: case PKT_BIGNUM:
bn = va_arg(ap2, Bignum); bn = va_arg(ap2, Bignum);
p += ssh1_write_bignum(p, bn); len = ssh1_write_bignum(p, bn);
break; break;
/* Tokens for modifications to packet logging */
case PKTT_PASSWORD:
dont_log_password(ssh, PKTLOG_BLANK);
break;
case PKTT_DATA:
dont_log_data(ssh, PKTLOG_OMIT);
break;
case PKTT_OTHER:
end_log_omission(ssh);
break;
}
p += len;
/* Deal with logfile omission, if required. */
if (len && (ssh->pktout_logmode != PKTLOG_EMIT)) {
ssh->pktout_nblanks++;
ssh->pktout_blanks = sresize(ssh->pktout_blanks,
ssh->pktout_nblanks,
struct logblank_t);
ssh->pktout_blanks[ssh->pktout_nblanks-1].offset = offset;
ssh->pktout_blanks[ssh->pktout_nblanks-1].len = len;
ssh->pktout_blanks[ssh->pktout_nblanks-1].type =
ssh->pktout_logmode;
} }
} }
} }
@ -1439,6 +1551,15 @@ static void ssh2_pkt_ensure(Ssh ssh, int length)
} }
static void ssh2_pkt_adddata(Ssh ssh, void *data, int len) static void ssh2_pkt_adddata(Ssh ssh, void *data, int len)
{ {
if (ssh->pktout_logmode != PKTLOG_EMIT) {
ssh->pktout_nblanks++;
ssh->pktout_blanks = sresize(ssh->pktout_blanks, ssh->pktout_nblanks,
struct logblank_t);
ssh->pktout_blanks[ssh->pktout_nblanks-1].offset =
ssh->pktout.length - 6;
ssh->pktout_blanks[ssh->pktout_nblanks-1].len = len;
ssh->pktout_blanks[ssh->pktout_nblanks-1].type = ssh->pktout_logmode;
}
ssh->pktout.length += len; ssh->pktout.length += len;
ssh2_pkt_ensure(ssh, ssh->pktout.length); ssh2_pkt_ensure(ssh, ssh->pktout.length);
memcpy(ssh->pktout.data + ssh->pktout.length - len, data, len); memcpy(ssh->pktout.data + ssh->pktout.length - len, data, len);
@ -1450,6 +1571,7 @@ static void ssh2_pkt_addbyte(Ssh ssh, unsigned char byte)
static void ssh2_pkt_init(Ssh ssh, int pkt_type) static void ssh2_pkt_init(Ssh ssh, int pkt_type)
{ {
ssh->pktout.length = 5; ssh->pktout.length = 5;
ssh->pktout_nblanks = 0; ssh->pktout_blanks = NULL;
ssh2_pkt_addbyte(ssh, (unsigned char) pkt_type); ssh2_pkt_addbyte(ssh, (unsigned char) pkt_type);
} }
static void ssh2_pkt_addbool(Ssh ssh, unsigned char value) static void ssh2_pkt_addbool(Ssh ssh, unsigned char value)
@ -1523,7 +1645,10 @@ static int ssh2_pkt_construct(Ssh ssh)
if (ssh->logctx) if (ssh->logctx)
log_packet(ssh->logctx, PKT_OUTGOING, ssh->pktout.data[5], log_packet(ssh->logctx, PKT_OUTGOING, ssh->pktout.data[5],
ssh2_pkt_type(ssh->pkt_ctx, ssh->pktout.data[5]), ssh2_pkt_type(ssh->pkt_ctx, ssh->pktout.data[5]),
ssh->pktout.data + 6, ssh->pktout.length - 6); ssh->pktout.data + 6, ssh->pktout.length - 6,
ssh->pktout_nblanks, ssh->pktout_blanks);
sfree(ssh->pktout_blanks); ssh->pktout_blanks = NULL;
ssh->pktout_nblanks = 0;
/* /*
* Compress packet payload. * Compress packet payload.
@ -2376,8 +2501,10 @@ static void ssh_agentf_callback(void *cv, void *reply, int replylen)
} else { } else {
send_packet(ssh, SSH1_MSG_CHANNEL_DATA, send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
PKT_INT, c->remoteid, PKT_INT, c->remoteid,
PKTT_DATA,
PKT_INT, replylen, PKT_INT, replylen,
PKT_DATA, sentreply, replylen, PKT_DATA, sentreply, replylen,
PKTT_OTHER,
PKT_END); PKT_END);
} }
if (reply) if (reply)
@ -3154,10 +3281,11 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
randomstr = snewn(top + 1, char); randomstr = snewn(top + 1, char);
for (i = bottom; i <= top; i++) { for (i = bottom; i <= top; i++) {
if (i == pwlen) if (i == pwlen) {
defer_packet(ssh, s->pwpkt_type, defer_packet(ssh, s->pwpkt_type,
PKT_STR, s->password, PKT_END); PKTT_PASSWORD, PKT_STR, s->password,
else { PKTT_OTHER, PKT_END);
} else {
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
do { do {
randomstr[j] = random_byte(); randomstr[j] = random_byte();
@ -3194,8 +3322,9 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
ss = s->password; ss = s->password;
} }
logevent("Sending length-padded password"); logevent("Sending length-padded password");
send_packet(ssh, s->pwpkt_type, PKT_INT, len, send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
PKT_DATA, ss, len, PKT_END); PKT_INT, len, PKT_DATA, ss, len,
PKTT_OTHER, PKT_END);
} else { } else {
/* /*
* The server has _both_ * The server has _both_
@ -3206,11 +3335,14 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
int len; int len;
len = strlen(s->password); len = strlen(s->password);
logevent("Sending unpadded password"); logevent("Sending unpadded password");
send_packet(ssh, s->pwpkt_type, PKT_INT, len, send_packet(ssh, s->pwpkt_type,
PKT_DATA, s->password, len, PKT_END); PKTT_PASSWORD, PKT_INT, len,
PKT_DATA, s->password, len,
PKTT_OTHER, PKT_END);
} }
} else { } else {
send_packet(ssh, s->pwpkt_type, PKT_STR, s->password, PKT_END); send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
PKT_STR, s->password, PKTT_OTHER, PKT_END);
} }
} }
logevent("Sent password"); logevent("Sent password");
@ -3282,7 +3414,9 @@ int sshfwd_write(struct ssh_channel *c, char *buf, int len)
if (ssh->version == 1) { if (ssh->version == 1) {
send_packet(ssh, SSH1_MSG_CHANNEL_DATA, send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
PKT_INT, c->remoteid, PKT_INT, c->remoteid,
PKT_INT, len, PKT_DATA, buf, len, PKT_END); PKTT_DATA,
PKT_INT, len, PKT_DATA, buf, len,
PKTT_OTHER, PKT_END);
/* /*
* In SSH1 we can return 0 here - implying that forwarded * In SSH1 we can return 0 here - implying that forwarded
* connections are never individually throttled - because * connections are never individually throttled - because
@ -3928,8 +4062,9 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
} else { } else {
while (inlen > 0) { while (inlen > 0) {
int len = min(inlen, 512); int len = min(inlen, 512);
send_packet(ssh, SSH1_CMSG_STDIN_DATA, send_packet(ssh, SSH1_CMSG_STDIN_DATA, PKTT_DATA,
PKT_INT, len, PKT_DATA, in, len, PKT_END); PKT_INT, len, PKT_DATA, in, len,
PKTT_OTHER, PKT_END);
in += len; in += len;
inlen -= len; inlen -= len;
} }
@ -4573,8 +4708,10 @@ static int ssh2_try_send(struct ssh_channel *c)
len = c->v.v2.remmaxpkt; len = c->v.v2.remmaxpkt;
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_DATA); ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_DATA);
ssh2_pkt_adduint32(ssh, c->remoteid); ssh2_pkt_adduint32(ssh, c->remoteid);
dont_log_data(ssh, PKTLOG_OMIT);
ssh2_pkt_addstring_start(ssh); ssh2_pkt_addstring_start(ssh);
ssh2_pkt_addstring_data(ssh, data, len); ssh2_pkt_addstring_data(ssh, data, len);
end_log_omission(ssh);
ssh2_pkt_send(ssh); ssh2_pkt_send(ssh);
bufchain_consume(&c->v.v2.outbuffer, len); bufchain_consume(&c->v.v2.outbuffer, len);
c->v.v2.remwindow -= len; c->v.v2.remwindow -= len;
@ -5385,8 +5522,10 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
ssh2_pkt_addstring(ssh, "ssh-connection"); /* service requested */ ssh2_pkt_addstring(ssh, "ssh-connection"); /* service requested */
ssh2_pkt_addstring(ssh, "password"); ssh2_pkt_addstring(ssh, "password");
ssh2_pkt_addbool(ssh, FALSE); ssh2_pkt_addbool(ssh, FALSE);
dont_log_password(ssh, PKTLOG_BLANK);
ssh2_pkt_addstring(ssh, s->password); ssh2_pkt_addstring(ssh, s->password);
memset(s->password, 0, sizeof(s->password)); memset(s->password, 0, sizeof(s->password));
end_log_omission(ssh);
ssh2_pkt_defer(ssh); ssh2_pkt_defer(ssh);
/* /*
* We'll include a string that's an exact multiple of the * We'll include a string that's an exact multiple of the
@ -5430,8 +5569,10 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
ssh2_pkt_adduint32(ssh, s->num_prompts); ssh2_pkt_adduint32(ssh, s->num_prompts);
} }
if (s->need_pw) { /* only add pw if we just got one! */ if (s->need_pw) { /* only add pw if we just got one! */
dont_log_password(ssh, PKTLOG_BLANK);
ssh2_pkt_addstring(ssh, s->password); ssh2_pkt_addstring(ssh, s->password);
memset(s->password, 0, sizeof(s->password)); memset(s->password, 0, sizeof(s->password));
end_log_omission(ssh);
s->curr_prompt++; s->curr_prompt++;
} }
if (s->curr_prompt >= s->num_prompts) { if (s->curr_prompt >= s->num_prompts) {
@ -6412,6 +6553,9 @@ static const char *ssh_init(void *frontend_handle, void **backend_handle,
ssh->deferred_send_data = NULL; ssh->deferred_send_data = NULL;
ssh->deferred_len = 0; ssh->deferred_len = 0;
ssh->deferred_size = 0; ssh->deferred_size = 0;
ssh->pktout_logmode = PKTLOG_EMIT;
ssh->pktout_nblanks = 0;
ssh->pktout_blanks = NULL;
ssh->fallback_cmd = 0; ssh->fallback_cmd = 0;
ssh->pkt_ctx = 0; ssh->pkt_ctx = 0;
ssh->x11auth = NULL; ssh->x11auth = NULL;

View File

@ -13,6 +13,8 @@
#define WINHELP_CTX_logging_main "logging.main" #define WINHELP_CTX_logging_main "logging.main"
#define WINHELP_CTX_logging_filename "logging.filename" #define WINHELP_CTX_logging_filename "logging.filename"
#define WINHELP_CTX_logging_exists "logging.exists" #define WINHELP_CTX_logging_exists "logging.exists"
#define WINHELP_CTX_logging_ssh_omit_password "logging.ssh.omitpassword"
#define WINHELP_CTX_logging_ssh_omit_data "logging.ssh.omitdata"
#define WINHELP_CTX_keyboard_backspace "keyboard.backspace" #define WINHELP_CTX_keyboard_backspace "keyboard.backspace"
#define WINHELP_CTX_keyboard_homeend "keyboard.homeend" #define WINHELP_CTX_keyboard_homeend "keyboard.homeend"
#define WINHELP_CTX_keyboard_funkeys "keyboard.funkeys" #define WINHELP_CTX_keyboard_funkeys "keyboard.funkeys"