* logging can sensibly be available.
*/
{
- char *sshlogname;
+ char *sshlogname, *sshrawlogname;
if ((midsession && protocol == PROT_SSH) ||
- (!midsession && backends[3].name != NULL))
- sshlogname = "Log SSH packet data";
- else
- sshlogname = NULL; /* this will disable the button */
- ctrl_radiobuttons(s, "Session logging:", NO_SHORTCUT, 1,
+ (!midsession && backends[3].name != NULL)) {
+ sshlogname = "SSH packets";
+ sshrawlogname = "SSH packets and raw data";
+ } else {
+ sshlogname = NULL; /* this will disable both buttons */
+ sshrawlogname = NULL; /* this will just placate optimisers */
+ }
+ ctrl_radiobuttons(s, "Session logging:", NO_SHORTCUT, 2,
HELPCTX(logging_main),
loggingbuttons_handler,
I(offsetof(Config, logtype)),
- "Logging turned off completely", 't', I(LGTYP_NONE),
- "Log printable output only", 'p', I(LGTYP_ASCII),
- "Log all session output", 'l', I(LGTYP_DEBUG),
+ "None", 't', I(LGTYP_NONE),
+ "Printable output", 'p', I(LGTYP_ASCII),
+ "All session output", 'l', I(LGTYP_DEBUG),
sshlogname, 's', I(LGTYP_PACKETS),
+ sshrawlogname, 'r', I(LGTYP_SSHRAW),
NULL);
}
ctrl_filesel(s, "Log file name:", 'f',
(ctx->cfg.logtype == LGTYP_ASCII ? "ASCII" :
ctx->cfg.logtype == LGTYP_DEBUG ? "raw" :
ctx->cfg.logtype == LGTYP_PACKETS ? "SSH packets" :
+ ctx->cfg.logtype == LGTYP_SSHRAW ? "SSH raw data" :
"unknown"),
filename_to_str(&ctx->currlogfilename));
logevent(ctx->frontend, event);
fprintf(stderr, "%s\n", event);
fflush(stderr);
}
- if (ctx->cfg.logtype != LGTYP_PACKETS)
+ if (ctx->cfg.logtype != LGTYP_PACKETS &&
+ ctx->cfg.logtype != LGTYP_SSHRAW)
return;
logprintf(ctx, "Event Log: %s\r\n", event);
+ logflush(ctx);
}
/*
int p = 0, b = 0, omitted = 0;
int output_pos = 0; /* NZ if pending output in dumpdata */
- if (ctx->cfg.logtype != LGTYP_PACKETS)
+ if (!(ctx->cfg.logtype == LGTYP_SSHRAW ||
+ (ctx->cfg.logtype == LGTYP_PACKETS && texttype)))
return;
/* Packet header. */
- logprintf(ctx, "%s packet type %d / 0x%02x (%s)\r\n",
- direction == PKT_INCOMING ? "Incoming" : "Outgoing",
- type, type, texttype);
+ if (texttype)
+ logprintf(ctx, "%s packet type %d / 0x%02x (%s)\r\n",
+ direction == PKT_INCOMING ? "Incoming" : "Outgoing",
+ type, type, texttype);
+ else
+ logprintf(ctx, "%s raw data\r\n",
+ direction == PKT_INCOMING ? "Incoming" : "Outgoing");
/*
* Output a hex/ASCII dump of the packet body, blanking/omitting
#define LGTYP_ASCII 1 /* logmode: pure ascii */
#define LGTYP_DEBUG 2 /* logmode: all chars of traffic */
#define LGTYP_PACKETS 3 /* logmode: SSH data packets */
+#define LGTYP_SSHRAW 4 /* logmode: SSH raw data */
typedef enum {
/* Actual special commands. Originally Telnet, but some codes have
return biglen + 4; /* len(length+padding+type+data+CRC) */
}
+static int s_write(Ssh ssh, void *data, int len)
+{
+ log_packet(ssh->logctx, PKT_OUTGOING, -1, NULL, data, len, 0, NULL);
+ return sk_write(ssh->s, (char *)data, len);
+}
+
static void s_wrpkt(Ssh ssh, struct Packet *pkt)
{
int len, backlog, offset;
len = s_wrpkt_prepare(ssh, pkt, &offset);
- backlog = sk_write(ssh->s, (char *)pkt->data + offset, len);
+ backlog = s_write(ssh, pkt->data + offset, len);
if (backlog > SSH_MAX_BACKLOG)
ssh_throttle_all(ssh, 1, backlog);
ssh_free_packet(pkt);
return;
}
len = ssh2_pkt_construct(ssh, pkt);
- backlog = sk_write(ssh->s, (char *)pkt->data, len);
+ backlog = s_write(ssh, pkt->data, len);
if (backlog > SSH_MAX_BACKLOG)
ssh_throttle_all(ssh, 1, backlog);
static void ssh_pkt_defersend(Ssh ssh)
{
int backlog;
- backlog = sk_write(ssh->s, (char *)ssh->deferred_send_data,
- ssh->deferred_len);
+ backlog = s_write(ssh, ssh->deferred_send_data, ssh->deferred_len);
ssh->deferred_len = ssh->deferred_size = 0;
sfree(ssh->deferred_send_data);
ssh->deferred_send_data = NULL;
}
logeventf(ssh, "We claim version: %.*s",
strcspn(verstring, "\015\012"), verstring);
- sk_write(ssh->s, verstring, strlen(verstring));
+ s_write(ssh, verstring, strlen(verstring));
sfree(verstring);
if (ssh->version == 2)
do_ssh2_transport(ssh, NULL, -1, NULL);
static void ssh_process_incoming_data(Ssh ssh,
unsigned char **data, int *datalen)
{
- struct Packet *pktin = ssh->s_rdpkt(ssh, data, datalen);
+ struct Packet *pktin;
+
+ pktin = ssh->s_rdpkt(ssh, data, datalen);
if (pktin) {
ssh->protocol(ssh, NULL, 0, pktin);
ssh_free_packet(pktin);
static void ssh_gotdata(Ssh ssh, unsigned char *data, int datalen)
{
+ /* Log raw data, if we're in that mode. */
+ log_packet(ssh->logctx, PKT_INCOMING, -1, NULL, data, datalen, 0, NULL);
+
crBegin(ssh->ssh_gotdata_crstate);
/*