From 21771e22d3e23a10cb01983b2df83d47362eadda Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 15 May 2011 08:45:50 +1000 Subject: - djm@cvs.openbsd.org 2011/05/06 21:34:32 [clientloop.c mux.c readconf.c readconf.h ssh.c ssh_config.5] Add a RequestTTY ssh_config option to allow configuration-based control over tty allocation (like -t/-T); ok markus@ --- ChangeLog | 4 ++++ clientloop.c | 24 +++++++++++------------- mux.c | 7 +++---- readconf.c | 28 ++++++++++++++++++++++++++-- readconf.h | 8 +++++++- ssh.c | 41 ++++++++++++++++++++++------------------- ssh_config.5 | 19 ++++++++++++++++++- 7 files changed, 91 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index caec1dd27..67e651335 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,10 @@ Will match "a.example.org", "b.example.org", but not "c.example.org" ok markus@ + - djm@cvs.openbsd.org 2011/05/06 21:34:32 + [clientloop.c mux.c readconf.c readconf.h ssh.c ssh_config.5] + Add a RequestTTY ssh_config option to allow configuration-based + control over tty allocation (like -t/-T); ok markus@ 20110510 - (dtucker) [openbsd-compat/openssl-compat.{c,h}] Bug #1882: fix diff --git a/clientloop.c b/clientloop.c index 502dd982c..5bd757dfb 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.232 2011/04/17 22:42:41 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.233 2011/05/06 21:34:32 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -130,9 +130,6 @@ extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */ */ extern char *host; -/* Force TTY allocation */ -extern int force_tty_flag; - /* * Flag to indicate that we have received a window change signal which has * not yet been processed. This will cause a message indicating the new @@ -662,7 +659,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); - leave_raw_mode(force_tty_flag); + leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); /* * Free (and clear) the buffer to reduce the amount of data that gets @@ -683,7 +680,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) buffer_init(bout); buffer_init(berr); - enter_raw_mode(force_tty_flag); + enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); } static void @@ -826,7 +823,7 @@ process_cmdline(void) bzero(&fwd, sizeof(fwd)); fwd.listen_host = fwd.connect_host = NULL; - leave_raw_mode(force_tty_flag); + leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); handler = signal(SIGINT, SIG_IGN); cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); if (s == NULL) @@ -930,7 +927,7 @@ process_cmdline(void) out: signal(SIGINT, handler); - enter_raw_mode(force_tty_flag); + enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); if (cmd) xfree(cmd); if (fwd.listen_host != NULL) @@ -1049,7 +1046,8 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, * more new connections). */ /* Restore tty modes. */ - leave_raw_mode(force_tty_flag); + leave_raw_mode( + options.request_tty == REQUEST_TTY_FORCE); /* Stop listening for new connections. */ channel_stop_listening(); @@ -1344,7 +1342,7 @@ client_channel_closed(int id, void *arg) { channel_cancel_cleanup(id); session_closed = 1; - leave_raw_mode(force_tty_flag); + leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); } /* @@ -1415,7 +1413,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) signal(SIGWINCH, window_change_handler); if (have_pty) - enter_raw_mode(force_tty_flag); + enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); if (compat20) { session_ident = ssh2_chan_id; @@ -1559,7 +1557,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) channel_free_all(); if (have_pty) - leave_raw_mode(force_tty_flag); + leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); /* restore blocking io */ if (!isatty(fileno(stdin))) @@ -2142,7 +2140,7 @@ client_stop_mux(void) void cleanup_exit(int i) { - leave_raw_mode(force_tty_flag); + leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); leave_non_blocking(); if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); diff --git a/mux.c b/mux.c index fb24c0f97..1afd1bdf3 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.26 2011/05/05 05:12:08 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.27 2011/05/06 21:34:32 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -87,7 +87,6 @@ /* from ssh.c */ extern int tty_flag; -extern int force_tty_flag; extern Options options; extern int stdin_null_flag; extern char *host; @@ -1710,7 +1709,7 @@ mux_client_request_session(int fd) signal(SIGWINCH, control_client_sigrelay); if (tty_flag) - enter_raw_mode(force_tty_flag); + enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); /* * Stick around until the controlee closes the client_fd. @@ -1739,7 +1738,7 @@ mux_client_request_session(int fd) } close(fd); - leave_raw_mode(force_tty_flag); + leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); if (muxclient_terminate) { debug2("Exiting on signal %d", muxclient_terminate); diff --git a/readconf.c b/readconf.c index 927e7fefa..4780ae289 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.191 2011/05/06 21:31:38 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.192 2011/05/06 21:34:32 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -134,7 +134,7 @@ typedef enum { oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, - oKexAlgorithms, oIPQoS, + oKexAlgorithms, oIPQoS, oRequestTTY, oDeprecated, oUnsupported } OpCodes; @@ -245,6 +245,7 @@ static struct { #endif { "kexalgorithms", oKexAlgorithms }, { "ipqos", oIPQoS }, + { "requesttty", oRequestTTY }, { NULL, oBadOption } }; @@ -1013,6 +1014,26 @@ parse_int: intptr = &options->use_roaming; goto parse_flag; + case oRequestTTY: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%s line %d: missing argument.", + filename, linenum); + intptr = &options->request_tty; + if (strcasecmp(arg, "yes") == 0) + value = REQUEST_TTY_YES; + else if (strcasecmp(arg, "no") == 0) + value = REQUEST_TTY_NO; + else if (strcasecmp(arg, "force") == 0) + value = REQUEST_TTY_FORCE; + else if (strcasecmp(arg, "auto") == 0) + value = REQUEST_TTY_AUTO; + else + fatal("Unsupported RequestTTY \"%s\"", arg); + if (*activep && *intptr == -1) + *intptr = value; + break; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -1173,6 +1194,7 @@ initialize_options(Options * options) options->zero_knowledge_password_authentication = -1; options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; + options->request_tty = -1; } /* @@ -1331,6 +1353,8 @@ fill_default_options(Options * options) options->ip_qos_interactive = IPTOS_LOWDELAY; if (options->ip_qos_bulk == -1) options->ip_qos_bulk = IPTOS_THROUGHPUT; + if (options->request_tty == -1) + options->request_tty = REQUEST_TTY_AUTO; /* options->local_command should not be set by default */ /* options->proxy_command should not be set by default */ /* options->user will be set in the main program if appropriate */ diff --git a/readconf.h b/readconf.h index ee160dfe7..bc3e8c1bb 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.88 2010/11/13 23:27:50 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.89 2011/05/06 21:34:32 djm Exp $ */ /* * Author: Tatu Ylonen @@ -132,6 +132,7 @@ typedef struct { int use_roaming; + int request_tty; } Options; #define SSHCTL_MASTER_NO 0 @@ -140,6 +141,11 @@ typedef struct { #define SSHCTL_MASTER_ASK 3 #define SSHCTL_MASTER_AUTO_ASK 4 +#define REQUEST_TTY_AUTO 0 +#define REQUEST_TTY_NO 1 +#define REQUEST_TTY_YES 2 +#define REQUEST_TTY_FORCE 3 + void initialize_options(Options *); void fill_default_options(Options *); int read_config_file(const char *, const char *, Options *, int); diff --git a/ssh.c b/ssh.c index 549dd5c22..7243fa2a6 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.358 2011/05/06 21:18:02 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.359 2011/05/06 21:34:32 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -114,10 +114,8 @@ extern char *__progname; /* Flag indicating whether debug mode is on. May be set on the command line. */ int debug_flag = 0; -/* Flag indicating whether a tty should be allocated */ +/* Flag indicating whether a tty should be requested */ int tty_flag = 0; -int no_tty_flag = 0; -int force_tty_flag = 0; /* don't exec a shell */ int no_shell_flag = 0; @@ -135,7 +133,7 @@ int stdin_null_flag = 0; int need_controlpersist_detach = 0; /* Copies of flags for ControlPersist foreground slave */ -int ostdin_null_flag, ono_shell_flag, ono_tty_flag, otty_flag; +int ostdin_null_flag, ono_shell_flag, otty_flag, orequest_tty; /* * Flag indicating that ssh should fork after authentication. This is useful @@ -389,9 +387,10 @@ main(int ac, char **av) #endif break; case 't': - if (tty_flag) - force_tty_flag = 1; - tty_flag = 1; + if (options.request_tty == REQUEST_TTY_YES) + options.request_tty = REQUEST_TTY_FORCE; + else + options.request_tty = REQUEST_TTY_YES; break; case 'v': if (debug_flag == 0) { @@ -434,7 +433,7 @@ main(int ac, char **av) optarg); exit(255); } - no_tty_flag = 1; + options.request_tty = REQUEST_TTY_NO; no_shell_flag = 1; options.clear_forwardings = 1; options.exit_on_forward_failure = 1; @@ -543,10 +542,10 @@ main(int ac, char **av) break; case 'N': no_shell_flag = 1; - no_tty_flag = 1; + options.request_tty = REQUEST_TTY_NO; break; case 'T': - no_tty_flag = 1; + options.request_tty = REQUEST_TTY_NO; break; case 'o': dummy = 1; @@ -606,6 +605,10 @@ main(int ac, char **av) /* Initialize the command to execute on remote host. */ buffer_init(&command); + if (options.request_tty == REQUEST_TTY_YES || + options.request_tty == REQUEST_TTY_FORCE) + tty_flag = 1; + /* * Save the command to execute on the remote host in a buffer. There * is no limit on the length of the command, except by the maximum @@ -613,7 +616,7 @@ main(int ac, char **av) */ if (!ac) { /* No command specified - execute shell on a tty. */ - tty_flag = 1; + tty_flag = options.request_tty != REQUEST_TTY_NO; if (subsystem_flag) { fprintf(stderr, "You must specify a subsystem to invoke.\n"); @@ -636,13 +639,14 @@ main(int ac, char **av) /* Allocate a tty by default if no command specified. */ if (buffer_len(&command) == 0) - tty_flag = 1; + tty_flag = options.request_tty != REQUEST_TTY_NO; /* Force no tty */ - if (no_tty_flag || muxclient_command != 0) + if (options.request_tty == REQUEST_TTY_NO || muxclient_command != 0) tty_flag = 0; /* Do not allocate a tty if stdin is not a tty. */ - if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) { + if ((!isatty(fileno(stdin)) || stdin_null_flag) && + options.request_tty != REQUEST_TTY_FORCE) { if (tty_flag) logit("Pseudo-terminal will not be allocated because " "stdin is not a terminal."); @@ -946,8 +950,7 @@ control_persist_detach(void) /* Parent: set up mux slave to connect to backgrounded master */ debug2("%s: background process is %ld", __func__, (long)pid); stdin_null_flag = ostdin_null_flag; - no_shell_flag = ono_shell_flag; - no_tty_flag = ono_tty_flag; + options.request_tty = orequest_tty; tty_flag = otty_flag; close(muxserver_sock); muxserver_sock = -1; @@ -1394,11 +1397,11 @@ ssh_session2(void) if (options.control_persist && muxserver_sock != -1) { ostdin_null_flag = stdin_null_flag; ono_shell_flag = no_shell_flag; - ono_tty_flag = no_tty_flag; + orequest_tty = options.request_tty; otty_flag = tty_flag; stdin_null_flag = 1; no_shell_flag = 1; - no_tty_flag = 1; + options.request_tty == REQUEST_TTY_NO; tty_flag = 0; if (!fork_after_authentication_flag) need_controlpersist_detach = 1; diff --git a/ssh_config.5 b/ssh_config.5 index 5bdc7fec1..83baa82b1 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,7 +33,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.148 2011/05/06 21:31:38 djm Exp $ +.\" $OpenBSD: ssh_config.5,v 1.149 2011/05/06 21:34:32 djm Exp $ .Dd $Mdocdate: May 6 2011 $ .Dt SSH_CONFIG 5 .Os @@ -959,6 +959,23 @@ will only succeed if the server's .Cm GatewayPorts option is enabled (see .Xr sshd_config 5 ) . +.It Cm RequestTTY +Specifies whether to request a pseudo-tty for the session. +The argument may be one of: +.Dq no +(never request a TTY), +.Dq yes +(always request a TTY when standard input is a TTY), +.Dq force +(always request a TTY) or +.Dq auto +(request a TTY when opening a login session). +This option mirrors the +.Fl t +and +.Fl T +flags for +.Xr ssh 1 . .It Cm RhostsRSAAuthentication Specifies whether to try rhosts based authentication with RSA host authentication. -- cgit v1.2.3