allow ssh_config SetEnv to override $TERM, which is otherwise handled
authordjm <djm@openbsd.org>
Fri, 4 Jun 2021 05:02:40 +0000 (05:02 +0000)
committerdjm <djm@openbsd.org>
Fri, 4 Jun 2021 05:02:40 +0000 (05:02 +0000)
specially by the protocol. Useful in ~/.ssh/config to set TERM to
something generic (e.g. "xterm" instead of "xterm-256color") for
destinations that lack terminfo entries. feedback and ok dtucker@

usr.bin/ssh/misc.c
usr.bin/ssh/misc.h
usr.bin/ssh/mux.c
usr.bin/ssh/ssh.c

index 2f54d63..94a1ea8 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.164 2021/04/03 06:18:40 djm Exp $ */
+/* $OpenBSD: misc.c,v 1.165 2021/06/04 05:02:40 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2005-2020 Damien Miller.  All rights reserved.
@@ -2570,3 +2570,18 @@ subprocess(const char *tag, const char *command,
                *child = f;
        return pid;
 }
+
+const char *
+lookup_env_in_list(const char *env, char * const *envs, size_t nenvs)
+{
+       size_t i, envlen;
+
+       envlen = strlen(env);
+       for (i = 0; i < nenvs; i++) {
+               if (strncmp(envs[i], env, envlen) == 0 &&
+                   envs[i][envlen] == '=') {
+                       return envs[i] + envlen + 1;
+               }
+       }
+       return NULL;
+}
index 70cd778..eba125c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.95 2021/04/03 06:18:40 djm Exp $ */
+/* $OpenBSD: misc.h,v 1.96 2021/06/04 05:02:40 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -173,6 +173,8 @@ void mktemp_proto(char *, size_t);
 
 void    child_set_env(char ***envp, u_int *envsizep, const char *name,
            const char *value);
+const char *lookup_env_in_list(const char *env,
+           char * const *envs, size_t nenvs);
 
 int     argv_split(const char *, int *, char ***);
 char   *argv_assemble(int, char **argv);
index d37101a..fbb346e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: mux.c,v 1.88 2021/05/19 01:24:05 djm Exp $ */
+/* $OpenBSD: mux.c,v 1.89 2021/06/04 05:02:40 djm Exp $ */
 /*
  * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
  *
@@ -1847,7 +1847,7 @@ mux_client_request_session(int fd)
 {
        struct sshbuf *m;
        char *e;
-       const char *term;
+       const char *term = NULL;
        u_int echar, rid, sid, esid, exitval, type, exitval_seen;
        extern char **environ;
        int r, i, rawmode;
@@ -1864,8 +1864,10 @@ mux_client_request_session(int fd)
        if (stdin_null_flag && stdfd_devnull(1, 0, 0) == -1)
                fatal_f("stdfd_devnull failed");
 
-       if ((term = getenv("TERM")) == NULL)
-               term = "";
+       if ((term = lookup_env_in_list("TERM", options.setenv,
+           options.num_setenv)) == NULL || *term == '\0')
+               term = getenv("TERM");
+
        echar = 0xffffffff;
        if (options.escape_char != SSH_ESCAPECHAR_NONE)
            echar = (u_int)options.escape_char;
@@ -1880,7 +1882,7 @@ mux_client_request_session(int fd)
            (r = sshbuf_put_u32(m, options.forward_agent)) != 0 ||
            (r = sshbuf_put_u32(m, subsystem_flag)) != 0 ||
            (r = sshbuf_put_u32(m, echar)) != 0 ||
-           (r = sshbuf_put_cstring(m, term)) != 0 ||
+           (r = sshbuf_put_cstring(m, term == NULL ? "" : term)) != 0 ||
            (r = sshbuf_put_stringb(m, command)) != 0)
                fatal_fr(r, "request");
 
index 9cbb93d..35c0327 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.557 2021/05/19 01:24:05 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.558 2021/06/04 05:02:40 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1997,7 +1997,7 @@ static void
 ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
 {
        extern char **environ;
-       const char *display;
+       const char *display, *term;
        int r, interactive = tty_flag;
        char *proto = NULL, *data = NULL;
 
@@ -2032,7 +2032,10 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
        ssh_packet_set_interactive(ssh, interactive,
            options.ip_qos_interactive, options.ip_qos_bulk);
 
-       client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"),
+       if ((term = lookup_env_in_list("TERM", options.setenv,
+           options.num_setenv)) == NULL || *term == '\0')
+               term = getenv("TERM");
+       client_session2_setup(ssh, id, tty_flag, subsystem_flag, term,
            NULL, fileno(stdin), command, environ);
 }