]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: Add a ForkAfterAuthentication ssh_config(5) counterpart
authordjm@openbsd.org <djm@openbsd.org>
Fri, 23 Jul 2021 04:04:52 +0000 (04:04 +0000)
committerDamien Miller <djm@mindrot.org>
Fri, 23 Jul 2021 04:07:19 +0000 (14:07 +1000)
to the ssh(1) -f flag. Last part of GHPR231 from Volker Diels-Grabsch. ok
dtucker

OpenBSD-Commit-ID: b18aeda12efdebe2093d55263c90fe4ea0bce0d3

clientloop.c
readconf.c
readconf.h
ssh.1
ssh.c
ssh_config.5

index 7eb6b63bdd2724a78a728bd0adaf5f32c18aebaa..bfcd50c263fd78c730e27118bf348b4bfd456ab8 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.368 2021/07/23 04:00:59 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.369 2021/07/23 04:04:52 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /* import options */
 extern Options options;
 
-/* Flag indicating that ssh should daemonise after authentication is complete */
-extern int fork_after_authentication_flag;
-
 /* Control socket */
 extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
 
@@ -1240,7 +1237,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
                        fatal_f("pledge(): %s", strerror(errno));
 
        } else if (!option_clear_or_none(options.proxy_command) ||
-           fork_after_authentication_flag) {
+           options.fork_after_authentication) {
                debug("pledge: proc");
                if (pledge("stdio cpath unix inet dns proc tty", NULL) == -1)
                        fatal_f("pledge(): %s", strerror(errno));
index 681e78f76651edfe9c5929260dbf8823f2481f09..03369a0866e6c2469ee639543509c0f22c916cda 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.360 2021/07/23 04:00:59 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.361 2021/07/23 04:04:52 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -168,7 +168,7 @@ typedef enum {
        oLocalCommand, oPermitLocalCommand, oRemoteCommand,
        oVisualHostKey,
        oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull,
-       oIgnoreUnknown, oProxyUseFdpass,
+       oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass,
        oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
        oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
        oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
@@ -300,6 +300,7 @@ static struct {
        { "requesttty", oRequestTTY },
        { "sessiontype", oSessionType },
        { "stdinnull", oStdinNull },
+       { "forkafterauthentication", oForkAfterAuthentication },
        { "proxyusefdpass", oProxyUseFdpass },
        { "canonicaldomains", oCanonicalDomains },
        { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
@@ -1959,6 +1960,10 @@ parse_pubkey_algos:
                intptr = &options->stdin_null;
                goto parse_flag;
 
+       case oForkAfterAuthentication:
+               intptr = &options->fork_after_authentication;
+               goto parse_flag;
+
        case oIgnoreUnknown:
                charptr = &options->ignored_unknown;
                goto parse_string;
@@ -2383,6 +2388,7 @@ initialize_options(Options * options)
        options->request_tty = -1;
        options->session_type = -1;
        options->stdin_null = -1;
+       options->fork_after_authentication = -1;
        options->proxy_use_fdpass = -1;
        options->ignored_unknown = NULL;
        options->num_canonical_domains = 0;
@@ -2573,6 +2579,8 @@ fill_default_options(Options * options)
                options->session_type = SESSION_TYPE_DEFAULT;
        if (options->stdin_null == -1)
                options->stdin_null = 0;
+       if (options->fork_after_authentication == -1)
+               options->fork_after_authentication = 0;
        if (options->proxy_use_fdpass == -1)
                options->proxy_use_fdpass = 0;
        if (options->canonicalize_max_dots == -1)
@@ -3252,6 +3260,7 @@ dump_client_config(Options *o, const char *host)
        dump_cfg_fmtint(oRequestTTY, o->request_tty);
        dump_cfg_fmtint(oSessionType, o->session_type);
        dump_cfg_fmtint(oStdinNull, o->stdin_null);
+       dump_cfg_fmtint(oForkAfterAuthentication, o->fork_after_authentication);
        dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
        dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
        dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
index 08ca9e7a7d613a4ced212bde73be7d249a1f0b6f..f7d53b067604e39e9101f43bfc8f2b632239d4c9 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.143 2021/07/23 04:00:59 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.144 2021/07/23 04:04:52 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -148,6 +148,7 @@ typedef struct {
        int     request_tty;
        int     session_type;
        int     stdin_null;
+       int     fork_after_authentication;
 
        int     proxy_use_fdpass;
 
diff --git a/ssh.1 b/ssh.1
index b31175ffeb3b4cb6f264806d749020c31144be05..46ad55ad498935085bd44cffb21b3c7eb76c4305 100644 (file)
--- a/ssh.1
+++ b/ssh.1
@@ -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.1,v 1.423 2021/07/23 04:00:59 djm Exp $
+.\" $OpenBSD: ssh.1,v 1.424 2021/07/23 04:04:52 djm Exp $
 .Dd $Mdocdate: July 23 2021 $
 .Dt SSH 1
 .Os
@@ -259,6 +259,11 @@ then a client started with
 .Fl f
 will wait for all remote port forwards to be successfully established
 before placing itself in the background.
+Refer to the description of
+.Cm ForkAfterAuthentication
+in
+.Xr ssh_config 5
+for details.
 .Pp
 .It Fl G
 Causes
@@ -508,6 +513,7 @@ For full details of the options listed below, and their possible values, see
 .It EscapeChar
 .It ExitOnForwardFailure
 .It FingerprintHash
+.It ForkAfterAuthentication
 .It ForwardAgent
 .It ForwardX11
 .It ForwardX11Timeout
diff --git a/ssh.c b/ssh.c
index 8a5aaa7ef03eaca4a52a01ddfcee0ee658120b5e..62a64ecc19fb7e1a27bb0d4bdfe5051c893923f1 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.563 2021/07/23 04:00:59 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.564 2021/07/23 04:04:52 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -135,13 +135,6 @@ int need_controlpersist_detach = 0;
 /* Copies of flags for ControlPersist foreground mux-client */
 int ostdin_null_flag, osession_type, otty_flag, orequest_tty;
 
-/*
- * Flag indicating that ssh should fork after authentication.  This is useful
- * so that the passphrase can be entered manually, and then ssh goes to the
- * background.
- */
-int fork_after_authentication_flag = 0;
-
 /*
  * General data structure for command line options and options configurable
  * in configuration files.  See readconf.h.
@@ -720,7 +713,7 @@ main(int ac, char **av)
                        options.stdin_null = 1;
                        break;
                case 'f':
-                       fork_after_authentication_flag = 1;
+                       options.fork_after_authentication = 1;
                        options.stdin_null = 1;
                        break;
                case 'x':
@@ -1324,7 +1317,7 @@ main(int ac, char **av)
                fatal("Cannot execute command-line and remote command.");
 
        /* Cannot fork to background if no command. */
-       if (fork_after_authentication_flag && sshbuf_len(command) == 0 &&
+       if (options.fork_after_authentication && sshbuf_len(command) == 0 &&
            options.remote_command == NULL &&
            options.session_type != SESSION_TYPE_NONE)
                fatal("Cannot fork into background without a command "
@@ -1752,7 +1745,7 @@ fork_postauth(void)
        if (need_controlpersist_detach)
                control_persist_detach();
        debug("forking to background");
-       fork_after_authentication_flag = 0;
+       options.fork_after_authentication = 0;
        if (daemon(1, 1) == -1)
                fatal("daemon() failed: %.200s", strerror(errno));
        if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag)) == -1)
@@ -1766,7 +1759,7 @@ forwarding_success(void)
                return;
        if (--forward_confirms_pending == 0) {
                debug_f("all expected forwarding replies received");
-               if (fork_after_authentication_flag)
+               if (options.fork_after_authentication)
                        fork_postauth();
        } else {
                debug2_f("%d expected forwarding replies remaining",
@@ -2145,11 +2138,11 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo)
                options.stdin_null = 1;
                options.session_type = SESSION_TYPE_NONE;
                tty_flag = 0;
-               if (!fork_after_authentication_flag &&
+               if (!options.fork_after_authentication &&
                    (osession_type != SESSION_TYPE_NONE ||
                    options.stdio_forward_host != NULL))
                        need_controlpersist_detach = 1;
-               fork_after_authentication_flag = 1;
+               options.fork_after_authentication = 1;
        }
        /*
         * ControlPersist mux listen socket setup failed, attempt the
@@ -2196,7 +2189,7 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo)
         * If requested and we are not interested in replies to remote
         * forwarding requests, then let ssh continue in the background.
         */
-       if (fork_after_authentication_flag) {
+       if (options.fork_after_authentication) {
                if (options.exit_on_forward_failure &&
                    options.num_remote_forwards > 0) {
                        debug("deferring postauth fork until remote forward "
index eb417c95afb3bb75840a37f289881a8041348201..94a7ea14d172503fdc5c2cca1c94949dd67fe92a 100644 (file)
@@ -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.358 2021/07/23 04:00:59 djm Exp $
+.\" $OpenBSD: ssh_config.5,v 1.359 2021/07/23 04:04:52 djm Exp $
 .Dd $Mdocdate: July 23 2021 $
 .Dt SSH_CONFIG 5
 .Os
@@ -676,6 +676,45 @@ Valid options are:
 and
 .Cm sha256
 (the default).
+.It Cm ForkAfterAuthentication
+Requests
+.Nm ssh
+to go to background just before command execution.
+This is useful if
+.Nm ssh
+is going to ask for passwords or passphrases, but the user
+wants it in the background.
+This implies the
+.Cm StdinNull
+configuration option being set to
+.Dq yes .
+The recommended way to start X11 programs at a remote site is with
+something like
+.Ic ssh -f host xterm ,
+which is the same as
+.Ic ssh host xterm
+if the
+.Cm ForkAfterAuthentication
+configuration option is set to
+.Dq yes .
+.Pp
+If the
+.Cm ExitOnForwardFailure
+configuration option is set to
+.Dq yes ,
+then a client started with the
+.Cm ForkAfterAuthentication
+configuration option being set to
+.Dq yes
+will wait for all remote port forwards to be successfully established
+before placing itself in the background.
+The argument to this keyword must be
+.Cm yes
+(same as the
+.Fl f
+option) or
+.Cm no
+(the default).
 .It Cm ForwardAgent
 Specifies whether the connection to the authentication agent (if any)
 will be forwarded to the remote machine.