From 7c65b9c57ab1b98ec21ac217a8892131497a1d0f Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 22 Nov 2015 14:33:28 +0000 Subject: [PATCH] Option to log proxy setup diagnostics to the terminal. It has three settings: on, off, and 'only until session starts'. The idea of the last one is that if you use something like 'ssh -v' as your proxy command, you probably wanted to see the initial SSH connection-setup messages while you were waiting to see if the connection would be set up successfully at all, but probably _didn't_ want a slew of diagnostics from rekeys disrupting your terminal in mid-emacs once the session had got properly under way. Default is off, to avoid startling people used to the old behaviour. I wonder if I should have set it more aggressively, though. --- be_misc.c | 23 +++++++++++++++++++++-- config.c | 9 +++++++++ network.h | 3 ++- putty.h | 7 ++++--- raw.c | 12 ++++++++++-- rlogin.c | 3 ++- settings.c | 2 ++ ssh.c | 7 ++++++- telnet.c | 6 +++++- unix/uxpgnt.c | 2 ++ 10 files changed, 63 insertions(+), 11 deletions(-) diff --git a/be_misc.c b/be_misc.c index 739f1602..e479aa3b 100644 --- a/be_misc.c +++ b/be_misc.c @@ -2,12 +2,16 @@ * be_misc.c: helper functions shared between main network backends. */ +#include +#include + #define DEFINE_PLUG_METHOD_MACROS #include "putty.h" #include "network.h" void backend_socket_log(void *frontend, int type, SockAddr addr, int port, - const char *error_msg, int error_code) + const char *error_msg, int error_code, Conf *conf, + int session_started) { char addrbuf[256], *msg; @@ -27,7 +31,22 @@ void backend_socket_log(void *frontend, int type, SockAddr addr, int port, case 2: /* Proxy-related log messages have their own identifying * prefix already, put on by our caller. */ - msg = dupstr(error_msg); + { + int len, log_to_term; + + /* Suffix \r\n temporarily, so we can log to the terminal. */ + msg = dupprintf("%s\r\n", error_msg); + len = strlen(msg); + assert(len >= 2); + + log_to_term = conf_get_int(conf, CONF_proxy_log_to_term); + if (log_to_term == AUTO) + log_to_term = session_started ? FORCE_OFF : FORCE_ON; + if (log_to_term == FORCE_ON) + from_backend(frontend, TRUE, msg, len); + + msg[len-2] = '\0'; /* remove the \r\n again */ + } break; default: msg = NULL; /* shouldn't happen, but placate optimiser */ diff --git a/config.c b/config.c index 613d5408..53ad2f91 100644 --- a/config.c +++ b/config.c @@ -2072,6 +2072,15 @@ void setup_config_box(struct controlbox *b, int midsession, HELPCTX(proxy_command), conf_editbox_handler, I(CONF_proxy_telnet_command), I(1)); + + ctrl_radiobuttons(s, "Print proxy diagnostics " + "in the terminal window", 'r', 5, + HELPCTX(proxy_main), + conf_radiobutton_handler, + I(CONF_proxy_log_to_term), + "No", I(FORCE_OFF), + "Yes", I(FORCE_ON), + "Only until session starts", I(AUTO), NULL); } /* diff --git a/network.h b/network.h index bebbd224..10be046f 100644 --- a/network.h +++ b/network.h @@ -227,7 +227,8 @@ Socket new_error_socket(const char *errmsg, Plug plug); * Exports from be_misc.c. */ void backend_socket_log(void *frontend, int type, SockAddr addr, int port, - const char *error_msg, int error_code); + const char *error_msg, int error_code, Conf *conf, + int session_started); typedef struct bufchain_tag bufchain; /* rest of declaration in misc.c */ void log_proxy_stderr(Plug plug, bufchain *buf, const void *vdata, int len); diff --git a/putty.h b/putty.h index 3ccd96cb..d5333942 100644 --- a/putty.h +++ b/putty.h @@ -279,9 +279,9 @@ enum { * three-way settings whose values are `always yes', `always * no', and `decide by some more complex automated means'. This * is true of line discipline options (local echo and line - * editing), proxy DNS, Close On Exit, and SSH server bug - * workarounds. Accordingly I supply a single enum here to deal - * with them all. + * editing), proxy DNS, proxy terminal logging, Close On Exit, and + * SSH server bug workarounds. Accordingly I supply a single enum + * here to deal with them all. */ FORCE_ON, FORCE_OFF, AUTO }; @@ -681,6 +681,7 @@ void cleanup_exit(int); X(STR, NONE, proxy_username) \ X(STR, NONE, proxy_password) \ X(STR, NONE, proxy_telnet_command) \ + X(INT, NONE, proxy_log_to_term) \ /* SSH options */ \ X(STR, NONE, remote_cmd) \ X(STR, NONE, remote_cmd2) /* fallback if remote_cmd fails; never loaded or saved */ \ diff --git a/raw.c b/raw.c index 24807713..0c5445ad 100644 --- a/raw.c +++ b/raw.c @@ -25,7 +25,9 @@ typedef struct raw_backend_data { int closed_on_socket_error; int bufsize; void *frontend; - int sent_console_eof, sent_socket_eof; + int sent_console_eof, sent_socket_eof, session_started; + + Conf *conf; } *Raw; static void raw_size(void *handle, int width, int height); @@ -41,7 +43,7 @@ static void raw_log(Plug plug, int type, SockAddr addr, int port, { Raw raw = (Raw) plug; backend_socket_log(raw->frontend, type, addr, port, - error_msg, error_code); + error_msg, error_code, raw->conf, raw->session_started); } static void raw_check_close(Raw raw) @@ -97,6 +99,9 @@ static int raw_receive(Plug plug, int urgent, char *data, int len) { Raw raw = (Raw) plug; c_write(raw, data, len); + /* We count 'session start', for proxy logging purposes, as being + * when data is received from the network and printed. */ + raw->session_started = TRUE; return 1; } @@ -138,6 +143,8 @@ static const char *raw_init(void *frontend_handle, void **backend_handle, *backend_handle = raw; raw->sent_console_eof = raw->sent_socket_eof = FALSE; raw->bufsize = 0; + raw->session_started = FALSE; + raw->conf = conf_copy(conf); raw->frontend = frontend_handle; @@ -184,6 +191,7 @@ static void raw_free(void *handle) if (raw->s) sk_close(raw->s); + conf_free(raw->conf); sfree(raw); } diff --git a/rlogin.c b/rlogin.c index 5541319d..eba468da 100644 --- a/rlogin.c +++ b/rlogin.c @@ -49,7 +49,8 @@ static void rlogin_log(Plug plug, int type, SockAddr addr, int port, { Rlogin rlogin = (Rlogin) plug; backend_socket_log(rlogin->frontend, type, addr, port, - error_msg, error_code); + error_msg, error_code, + rlogin->conf, !rlogin->firstbyte); } static int rlogin_closing(Plug plug, const char *error_msg, int error_code, diff --git a/settings.c b/settings.c index 07ee4123..23e0ec39 100644 --- a/settings.c +++ b/settings.c @@ -480,6 +480,7 @@ void save_open_settings(void *sesskey, Conf *conf) write_setting_s(sesskey, "ProxyUsername", conf_get_str(conf, CONF_proxy_username)); write_setting_s(sesskey, "ProxyPassword", conf_get_str(conf, CONF_proxy_password)); write_setting_s(sesskey, "ProxyTelnetCommand", conf_get_str(conf, CONF_proxy_telnet_command)); + write_setting_i(sesskey, "ProxyLogToTerm", conf_get_int(conf, CONF_proxy_log_to_term)); wmap(sesskey, "Environment", conf, CONF_environmt, TRUE); write_setting_s(sesskey, "UserName", conf_get_str(conf, CONF_username)); write_setting_i(sesskey, "UserNameFromEnvironment", conf_get_int(conf, CONF_username_from_env)); @@ -759,6 +760,7 @@ void load_open_settings(void *sesskey, Conf *conf) gpps(sesskey, "ProxyPassword", "", conf, CONF_proxy_password); gpps(sesskey, "ProxyTelnetCommand", "connect %host %port\\n", conf, CONF_proxy_telnet_command); + gppi(sesskey, "ProxyLogToTerm", FORCE_OFF, conf, CONF_proxy_log_to_term); gppmap(sesskey, "Environment", conf, CONF_environmt); gpps(sesskey, "UserName", "", conf, CONF_username); gppi(sesskey, "UserNameFromEnvironment", 0, conf, CONF_username_from_env); diff --git a/ssh.c b/ssh.c index d1ed1421..94297248 100644 --- a/ssh.c +++ b/ssh.c @@ -792,6 +792,7 @@ struct ssh_tag { int send_ok; int echoing, editing; + int session_started; void *frontend; int ospeed, ispeed; /* temporaries */ @@ -3070,6 +3071,8 @@ static int do_ssh_init(Ssh ssh, unsigned char c) crReturn(1); } + ssh->session_started = TRUE; + s->vstrsize = sizeof(protoname) + 16; s->vstring = snewn(s->vstrsize, char); strcpy(s->vstring, protoname); @@ -3464,7 +3467,8 @@ static void ssh_socket_log(Plug plug, int type, SockAddr addr, int port, if (!ssh->attempting_connshare) backend_socket_log(ssh->frontend, type, addr, port, - error_msg, error_code); + error_msg, error_code, ssh->conf, + ssh->session_started); } void ssh_connshare_log(Ssh ssh, int event, const char *logtext, @@ -10998,6 +11002,7 @@ static const char *ssh_init(void *frontend_handle, void **backend_handle, ssh->X11_fwd_enabled = FALSE; ssh->connshare = NULL; ssh->attempting_connshare = FALSE; + ssh->session_started = FALSE; *backend_handle = ssh; diff --git a/telnet.c b/telnet.c index 09a72d1f..c4b04132 100644 --- a/telnet.c +++ b/telnet.c @@ -197,6 +197,7 @@ typedef struct telnet_tag { int sb_opt, sb_len; unsigned char *sb_buf; int sb_size; + int session_started; enum { TOP_LEVEL, SEENIAC, SEENWILL, SEENWONT, SEENDO, SEENDONT, @@ -653,7 +654,8 @@ static void telnet_log(Plug plug, int type, SockAddr addr, int port, { Telnet telnet = (Telnet) plug; backend_socket_log(telnet->frontend, type, addr, port, - error_msg, error_code); + error_msg, error_code, telnet->conf, + telnet->session_started); } static int telnet_closing(Plug plug, const char *error_msg, int error_code, @@ -687,6 +689,7 @@ static int telnet_receive(Plug plug, int urgent, char *data, int len) Telnet telnet = (Telnet) plug; if (urgent) telnet->in_synch = TRUE; + telnet->session_started = TRUE; do_telnet_read(telnet, data, len); return 1; } @@ -737,6 +740,7 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle, telnet->state = TOP_LEVEL; telnet->ldisc = NULL; telnet->pinger = NULL; + telnet->session_started = TRUE; *backend_handle = telnet; /* diff --git a/unix/uxpgnt.c b/unix/uxpgnt.c index 2f9826b8..75f719cf 100644 --- a/unix/uxpgnt.c +++ b/unix/uxpgnt.c @@ -103,6 +103,8 @@ FontSpec *platform_default_fontspec(const char *name) { return fontspec_new(""); Filename *platform_default_filename(const char *name) { return filename_from_str(""); } char *x_get_default(const char *key) { return NULL; } void log_eventlog(void *handle, const char *event) {} +int from_backend(void *frontend, int is_stderr, const char *data, int datalen) +{ assert(!"only here to satisfy notional call from backend_socket_log"); } /* * Short description of parameters. -- 2.45.2