From 9a10ecf4474c0c40d1ec162209ad081512a6474d Mon Sep 17 00:00:00 2001 From: jacob Date: Sat, 2 Oct 2004 00:33:27 +0000 Subject: [PATCH] `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. git-svn-id: svn://svn.tartarus.org/sgt/putty@4593 cda61777-01e9-0310-a592-d414129be87e --- config.c | 12 ++++ doc/config.but | 45 +++++++++++++- logging.c | 86 ++++++++++++++++++++++---- putty.h | 11 +++- settings.c | 4 ++ ssh.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++------- winhelp.h | 2 + 7 files changed, 311 insertions(+), 39 deletions(-) diff --git a/config.c b/config.c index 146fb58b..cbf31698 100644 --- a/config.c +++ b/config.c @@ -885,6 +885,18 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, "Always append to the end of it", I(LGXF_APN), "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. */ diff --git a/doc/config.but b/doc/config.but index 2556a387..8a773ef2 100644 --- a/doc/config.but +++ b/doc/config.but @@ -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 @@ -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 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! +password, the password can appear in the log file; see +\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} @@ -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 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 The Terminal configuration panel allows you to control the behaviour diff --git a/logging.c b/logging.c index 5302998f..808e429f 100644 --- a/logging.c +++ b/logging.c @@ -70,12 +70,14 @@ void log_eventlog(void *handle, const char *event) /* * 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, - 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; - int i, j; char dumpdata[80], smalldata[5]; if (ctx->cfg.logtype != LGTYP_PACKETS) @@ -83,21 +85,81 @@ void log_packet(void *handle, int direction, int type, if (!ctx->lgfp) logfopen(ctx); 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", direction == PKT_INCOMING ? "Incoming" : "Outgoing", 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++) { - 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 : '.'); + + /* + * Output a hex/ASCII dump of the packet body, blanking/omitting + * 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); + } + 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); + output_pos = 0; + } } - strcpy(dumpdata + 10+1+3*16+2+j, "\r\n"); - fputs(dumpdata, ctx->lgfp); + } + + /* Tidy up */ + if (omitted) + fprintf(ctx->lgfp, " (%d byte%s omitted)\r\n", + omitted, (omitted==1?"":"s")); fflush(ctx->lgfp); } } diff --git a/putty.h b/putty.h index b12429f5..93a39e4b 100644 --- a/putty.h +++ b/putty.h @@ -425,6 +425,8 @@ struct config_tag { Filename logfilename; int logtype; int logxfovr; + int logomitpass; + int logomitdata; int hide_mouseptr; int sunken_edge; int window_border; @@ -658,8 +660,15 @@ void logtraffic(void *logctx, unsigned char c, int logmode); void logflush(void *logctx); void log_eventlog(void *logctx, const char *string); 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, - char *texttype, void *data, int len); + char *texttype, void *data, int len, + int n_blanks, const struct logblank_t *blanks); /* * Exports from testback.c diff --git a/settings.c b/settings.c index a5f2e448..679fab15 100644 --- a/settings.c +++ b/settings.c @@ -167,6 +167,8 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg) write_setting_filename(sesskey, "LogFileName", cfg->logfilename); write_setting_i(sesskey, "LogType", cfg->logtype); write_setting_i(sesskey, "LogFileClash", cfg->logxfovr); + write_setting_i(sesskey, "SSHLogOmitPasswords", cfg->logomitpass); + write_setting_i(sesskey, "SSHLogOmitData", cfg->logomitdata); p = "raw"; for (i = 0; backends[i].name != NULL; i++) 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); gppi(sesskey, "LogType", 0, &cfg->logtype); 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); cfg->protocol = default_protocol; diff --git a/ssh.c b/ssh.c index 5b5a6be7..e8d24313 100644 --- a/ssh.c +++ b/ssh.c @@ -267,7 +267,13 @@ static char *ssh2_pkt_type(int pkt_ctx, int type) (cp)[2] = (unsigned char)((value) >> 8); \ (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 @@ -598,6 +604,13 @@ struct ssh_tag { 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 * scp1 if that fails. This variable is the means by which * scp.c can reach into the SSH code and find out which one it @@ -684,6 +697,25 @@ static void logeventf(Ssh ssh, const char *fmt, ...) sfree(text); \ } 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) { 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]; - 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, PKT_INCOMING, 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 || 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.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, 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) { /* @@ -1215,6 +1292,9 @@ static void s_wrpkt_start(Ssh ssh, int type, int len) { ssh1_pktout_size(ssh, len); ssh->pktout.type = type; + /* Initialise log omission state */ + ssh->pktout_nblanks = 0; + ssh->pktout_blanks = NULL; } static int s_wrpkt_prepare(Ssh ssh) @@ -1237,7 +1317,10 @@ static int s_wrpkt_prepare(Ssh ssh) if (ssh->logctx) log_packet(ssh->logctx, PKT_OUTGOING, 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) { 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); pktlen += ssh1_bignum_length(bn); break; + case PKTT_PASSWORD: + case PKTT_DATA: + case PKTT_OTHER: + /* ignore this pass */ + break; default: assert(0); } @@ -1333,34 +1421,58 @@ static void construct_packet(Ssh ssh, int pkttype, va_list ap1, va_list ap2) p = ssh->pktout.body; while ((argtype = va_arg(ap2, int)) != PKT_END) { + int offset = p - ssh->pktout.body, len = 0; switch (argtype) { + /* Actual fields in the packet */ case PKT_INT: argint = va_arg(ap2, int); PUT_32BIT(p, argint); - p += 4; + len = 4; break; case PKT_CHAR: argchar = (unsigned char) va_arg(ap2, int); *p = argchar; - p++; + len = 1; break; case PKT_DATA: argp = va_arg(ap2, unsigned char *); arglen = va_arg(ap2, int); memcpy(p, argp, arglen); - p += arglen; + len = arglen; break; case PKT_STR: argp = va_arg(ap2, unsigned char *); arglen = strlen((char *)argp); PUT_32BIT(p, arglen); memcpy(p + 4, argp, arglen); - p += 4 + arglen; + len = arglen + 4; break; case PKT_BIGNUM: bn = va_arg(ap2, Bignum); - p += ssh1_write_bignum(p, bn); + len = ssh1_write_bignum(p, bn); + 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) { + 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; ssh2_pkt_ensure(ssh, ssh->pktout.length); 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) { ssh->pktout.length = 5; + ssh->pktout_nblanks = 0; ssh->pktout_blanks = NULL; ssh2_pkt_addbyte(ssh, (unsigned char) pkt_type); } static void ssh2_pkt_addbool(Ssh ssh, unsigned char value) @@ -1523,7 +1645,10 @@ static int ssh2_pkt_construct(Ssh ssh) if (ssh->logctx) log_packet(ssh->logctx, PKT_OUTGOING, 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. @@ -2376,8 +2501,10 @@ static void ssh_agentf_callback(void *cv, void *reply, int replylen) } else { send_packet(ssh, SSH1_MSG_CHANNEL_DATA, PKT_INT, c->remoteid, + PKTT_DATA, PKT_INT, replylen, PKT_DATA, sentreply, replylen, + PKTT_OTHER, PKT_END); } 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); for (i = bottom; i <= top; i++) { - if (i == pwlen) + if (i == pwlen) { defer_packet(ssh, s->pwpkt_type, - PKT_STR, s->password, PKT_END); - else { + PKTT_PASSWORD, PKT_STR, s->password, + PKTT_OTHER, PKT_END); + } else { for (j = 0; j < i; j++) { do { 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; } logevent("Sending length-padded password"); - send_packet(ssh, s->pwpkt_type, PKT_INT, len, - PKT_DATA, ss, len, PKT_END); + send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD, + PKT_INT, len, PKT_DATA, ss, len, + PKTT_OTHER, PKT_END); } else { /* * The server has _both_ @@ -3206,11 +3335,14 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) int len; len = strlen(s->password); logevent("Sending unpadded password"); - send_packet(ssh, s->pwpkt_type, PKT_INT, len, - PKT_DATA, s->password, len, PKT_END); + send_packet(ssh, s->pwpkt_type, + PKTT_PASSWORD, PKT_INT, len, + PKT_DATA, s->password, len, + PKTT_OTHER, PKT_END); } } 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"); @@ -3282,7 +3414,9 @@ int sshfwd_write(struct ssh_channel *c, char *buf, int len) if (ssh->version == 1) { send_packet(ssh, SSH1_MSG_CHANNEL_DATA, 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 * connections are never individually throttled - because @@ -3928,8 +4062,9 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt) } else { while (inlen > 0) { int len = min(inlen, 512); - send_packet(ssh, SSH1_CMSG_STDIN_DATA, - PKT_INT, len, PKT_DATA, in, len, PKT_END); + send_packet(ssh, SSH1_CMSG_STDIN_DATA, PKTT_DATA, + PKT_INT, len, PKT_DATA, in, len, + PKTT_OTHER, PKT_END); in += len; inlen -= len; } @@ -4573,8 +4708,10 @@ static int ssh2_try_send(struct ssh_channel *c) len = c->v.v2.remmaxpkt; ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_DATA); ssh2_pkt_adduint32(ssh, c->remoteid); + dont_log_data(ssh, PKTLOG_OMIT); ssh2_pkt_addstring_start(ssh); ssh2_pkt_addstring_data(ssh, data, len); + end_log_omission(ssh); ssh2_pkt_send(ssh); bufchain_consume(&c->v.v2.outbuffer, 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, "password"); ssh2_pkt_addbool(ssh, FALSE); + dont_log_password(ssh, PKTLOG_BLANK); ssh2_pkt_addstring(ssh, s->password); memset(s->password, 0, sizeof(s->password)); + end_log_omission(ssh); ssh2_pkt_defer(ssh); /* * 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); } if (s->need_pw) { /* only add pw if we just got one! */ + dont_log_password(ssh, PKTLOG_BLANK); ssh2_pkt_addstring(ssh, s->password); memset(s->password, 0, sizeof(s->password)); + end_log_omission(ssh); s->curr_prompt++; } 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_len = 0; ssh->deferred_size = 0; + ssh->pktout_logmode = PKTLOG_EMIT; + ssh->pktout_nblanks = 0; + ssh->pktout_blanks = NULL; ssh->fallback_cmd = 0; ssh->pkt_ctx = 0; ssh->x11auth = NULL; diff --git a/winhelp.h b/winhelp.h index 5271f924..6b7ca242 100644 --- a/winhelp.h +++ b/winhelp.h @@ -13,6 +13,8 @@ #define WINHELP_CTX_logging_main "logging.main" #define WINHELP_CTX_logging_filename "logging.filename" #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_homeend "keyboard.homeend" #define WINHELP_CTX_keyboard_funkeys "keyboard.funkeys" -- 2.11.0