]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Merge branch 'master' of ssh://tartarus.org/putty
authorOwen Dunn <owen@greenend.org.uk>
Fri, 27 Nov 2015 19:44:25 +0000 (19:44 +0000)
committerOwen Dunn <owen@greenend.org.uk>
Fri, 27 Nov 2015 19:44:25 +0000 (19:44 +0000)
22 files changed:
Recipe
be_misc.c [new file with mode: 0644]
config.c
doc/errors.but
network.h
portfwd.c
proxy.c
putty.h
raw.c
rlogin.c
settings.c
ssh.c
telnet.c
unix/gtkmisc.c
unix/uxpgnt.c
unix/uxproxy.c
unix/uxsel.c
windows/winhsock.c
windows/winnpc.c
windows/winnps.c
windows/winproxy.c
x11fwd.c

diff --git a/Recipe b/Recipe
index 5fa7356d1dad3523c09be54eb81bb0ad319a306d..fc8e444a55a16ea84ee79c1031bfdf6db5f46095 100644 (file)
--- a/Recipe
+++ b/Recipe
@@ -237,7 +237,7 @@ SFTP     = sftp int64 logging
 
 # Miscellaneous objects appearing in all the network utilities (not
 # Pageant or PuTTYgen).
-MISC     = timing callback misc version settings tree234 proxy conf
+MISC     = timing callback misc version settings tree234 proxy conf be_misc
 WINMISC  = MISC winstore winnet winhandl cmdline windefs winmisc winproxy
          + wintime winhsock errsock winsecur
 UXMISC   = MISC uxstore uxsel uxnet uxpeer cmdline uxmisc uxproxy time
diff --git a/be_misc.c b/be_misc.c
new file mode 100644 (file)
index 0000000..e479aa3
--- /dev/null
+++ b/be_misc.c
@@ -0,0 +1,111 @@
+/*
+ * be_misc.c: helper functions shared between main network backends.
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#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, Conf *conf,
+                        int session_started)
+{
+    char addrbuf[256], *msg;
+
+    switch (type) {
+      case 0:
+        sk_getaddr(addr, addrbuf, lenof(addrbuf));
+        if (sk_addr_needs_port(addr)) {
+            msg = dupprintf("Connecting to %s port %d", addrbuf, port);
+        } else {
+            msg = dupprintf("Connecting to %s", addrbuf);
+        }
+        break;
+      case 1:
+        sk_getaddr(addr, addrbuf, lenof(addrbuf));
+        msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg);
+        break;
+      case 2:
+        /* Proxy-related log messages have their own identifying
+         * prefix already, put on by our caller. */
+        {
+            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 */
+        break;
+    }
+
+    if (msg) {
+        logevent(frontend, msg);
+        sfree(msg);
+    }
+}
+
+void log_proxy_stderr(Plug plug, bufchain *buf, const void *vdata, int len)
+{
+    const char *data = (const char *)vdata;
+    int pos = 0;
+    int msglen;
+    char *nlpos, *msg, *fullmsg;
+
+    /*
+     * This helper function allows us to collect the data written to a
+     * local proxy command's standard error in whatever size chunks we
+     * happen to get from its pipe, and whenever we have a complete
+     * line, we pass it to plug_log.
+     *
+     * Prerequisites: a plug to log to, and a bufchain stored
+     * somewhere to collect the data in.
+     */
+
+    while (pos < len && (nlpos = memchr(data+pos, '\n', len-pos)) != NULL) {
+        /*
+         * Found a newline in the current input buffer. Append it to
+         * the bufchain (which may contain a partial line from last
+         * time).
+         */
+        bufchain_add(buf, data + pos, nlpos - (data + pos));
+
+        /*
+         * Collect the resulting line of data and pass it to plug_log.
+         */
+        msglen = bufchain_size(buf);
+        msg = snewn(msglen+1, char);
+        bufchain_fetch(buf, msg, msglen);
+        bufchain_consume(buf, msglen);
+        msg[msglen] = '\0';
+        fullmsg = dupprintf("proxy: %s", msg);
+        plug_log(plug, 2, NULL, 0, fullmsg, 0);
+        sfree(fullmsg);
+        sfree(msg);
+
+        /*
+         * Advance past the newline.
+         */
+        pos += nlpos+1 - (data + pos);
+    }
+
+    /*
+     * Now any remaining data is a partial line, which we save for
+     * next time.
+     */
+    bufchain_add(buf, data + pos, len - pos);
+}
index 613d5408b5005621393c3003dfdcdd242d5fb9e4..53ad2f910e24a340a2e325a814a0296938be39c7 100644 (file)
--- 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);
     }
 
     /*
index 2d253520feb86affc24f32bad96d19fbf9ce04f8..bf9672d05a0c7d28a268aef0565dc1cba08c6e55 100644 (file)
@@ -338,3 +338,13 @@ things into PuTTY while the network is down, but it can also occur
 if PuTTY decides of its own accord to send data: due to a repeat key
 exchange in SSH-2 (see \k{config-ssh-kex-rekey}) or due to
 keepalives (\k{config-keepalive}).
+
+\H{errors-cannotassignaddress} \q{Network error: Cannot assign requested
+address}
+
+This means that the operating system rejected the parameters of the
+network connection PuTTY tried to make, usually without actually
+trying to connect to anything, because they were simply invalid.
+
+A common way to provoke this error is to accidentally try to connect
+to port 0, which is not a valid port number.
index 7dc497827a26b7e1dcd469cd14f23d3491a6d252..10be046feb10a577ac57e2717f37e1df77cc95a5 100644 (file)
--- a/network.h
+++ b/network.h
@@ -58,6 +58,11 @@ struct plug_function_table {
      *           fatal error - we may well have other candidate addresses
      *           to fall back to. When it _is_ fatal, the closing()
      *           function will be called.
+     *  - type==2 means that error_msg contains a line of generic
+     *    logging information about setting up the connection. This
+     *    will typically be a wodge of standard-error output from a
+     *    proxy command, so the receiver should probably prefix it to
+     *    indicate this.
      */
     int (*closing)
      (Plug p, const char *error_msg, int error_code, int calling_back);
@@ -100,7 +105,8 @@ Socket new_connection(SockAddr addr, const char *hostname,
 Socket new_listener(const char *srcaddr, int port, Plug plug,
                     int local_host_only, Conf *conf, int addressfamily);
 SockAddr name_lookup(const char *host, int port, char **canonicalname,
-                    Conf *conf, int addressfamily);
+                    Conf *conf, int addressfamily, void *frontend_for_logging,
+                     const char *lookup_reason_for_logging);
 int proxy_for_destination (SockAddr addr, const char *hostname, int port,
                            Conf *conf);
 
@@ -211,40 +217,19 @@ char *get_hostname(void);
  */
 Socket new_error_socket(const char *errmsg, Plug plug);
 
-/********** SSL stuff **********/
+/* ----------------------------------------------------------------------
+ * Functions defined outside the network code, which have to be
+ * declared in this header file rather than the main putty.h because
+ * they use types defined here.
+ */
 
 /*
- * This section is subject to change, but you get the general idea
- * of what it will eventually look like.
+ * Exports from be_misc.c.
  */
-
-typedef struct certificate *Certificate;
-typedef struct our_certificate *Our_Certificate;
-    /* to be defined somewhere else, somehow */
-
-typedef struct ssl_client_socket_function_table **SSL_Client_Socket;
-typedef struct ssl_client_plug_function_table **SSL_Client_Plug;
-
-struct ssl_client_socket_function_table {
-    struct socket_function_table base;
-    void (*renegotiate) (SSL_Client_Socket s);
-    /* renegotiate the cipher spec */
-};
-
-struct ssl_client_plug_function_table {
-    struct plug_function_table base;
-    int (*refuse_cert) (SSL_Client_Plug p, Certificate cert[]);
-    /* do we accept this certificate chain?  If not, why not? */
-    /* cert[0] is the server's certificate, cert[] is NULL-terminated */
-    /* the last certificate may or may not be the root certificate */
-     Our_Certificate(*client_cert) (SSL_Client_Plug p);
-    /* the server wants us to identify ourselves */
-    /* may return NULL if we want anonymity */
-};
-
-SSL_Client_Socket sk_ssl_client_over(Socket s, /* pre-existing (tcp) connection */
-                                    SSL_Client_Plug p);
-
-#define sk_renegotiate(s) (((*s)->renegotiate) (s))
+void backend_socket_log(void *frontend, int type, SockAddr addr, int port,
+                        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);
 
 #endif
index 325e86870f426a35be2e1ce7438a1653cc8a9aab..8a73a182d55329ab33a0ab763ff6d3c89d1cac39 100644 (file)
--- a/portfwd.c
+++ b/portfwd.c
@@ -443,7 +443,8 @@ char *pfd_connect(struct PortForwarding **pf_ret, char *hostname,int port,
     /*
      * Try to find host.
      */
-    addr = name_lookup(hostname, port, &dummy_realhost, conf, addressfamily);
+    addr = name_lookup(hostname, port, &dummy_realhost, conf, addressfamily,
+                       NULL, NULL);
     if ((err = sk_addr_error(addr)) != NULL) {
         char *err_ret = dupstr(err);
        sk_addr_free(addr);
diff --git a/proxy.c b/proxy.c
index 3104ef0d8922f8dfd33028b8e1b989d4a5608252..5b77bc7670b1844a273c1693042502ebf39672e6 100644 (file)
--- a/proxy.c
+++ b/proxy.c
@@ -362,17 +362,42 @@ int proxy_for_destination (SockAddr addr, const char *hostname,
     return 1;
 }
 
+static char *dns_log_msg(const char *host, int addressfamily,
+                         const char *reason)
+{
+    return dupprintf("Looking up host \"%s\"%s for %s", host,
+                     (addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
+                      addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" :
+                      ""), reason);
+}
+
 SockAddr name_lookup(const char *host, int port, char **canonicalname,
-                    Conf *conf, int addressfamily)
+                    Conf *conf, int addressfamily, void *frontend,
+                     const char *reason)
 {
+    char *logmsg;
     if (conf_get_int(conf, CONF_proxy_type) != PROXY_NONE &&
        do_proxy_dns(conf) &&
        proxy_for_destination(NULL, host, port, conf)) {
+
+        if (frontend) {
+            logmsg = dupprintf("Leaving host lookup to proxy of \"%s\""
+                               " (for %s)", host, reason);
+            logevent(frontend, logmsg);
+            sfree(logmsg);
+        }
+
        *canonicalname = dupstr(host);
        return sk_nonamelookup(host);
+    } else {
+        if (frontend) {
+            logmsg = dns_log_msg(host, addressfamily, reason);
+            logevent(frontend, logmsg);
+            sfree(logmsg);
+        }
+
+        return sk_namelookup(host, canonicalname, addressfamily);
     }
-
-    return sk_namelookup(host, canonicalname, addressfamily);
 }
 
 Socket new_connection(SockAddr addr, const char *hostname,
@@ -407,6 +432,7 @@ Socket new_connection(SockAddr addr, const char *hostname,
        Proxy_Plug pplug;
        SockAddr proxy_addr;
        char *proxy_canonical_name;
+        const char *proxy_type;
        Socket sret;
        int type;
 
@@ -439,23 +465,45 @@ Socket new_connection(SockAddr addr, const char *hostname,
        type = conf_get_int(conf, CONF_proxy_type);
        if (type == PROXY_HTTP) {
            ret->negotiate = proxy_http_negotiate;
+            proxy_type = "HTTP";
        } else if (type == PROXY_SOCKS4) {
             ret->negotiate = proxy_socks4_negotiate;
+            proxy_type = "SOCKS 4";
        } else if (type == PROXY_SOCKS5) {
             ret->negotiate = proxy_socks5_negotiate;
+            proxy_type = "SOCKS 5";
        } else if (type == PROXY_TELNET) {
            ret->negotiate = proxy_telnet_negotiate;
+            proxy_type = "Telnet";
        } else {
            ret->error = "Proxy error: Unknown proxy method";
            return (Socket) ret;
        }
 
+        {
+            char *logmsg = dupprintf("Will use %s proxy at %s:%d to connect"
+                                      " to %s:%d", proxy_type,
+                                      conf_get_str(conf, CONF_proxy_host),
+                                      conf_get_int(conf, CONF_proxy_port),
+                                      hostname, port);
+            plug_log(plug, 2, NULL, 0, logmsg, 0);
+            sfree(logmsg);
+        }
+
        /* create the proxy plug to map calls from the actual
         * socket into our proxy socket layer */
        pplug = snew(struct Plug_proxy_tag);
        pplug->fn = &plug_fn_table;
        pplug->proxy_socket = ret;
 
+        {
+            char *logmsg = dns_log_msg(conf_get_str(conf, CONF_proxy_host),
+                                       conf_get_int(conf, CONF_addressfamily),
+                                       "proxy");
+            plug_log(plug, 2, NULL, 0, logmsg, 0);
+            sfree(logmsg);
+        }
+
        /* look-up proxy */
        proxy_addr = sk_namelookup(conf_get_str(conf, CONF_proxy_host),
                                   &proxy_canonical_name,
@@ -468,6 +516,16 @@ Socket new_connection(SockAddr addr, const char *hostname,
        }
        sfree(proxy_canonical_name);
 
+        {
+            char addrbuf[256], *logmsg;
+            sk_getaddr(addr, addrbuf, lenof(addrbuf));
+            logmsg = dupprintf("Connecting to %s proxy at %s port %d",
+                               proxy_type, addrbuf,
+                               conf_get_int(conf, CONF_proxy_port));
+            plug_log(plug, 2, NULL, 0, logmsg, 0);
+            sfree(logmsg);
+        }
+
        /* create the actual socket we will be using,
         * connected to our proxy server and port.
         */
@@ -1454,6 +1512,39 @@ int proxy_telnet_negotiate (Proxy_Socket p, int change)
        formatted_cmd = format_telnet_command(p->remote_addr, p->remote_port,
                                              p->conf);
 
+        {
+            /*
+             * Re-escape control chars in the command, for logging.
+             */
+            char *reescaped = snewn(4*strlen(formatted_cmd) + 1, char);
+            const char *in;
+            char *out;
+            char *logmsg;
+
+            for (in = formatted_cmd, out = reescaped; *in; in++) {
+                if (*in == '\n') {
+                    *out++ = '\\'; *out++ = 'n';
+                } else if (*in == '\r') {
+                    *out++ = '\\'; *out++ = 'r';
+                } else if (*in == '\t') {
+                    *out++ = '\\'; *out++ = 't';
+                } else if (*in == '\\') {
+                    *out++ = '\\'; *out++ = '\\';
+                } else if ((unsigned)(((unsigned char)*in) - 0x20) <
+                           (0x7F-0x20)) {
+                    *out++ = *in;
+                } else {
+                    out += sprintf(out, "\\x%02X", (unsigned)*in & 0xFF);
+                }
+            }
+            *out = '\0';
+
+            logmsg = dupprintf("Sending Telnet proxy command: %s", reescaped);
+            plug_log(p->plug, 2, NULL, 0, logmsg, 0);
+            sfree(logmsg);
+            sfree(reescaped);
+        }
+
        sk_write(p->sub_socket, formatted_cmd, strlen(formatted_cmd));
        sfree(formatted_cmd);
 
diff --git a/putty.h b/putty.h
index 3ccd96cb868beb52d8286d617b3ae1a7ddef1ab8..d5333942bd27dbd74eab5eb5cebeb343663d5d45 100644 (file)
--- 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 6262ed8994acc7a6a583addd71d924947ec11f3b..0c5445ad432c28619033cc7cf13f7a0e1c639365 100644 (file)
--- 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);
@@ -40,17 +42,8 @@ static void raw_log(Plug plug, int type, SockAddr addr, int port,
                    const char *error_msg, int error_code)
 {
     Raw raw = (Raw) plug;
-    char addrbuf[256], *msg;
-
-    sk_getaddr(addr, addrbuf, lenof(addrbuf));
-
-    if (type == 0)
-       msg = dupprintf("Connecting to %s port %d", addrbuf, port);
-    else
-       msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg);
-
-    logevent(raw->frontend, msg);
-    sfree(msg);
+    backend_socket_log(raw->frontend, type, addr, port,
+                       error_msg, error_code, raw->conf, raw->session_started);
 }
 
 static void raw_check_close(Raw raw)
@@ -106,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;
 }
 
@@ -147,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;
 
@@ -154,16 +152,8 @@ static const char *raw_init(void *frontend_handle, void **backend_handle,
     /*
      * Try to find host.
      */
-    {
-       char *buf;
-       buf = dupprintf("Looking up host \"%s\"%s", host,
-                       (addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
-                        (addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" :
-                         "")));
-       logevent(raw->frontend, buf);
-       sfree(buf);
-    }
-    addr = name_lookup(host, port, realhost, conf, addressfamily);
+    addr = name_lookup(host, port, realhost, conf, addressfamily,
+                       raw->frontend, "main connection");
     if ((err = sk_addr_error(addr)) != NULL) {
        sk_addr_free(addr);
        return err;
@@ -201,6 +191,7 @@ static void raw_free(void *handle)
 
     if (raw->s)
        sk_close(raw->s);
+    conf_free(raw->conf);
     sfree(raw);
 }
 
index d73f7f9f97b7349025f1c566672178f5c63b5b7c..eba468da235a8689f83753a4b1c8235edc538dab 100644 (file)
--- a/rlogin.c
+++ b/rlogin.c
@@ -48,17 +48,9 @@ static void rlogin_log(Plug plug, int type, SockAddr addr, int port,
                       const char *error_msg, int error_code)
 {
     Rlogin rlogin = (Rlogin) plug;
-    char addrbuf[256], *msg;
-
-    sk_getaddr(addr, addrbuf, lenof(addrbuf));
-
-    if (type == 0)
-       msg = dupprintf("Connecting to %s port %d", addrbuf, port);
-    else
-       msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg);
-
-    logevent(rlogin->frontend, msg);
-    sfree(msg);
+    backend_socket_log(rlogin->frontend, type, addr, port,
+                       error_msg, error_code,
+                       rlogin->conf, !rlogin->firstbyte);
 }
 
 static int rlogin_closing(Plug plug, const char *error_msg, int error_code,
@@ -194,16 +186,8 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle,
     /*
      * Try to find host.
      */
-    {
-       char *buf;
-       buf = dupprintf("Looking up host \"%s\"%s", host,
-                       (addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
-                        (addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" :
-                         "")));
-       logevent(rlogin->frontend, buf);
-       sfree(buf);
-    }
-    addr = name_lookup(host, port, realhost, conf, addressfamily);
+    addr = name_lookup(host, port, realhost, conf, addressfamily,
+                       rlogin->frontend, "rlogin connection");
     if ((err = sk_addr_error(addr)) != NULL) {
        sk_addr_free(addr);
        return err;
index 07ee4123b532f78e34189dfc9c2cb005c1558a0a..23e0ec3921384a633ea4cb10c29dfbff4f6089b5 100644 (file)
@@ -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 01c261a2e2acd5cdea4fe689e2fc40ed4f4268e6..9429724804485dea33c388c0094a2996c1e50368 100644 (file)
--- 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);
@@ -3452,34 +3455,20 @@ static void ssh_socket_log(Plug plug, int type, SockAddr addr, int port,
                            const char *error_msg, int error_code)
 {
     Ssh ssh = (Ssh) plug;
-    char addrbuf[256], *msg;
-
-    if (ssh->attempting_connshare) {
-        /*
-         * While we're attempting connection sharing, don't loudly log
-         * everything that happens. Real TCP connections need to be
-         * logged when we _start_ trying to connect, because it might
-         * be ages before they respond if something goes wrong; but
-         * connection sharing is local and quick to respond, and it's
-         * sufficient to simply wait and see whether it worked
-         * afterwards.
-         */
-    } else {
-        sk_getaddr(addr, addrbuf, lenof(addrbuf));
 
-        if (type == 0) {
-            if (sk_addr_needs_port(addr)) {
-                msg = dupprintf("Connecting to %s port %d", addrbuf, port);
-            } else {
-                msg = dupprintf("Connecting to %s", addrbuf);
-            }
-        } else {
-            msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg);
-        }
+    /*
+     * While we're attempting connection sharing, don't loudly log
+     * everything that happens. Real TCP connections need to be logged
+     * when we _start_ trying to connect, because it might be ages
+     * before they respond if something goes wrong; but connection
+     * sharing is local and quick to respond, and it's sufficient to
+     * simply wait and see whether it worked afterwards.
+     */
 
-        logevent(msg);
-        sfree(msg);
-    }
+    if (!ssh->attempting_connshare)
+        backend_socket_log(ssh->frontend, type, addr, port,
+                           error_msg, error_code, ssh->conf,
+                           ssh->session_started);
 }
 
 void ssh_connshare_log(Ssh ssh, int event, const char *logtext,
@@ -3674,10 +3663,8 @@ static const char *connect_to_host(Ssh ssh, const char *host, int port,
          * Try to find host.
          */
         addressfamily = conf_get_int(ssh->conf, CONF_addressfamily);
-        logeventf(ssh, "Looking up host \"%s\"%s", host,
-                  (addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
-                   (addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" : "")));
-        addr = name_lookup(host, port, realhost, ssh->conf, addressfamily);
+        addr = name_lookup(host, port, realhost, ssh->conf, addressfamily,
+                           ssh->frontend, "SSH connection");
         if ((err = sk_addr_error(addr)) != NULL) {
             sk_addr_free(addr);
             return err;
@@ -11015,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;
 
index 0de8b016c381160ea3f627c171b623450e229b06..c4b0413272be222e5e3c0806805c0f13a6a90ad6 100644 (file)
--- 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,
@@ -652,17 +653,9 @@ static void telnet_log(Plug plug, int type, SockAddr addr, int port,
                       const char *error_msg, int error_code)
 {
     Telnet telnet = (Telnet) plug;
-    char addrbuf[256], *msg;
-
-    sk_getaddr(addr, addrbuf, lenof(addrbuf));
-
-    if (type == 0)
-       msg = dupprintf("Connecting to %s port %d", addrbuf, port);
-    else
-       msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg);
-
-    logevent(telnet->frontend, msg);
-    sfree(msg);
+    backend_socket_log(telnet->frontend, type, addr, port,
+                       error_msg, error_code, telnet->conf,
+                       telnet->session_started);
 }
 
 static int telnet_closing(Plug plug, const char *error_msg, int error_code,
@@ -696,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;
 }
@@ -746,22 +740,15 @@ 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;
 
     /*
      * Try to find host.
      */
-    {
-       char *buf;
-       addressfamily = conf_get_int(telnet->conf, CONF_addressfamily);
-       buf = dupprintf("Looking up host \"%s\"%s", host,
-                       (addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
-                        (addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" :
-                         "")));
-       logevent(telnet->frontend, buf);
-       sfree(buf);
-    }
-    addr = name_lookup(host, port, realhost, telnet->conf, addressfamily);
+    addressfamily = conf_get_int(telnet->conf, CONF_addressfamily);
+    addr = name_lookup(host, port, realhost, telnet->conf, addressfamily,
+                       telnet->frontend, "Telnet connection");
     if ((err = sk_addr_error(addr)) != NULL) {
        sk_addr_free(addr);
        return err;
index cbcc1af50ba8323c66bae5417593de76d24d31d5..d3619e2d358a1493104911c9691d59d34db96617 100644 (file)
@@ -62,6 +62,8 @@ void align_label_left(GtkLabel *label)
 {
 #if GTK_CHECK_VERSION(3,16,0)
     gtk_label_set_xalign(label, 0.0);
+#elif GTK_CHECK_VERSION(3,14,0)
+    gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_START);
 #else
     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
 #endif
index 2f9826b840c0bb6e7585eba524162dd4e55387f3..75f719cf38aedae18fae4d72378dad13d56f34cd 100644 (file)
@@ -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.
index 8c916dc99d7111eb8b898b4b14827555c048c0f5..f92c459be284ee341a35fda4c3e61b14690b75ec 100644 (file)
@@ -21,7 +21,7 @@ struct Socket_localproxy_tag {
     const struct socket_function_table *fn;
     /* the above variable absolutely *must* be the first in this structure */
 
-    int to_cmd, from_cmd;             /* fds */
+    int to_cmd, from_cmd, cmd_err;     /* fds */
 
     char *error;
 
@@ -29,6 +29,7 @@ struct Socket_localproxy_tag {
 
     bufchain pending_output_data;
     bufchain pending_input_data;
+    bufchain pending_error_data;
     enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
 };
 
@@ -37,7 +38,9 @@ static int localproxy_select_result(int fd, int event);
 /*
  * Trees to look up the pipe fds in.
  */
-static tree234 *localproxy_by_fromfd, *localproxy_by_tofd;
+static tree234 *localproxy_by_fromfd;
+static tree234 *localproxy_by_tofd;
+static tree234 *localproxy_by_errfd;
 static int localproxy_fromfd_cmp(void *av, void *bv)
 {
     Local_Proxy_Socket a = (Local_Proxy_Socket)av;
@@ -78,6 +81,26 @@ static int localproxy_tofd_find(void *av, void *bv)
        return +1;
     return 0;
 }
+static int localproxy_errfd_cmp(void *av, void *bv)
+{
+    Local_Proxy_Socket a = (Local_Proxy_Socket)av;
+    Local_Proxy_Socket b = (Local_Proxy_Socket)bv;
+    if (a->cmd_err < b->cmd_err)
+       return -1;
+    if (a->cmd_err > b->cmd_err)
+       return +1;
+    return 0;
+}
+static int localproxy_errfd_find(void *av, void *bv)
+{
+    int a = *(int *)av;
+    Local_Proxy_Socket b = (Local_Proxy_Socket)bv;
+    if (a < b->cmd_err)
+       return -1;
+    if (a > b->cmd_err)
+       return +1;
+    return 0;
+}
 
 /* basic proxy socket functions */
 
@@ -104,6 +127,14 @@ static void sk_localproxy_close (Socket s)
     uxsel_del(ps->from_cmd);
     close(ps->from_cmd);
 
+    del234(localproxy_by_errfd, ps);
+    uxsel_del(ps->cmd_err);
+    close(ps->cmd_err);
+
+    bufchain_clear(&ps->pending_input_data);
+    bufchain_clear(&ps->pending_output_data);
+    bufchain_clear(&ps->pending_error_data);
+
     sfree(ps);
 }
 
@@ -207,19 +238,26 @@ static int localproxy_select_result(int fd, int event)
     int ret;
 
     if (!(s = find234(localproxy_by_fromfd, &fd, localproxy_fromfd_find)) &&
+       !(s = find234(localproxy_by_fromfd, &fd, localproxy_errfd_find)) &&
        !(s = find234(localproxy_by_tofd, &fd, localproxy_tofd_find)) )
        return 1;                      /* boggle */
 
     if (event == 1) {
-       assert(fd == s->from_cmd);
-       ret = read(fd, buf, sizeof(buf));
-       if (ret < 0) {
-           return plug_closing(s->plug, strerror(errno), errno, 0);
-       } else if (ret == 0) {
-           return plug_closing(s->plug, NULL, 0, 0);
-       } else {
-           return plug_receive(s->plug, 0, buf, ret);
-       }
+        if (fd == s->cmd_err) {
+            ret = read(fd, buf, sizeof(buf));
+            if (ret > 0)
+                log_proxy_stderr(s->plug, &s->pending_error_data, buf, ret);
+        } else {
+            assert(fd == s->from_cmd);
+            ret = read(fd, buf, sizeof(buf));
+            if (ret < 0) {
+                return plug_closing(s->plug, strerror(errno), errno, 0);
+            } else if (ret == 0) {
+                return plug_closing(s->plug, NULL, 0, 0);
+            } else {
+                return plug_receive(s->plug, 0, buf, ret);
+            }
+        }
     } else if (event == 2) {
        assert(fd == s->to_cmd);
        if (localproxy_try_send(s))
@@ -250,7 +288,7 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
     };
 
     Local_Proxy_Socket ret;
-    int to_cmd_pipe[2], from_cmd_pipe[2], pid, proxytype;
+    int to_cmd_pipe[2], from_cmd_pipe[2], cmd_err_pipe[2], pid, proxytype;
 
     proxytype = conf_get_int(conf, CONF_proxy_type);
     if (proxytype != PROXY_CMD && proxytype != PROXY_FUZZ)
@@ -264,22 +302,44 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
 
     bufchain_init(&ret->pending_input_data);
     bufchain_init(&ret->pending_output_data);
+    bufchain_init(&ret->pending_error_data);
 
     if (proxytype == PROXY_CMD) {
        cmd = format_telnet_command(addr, port, conf);
 
+        if (flags & FLAG_STDERR) {
+            /* If we have a sensible stderr, the proxy command can
+             * send its own standard error there, so we won't
+             * interfere. */
+            cmd_err_pipe[0] = cmd_err_pipe[1] = -1;
+        } else {
+            /* If we don't have a sensible stderr, we should catch the
+             * proxy command's standard error to put in our event
+             * log. */
+            cmd_err_pipe[0] = cmd_err_pipe[1] = 0;
+        }
+
+        {
+            char *logmsg = dupprintf("Starting local proxy command: %s", cmd);
+            plug_log(plug, 2, NULL, 0, logmsg, 0);
+            sfree(logmsg);
+        }
+
        /*
         * Create the pipes to the proxy command, and spawn the proxy
         * command process.
         */
        if (pipe(to_cmd_pipe) < 0 ||
-           pipe(from_cmd_pipe) < 0) {
+           pipe(from_cmd_pipe) < 0 ||
+            (cmd_err_pipe[0] == 0 && pipe(cmd_err_pipe) < 0)) {
            ret->error = dupprintf("pipe: %s", strerror(errno));
            sfree(cmd);
            return (Socket)ret;
        }
        cloexec(to_cmd_pipe[1]);
        cloexec(from_cmd_pipe[0]);
+       if (cmd_err_pipe[0] >= 0)
+            cloexec(cmd_err_pipe[0]);
 
        pid = fork();
 
@@ -294,6 +354,10 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
            dup2(from_cmd_pipe[1], 1);
            close(to_cmd_pipe[0]);
            close(from_cmd_pipe[1]);
+           if (cmd_err_pipe[0] >= 0) {
+                dup2(cmd_err_pipe[1], 2);
+                close(cmd_err_pipe[1]);
+            }
            noncloexec(0);
            noncloexec(1);
            execl("/bin/sh", "sh", "-c", cmd, (void *)NULL);
@@ -304,9 +368,12 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
 
        close(to_cmd_pipe[0]);
        close(from_cmd_pipe[1]);
+        if (cmd_err_pipe[0] >= 0)
+            close(cmd_err_pipe[1]);
 
        ret->to_cmd = to_cmd_pipe[1];
        ret->from_cmd = from_cmd_pipe[0];
+       ret->cmd_err = cmd_err_pipe[0];
     } else {
        cmd = format_telnet_command(addr, port, conf);
        ret->to_cmd = open("/dev/null", O_WRONLY);
@@ -322,17 +389,24 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
            return (Socket)ret;
        }
        sfree(cmd);
+       ret->cmd_err = -1;
     }
 
     if (!localproxy_by_fromfd)
        localproxy_by_fromfd = newtree234(localproxy_fromfd_cmp);
     if (!localproxy_by_tofd)
        localproxy_by_tofd = newtree234(localproxy_tofd_cmp);
+    if (!localproxy_by_errfd)
+       localproxy_by_errfd = newtree234(localproxy_errfd_cmp);
 
     add234(localproxy_by_fromfd, ret);
     add234(localproxy_by_tofd, ret);
+    if (ret->cmd_err >= 0)
+        add234(localproxy_by_errfd, ret);
 
     uxsel_set(ret->from_cmd, 1, localproxy_select_result);
+    if (ret->cmd_err >= 0)
+        uxsel_set(ret->cmd_err, 1, localproxy_select_result);
 
     /* We are responsible for this and don't need it any more */
     sk_addr_free(addr);
index fa48507fced4a0590fa557a192d411c9c6888fca..ef25cdb574e2a6cf7fe4bb95112be1e05e52b947 100644 (file)
@@ -64,6 +64,8 @@ void uxsel_set(int fd, int rwx, uxsel_callback_fn callback)
 {
     struct fd *newfd;
 
+    assert(fd >= 0);
+
     uxsel_del(fd);
 
     if (rwx) {
index f52d5211572f3ad1e98d6194dd6793e777f9b11e..6c00181589b6f5693facb622b583ab2ab61f1162 100644 (file)
@@ -18,8 +18,8 @@ struct Socket_handle_tag {
     const struct socket_function_table *fn;
     /* the above variable absolutely *must* be the first in this structure */
 
-    HANDLE send_H, recv_H;
-    struct handle *send_h, *recv_h;
+    HANDLE send_H, recv_H, stderr_H;
+    struct handle *send_h, *recv_h, *stderr_h;
 
     /*
      * Freezing one of these sockets is a slightly fiddly business,
@@ -39,6 +39,9 @@ struct Socket_handle_tag {
     /* We buffer data here if we receive it from winhandl while frozen. */
     bufchain inputdata;
 
+    /* Data received from stderr_H, if we have one. */
+    bufchain stderrdata;
+
     char *error;
 
     Plug plug;
@@ -75,6 +78,16 @@ static int handle_gotdata(struct handle *h, void *data, int len)
     }
 }
 
+static int handle_stderr(struct handle *h, void *data, int len)
+{
+    Handle_Socket ps = (Handle_Socket) handle_get_privdata(h);
+
+    if (len > 0)
+        log_proxy_stderr(ps->plug, &ps->stderrdata, data, len);
+
+    return 0;
+}
+
 static void handle_sentdata(struct handle *h, int new_backlog)
 {
     Handle_Socket ps = (Handle_Socket) handle_get_privdata(h);
@@ -101,6 +114,7 @@ static void sk_handle_close(Socket s)
     if (ps->recv_H != ps->send_H)
         CloseHandle(ps->recv_H);
     bufchain_clear(&ps->inputdata);
+    bufchain_clear(&ps->stderrdata);
 
     sfree(ps);
 }
@@ -259,8 +273,8 @@ static char *sk_handle_peer_info(Socket s)
     return NULL;
 }
 
-Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, Plug plug,
-                          int overlapped)
+Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
+                          Plug plug, int overlapped)
 {
     static const struct socket_function_table socket_fn_table = {
        sk_handle_plug,
@@ -283,11 +297,16 @@ Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, Plug plug,
     ret->error = NULL;
     ret->frozen = UNFROZEN;
     bufchain_init(&ret->inputdata);
+    bufchain_init(&ret->stderrdata);
 
     ret->recv_H = recv_H;
     ret->recv_h = handle_input_new(ret->recv_H, handle_gotdata, ret, flags);
     ret->send_H = send_H;
     ret->send_h = handle_output_new(ret->send_H, handle_sentdata, ret, flags);
+    ret->stderr_H = stderr_H;
+    if (ret->stderr_H)
+        ret->stderr_h = handle_input_new(ret->stderr_H, handle_stderr,
+                                         ret, flags);
 
     return (Socket) ret;
 }
index 0e8ac6994dc5baa45e21fff76d84451a480f1a32..85a3c3ffc3b6e37b252ba0c7f1d92cd41d33fa7d 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "winsecur.h"
 
-Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, Plug plug,
-                          int overlapped);
+Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
+                          Plug plug, int overlapped);
 
 Socket new_named_pipe_client(const char *pipename, Plug plug)
 {
@@ -96,7 +96,7 @@ Socket new_named_pipe_client(const char *pipename, Plug plug)
     LocalFree(psd);
     sfree(usersid);
 
-    return make_handle_socket(pipehandle, pipehandle, plug, TRUE);
+    return make_handle_socket(pipehandle, pipehandle, NULL, plug, TRUE);
 }
 
 #endif /* !defined NO_SECURITY */
index 2547fd71c5a3863b8114ab8ca4777a0a86e33d5e..f992a4f0cbfd98f46a7dd95f760f6da07c3c1b27 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "winsecur.h"
 
-Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, Plug plug,
-                          int overlapped);
+Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
+                          Plug plug, int overlapped);
 
 typedef struct Socket_named_pipe_server_tag *Named_Pipe_Server_Socket;
 struct Socket_named_pipe_server_tag {
@@ -120,7 +120,7 @@ static Socket named_pipe_accept(accept_ctx_t ctx, Plug plug)
 {
     HANDLE conn = (HANDLE)ctx.p;
 
-    return make_handle_socket(conn, conn, plug, TRUE);
+    return make_handle_socket(conn, conn, NULL, plug, TRUE);
 }
 
 /*
index 949546000f0c833fb80ed3e7131d7dc1b1675d6c..813c4fe9a76bc21ac0a1d0667a4bd47faf5f2e80 100644 (file)
@@ -13,8 +13,8 @@
 #include "network.h"
 #include "proxy.h"
 
-Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, Plug plug,
-                          int overlapped);
+Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
+                          Plug plug, int overlapped);
 
 Socket platform_new_connection(SockAddr addr, const char *hostname,
                               int port, int privport,
@@ -22,7 +22,9 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
                               Plug plug, Conf *conf)
 {
     char *cmd;
-    HANDLE us_to_cmd, us_from_cmd, cmd_to_us, cmd_from_us;
+    HANDLE us_to_cmd, cmd_from_us;
+    HANDLE us_from_cmd, cmd_to_us;
+    HANDLE us_from_cmd_err, cmd_err_to_us;
     SECURITY_ATTRIBUTES sa;
     STARTUPINFO si;
     PROCESS_INFORMATION pi;
@@ -37,9 +39,7 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
 
     {
        char *msg = dupprintf("Starting local proxy command: %s", cmd);
-       /* We're allowed to pass NULL here, because we're part of the Windows
-        * front end so we know logevent doesn't expect any data. */
-       logevent(NULL, msg);
+       plug_log(plug, 2, NULL, 0, msg, 0);
        sfree(msg);
     }
 
@@ -66,8 +66,25 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
        return ret;
     }
 
+    if (flags & FLAG_STDERR) {
+        /* If we have a sensible stderr, the proxy command can send
+         * its own standard error there, so we won't interfere. */
+        us_from_cmd_err = cmd_err_to_us = NULL;
+    } else {
+        /* If we don't have a sensible stderr, we should catch the
+         * proxy command's standard error to put in our event log. */
+        if (!CreatePipe(&us_from_cmd_err, &cmd_err_to_us, &sa, 0)) {
+            Socket ret = new_error_socket
+                ("Unable to create pipes for proxy command", plug);
+            sfree(cmd);
+            return ret;
+        }
+    }
+
     SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
     SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);
+    if (us_from_cmd_err != NULL)
+        SetHandleInformation(us_from_cmd_err, HANDLE_FLAG_INHERIT, 0);
 
     si.cb = sizeof(si);
     si.lpReserved = NULL;
@@ -78,7 +95,7 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
     si.lpReserved2 = NULL;
     si.hStdInput = cmd_from_us;
     si.hStdOutput = cmd_to_us;
-    si.hStdError = NULL;
+    si.hStdError = cmd_err_to_us;
     CreateProcess(NULL, cmd, NULL, NULL, TRUE,
                  CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
                  NULL, NULL, &si, &pi);
@@ -90,5 +107,9 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
     CloseHandle(cmd_from_us);
     CloseHandle(cmd_to_us);
 
-    return make_handle_socket(us_to_cmd, us_from_cmd, plug, FALSE);
+    if (cmd_err_to_us != NULL)
+        CloseHandle(cmd_err_to_us);
+
+    return make_handle_socket(us_to_cmd, us_from_cmd, us_from_cmd_err,
+                              plug, FALSE);
 }
index 6cfec72824304b8e853802b599c12ed932802a91..bdfc4e743570f9173cf86d82040b593d41fc6e7e 100644 (file)
--- a/x11fwd.c
+++ b/x11fwd.c
@@ -286,7 +286,8 @@ struct X11Display *x11_setup_display(const char *display, Conf *conf)
 
        disp->port = 6000 + disp->displaynum;
        disp->addr = name_lookup(disp->hostname, disp->port,
-                                &disp->realhost, conf, ADDRTYPE_UNSPEC);
+                                &disp->realhost, conf, ADDRTYPE_UNSPEC,
+                                 NULL, NULL);
     
        if ((err = sk_addr_error(disp->addr)) != NULL) {
            sk_addr_free(disp->addr);