Add RemoteCommand option to specify a command in the ssh config
authorbluhm <bluhm@openbsd.org>
Tue, 30 May 2017 18:58:37 +0000 (18:58 +0000)
committerbluhm <bluhm@openbsd.org>
Tue, 30 May 2017 18:58:37 +0000 (18:58 +0000)
file instead of giving it on the client's command line.  This command
will be executed on the remote host.  The feature allows to automate
tasks using ssh config.
OK markus@

usr.bin/ssh/readconf.c
usr.bin/ssh/readconf.h
usr.bin/ssh/ssh.1
usr.bin/ssh/ssh.c
usr.bin/ssh/ssh_config.5

index 7b4160e..b9a7f7c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.276 2017/05/20 02:35:47 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.277 2017/05/30 18:58:37 bluhm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -148,7 +148,8 @@ typedef enum {
        oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
        oSendEnv, oControlPath, oControlMaster, oControlPersist,
        oHashKnownHosts,
-       oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
+       oTunnel, oTunnelDevice,
+       oLocalCommand, oPermitLocalCommand, oRemoteCommand,
        oVisualHostKey,
        oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
        oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
@@ -269,6 +270,7 @@ static struct {
        { "tunneldevice", oTunnelDevice },
        { "localcommand", oLocalCommand },
        { "permitlocalcommand", oPermitLocalCommand },
+       { "remotecommand", oRemoteCommand },
        { "visualhostkey", oVisualHostKey },
        { "kexalgorithms", oKexAlgorithms },
        { "ipqos", oIPQoS },
@@ -1425,6 +1427,10 @@ parse_keytypes:
                intptr = &options->permit_local_command;
                goto parse_flag;
 
+       case oRemoteCommand:
+               charptr = &options->remote_command;
+               goto parse_command;
+
        case oVisualHostKey:
                intptr = &options->visual_host_key;
                goto parse_flag;
@@ -1813,6 +1819,7 @@ initialize_options(Options * options)
        options->tun_remote = -1;
        options->local_command = NULL;
        options->permit_local_command = -1;
+       options->remote_command = NULL;
        options->add_keys_to_agent = -1;
        options->identity_agent = NULL;
        options->visual_host_key = -1;
@@ -2015,6 +2022,7 @@ fill_default_options(Options * options)
                } \
        } while(0)
        CLEAR_ON_NONE(options->local_command);
+       CLEAR_ON_NONE(options->remote_command);
        CLEAR_ON_NONE(options->proxy_command);
        CLEAR_ON_NONE(options->control_path);
        CLEAR_ON_NONE(options->revoked_host_keys);
@@ -2492,6 +2500,7 @@ dump_client_config(Options *o, const char *host)
        dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
        dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
        dump_cfg_string(oLocalCommand, o->local_command);
+       dump_cfg_string(oRemoteCommand, o->remote_command);
        dump_cfg_string(oLogLevel, log_level_name(o->log_level));
        dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
 #ifdef ENABLE_PKCS11
index f47f534..94dd427 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.121 2017/04/30 23:18:22 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.122 2017/05/30 18:58:37 bluhm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -134,6 +134,7 @@ typedef struct {
 
        char    *local_command;
        int     permit_local_command;
+       char    *remote_command;
        int     visual_host_key;
 
        int     request_tty;
index 10633d9..47cd021 100644 (file)
@@ -33,8 +33,8 @@
 .\" (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.1,v 1.381 2017/05/05 10:41:58 naddy Exp $
-.Dd $Mdocdate: May 5 2017 $
+.\" $OpenBSD: ssh.1,v 1.382 2017/05/30 18:58:37 bluhm Exp $
+.Dd $Mdocdate: May 30 2017 $
 .Dt SSH 1
 .Os
 .Sh NAME
@@ -518,6 +518,7 @@ For full details of the options listed below, and their possible values, see
 .It PubkeyAcceptedKeyTypes
 .It PubkeyAuthentication
 .It RekeyLimit
+.It RemoteCommand
 .It RemoteForward
 .It RequestTTY
 .It SendEnv
index 2cb6a1d..61fbd28 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.460 2017/05/30 08:52:19 markus Exp $ */
+/* $OpenBSD: ssh.c,v 1.461 2017/05/30 18:58:37 bluhm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -942,12 +942,6 @@ main(int ac, char **av)
                }
        }
 
-       /* Cannot fork to background if no command. */
-       if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
-           !no_shell_flag)
-               fatal("Cannot fork into background without a command "
-                   "to execute.");
-
        /*
         * Initialize "log" output.  Since we are the client all output
         * goes to stderr unless otherwise specified by -y or -E.
@@ -1101,6 +1095,15 @@ main(int ac, char **av)
        if (original_effective_uid != 0)
                options.use_privileged_port = 0;
 
+       if (buffer_len(&command) != 0 && options.remote_command != NULL)
+               fatal("Cannot execute command-line and remote command.");
+
+       /* Cannot fork to background if no command. */
+       if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
+           options.remote_command == NULL && !no_shell_flag)
+               fatal("Cannot fork into background without a command "
+                   "to execute.");
+
        /* reinit */
        log_init(argv0, options.log_level, options.log_facility, !use_syslog);
 
@@ -1109,7 +1112,7 @@ main(int ac, char **av)
                tty_flag = 1;
 
        /* Allocate a tty by default if no command specified. */
-       if (buffer_len(&command) == 0)
+       if (buffer_len(&command) == 0 && options.remote_command == NULL)
                tty_flag = options.request_tty != REQUEST_TTY_NO;
 
        /* Force no tty */
@@ -1163,6 +1166,27 @@ main(int ac, char **av)
                free(cp);
        }
 
+       if (options.remote_command != NULL) {
+               debug3("expanding RemoteCommand: %s", options.remote_command);
+               cp = options.remote_command;
+               options.remote_command = percent_expand(cp,
+                   "C", conn_hash_hex,
+                   "L", shorthost,
+                   "d", pw->pw_dir,
+                   "h", host,
+                   "l", thishost,
+                   "n", host_arg,
+                   "p", portstr,
+                   "r", options.user,
+                   "u", pw->pw_name,
+                   (char *)NULL);
+               debug3("expanded RemoteCommand: %s", options.remote_command);
+               free(cp);
+               buffer_append(&command, options.remote_command,
+                   strlen(options.remote_command));
+
+       }
+
        if (options.control_path != NULL) {
                cp = tilde_expand_filename(options.control_path,
                    original_real_uid);
index db37b92..2c9e20f 100644 (file)
@@ -33,8 +33,8 @@
 .\" (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.248 2017/05/07 23:12:57 djm Exp $
-.Dd $Mdocdate: May 7 2017 $
+.\" $OpenBSD: ssh_config.5,v 1.249 2017/05/30 18:58:37 bluhm Exp $
+.Dd $Mdocdate: May 30 2017 $
 .Dt SSH_CONFIG 5
 .Os
 .Sh NAME
@@ -1287,6 +1287,14 @@ is
 .Cm default none ,
 which means that rekeying is performed after the cipher's default amount
 of data has been sent or received and no time based rekeying is done.
+.It Cm RemoteCommand
+Specifies a command to execute on the remote machine after successfully
+connecting to the server.
+The command string extends to the end of the line, and is executed with
+the user's shell.
+The same escape character substitutions as for
+.Cm LocalCommand
+will be performed.
 .It Cm RemoteForward
 Specifies that a TCP port on the remote machine be forwarded over
 the secure channel to the specified host and port from the local machine.