From 1025d804ea594740ac60e3b0779bc2bc35c957e8 Mon Sep 17 00:00:00 2001 From: djm Date: Fri, 4 Jun 2021 05:02:40 +0000 Subject: [PATCH] allow ssh_config SetEnv to override $TERM, which is otherwise handled 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 | 17 ++++++++++++++++- usr.bin/ssh/misc.h | 4 +++- usr.bin/ssh/mux.c | 12 +++++++----- usr.bin/ssh/ssh.c | 9 ++++++--- 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/usr.bin/ssh/misc.c b/usr.bin/ssh/misc.c index 2f54d6305ab..94a1ea8266c 100644 --- a/usr.bin/ssh/misc.c +++ b/usr.bin/ssh/misc.c @@ -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; +} diff --git a/usr.bin/ssh/misc.h b/usr.bin/ssh/misc.h index 70cd7787e86..eba125c88c6 100644 --- a/usr.bin/ssh/misc.h +++ b/usr.bin/ssh/misc.h @@ -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 @@ -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); diff --git a/usr.bin/ssh/mux.c b/usr.bin/ssh/mux.c index d37101ae20f..fbb346ef3ef 100644 --- a/usr.bin/ssh/mux.c +++ b/usr.bin/ssh/mux.c @@ -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 * @@ -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"); diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c index 9cbb93d5d94..35c03270310 100644 --- a/usr.bin/ssh/ssh.c +++ b/usr.bin/ssh/ssh.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , 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); } -- 2.20.1