Skip to content

Commit

Permalink
Add ssh_config option ForkAfterAuthentication with same behavior as -f
Browse files Browse the repository at this point in the history
  • Loading branch information
vog committed Mar 9, 2021
1 parent 97b3eb8 commit 792101d
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 21 deletions.
5 changes: 1 addition & 4 deletions clientloop.c
Expand Up @@ -115,9 +115,6 @@
/* 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 */

Expand Down Expand Up @@ -1238,7 +1235,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));
Expand Down
11 changes: 10 additions & 1 deletion readconf.c
Expand Up @@ -168,7 +168,7 @@ typedef enum {
oLocalCommand, oPermitLocalCommand, oRemoteCommand,
oVisualHostKey,
oKexAlgorithms, oIPQoS, oRequestTTY, oNoShell, oStdinNull,
oIgnoreUnknown, oProxyUseFdpass,
oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass,
oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
Expand Down Expand Up @@ -300,6 +300,7 @@ static struct {
{ "requesttty", oRequestTTY },
{ "noshell", oNoShell },
{ "stdinnull", oStdinNull },
{ "forkafterauthentication", oForkAfterAuthentication },
{ "proxyusefdpass", oProxyUseFdpass },
{ "canonicaldomains", oCanonicalDomains },
{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
Expand Down Expand Up @@ -1872,6 +1873,10 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
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;
Expand Down Expand Up @@ -2275,6 +2280,7 @@ initialize_options(Options * options)
options->request_tty = -1;
options->no_shell = -1;
options->stdin_null = -1;
options->fork_after_authentication = -1;
options->proxy_use_fdpass = -1;
options->ignored_unknown = NULL;
options->num_canonical_domains = 0;
Expand Down Expand Up @@ -2467,6 +2473,8 @@ fill_default_options(Options * options)
options->no_shell = 0;
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)
Expand Down Expand Up @@ -3134,6 +3142,7 @@ dump_client_config(Options *o, const char *host)
dump_cfg_fmtint(oRequestTTY, o->request_tty);
dump_cfg_fmtint(oNoShell, o->no_shell);
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);
Expand Down
1 change: 1 addition & 0 deletions readconf.h
Expand Up @@ -150,6 +150,7 @@ typedef struct {
int request_tty;
int no_shell;
int stdin_null;
int fork_after_authentication;

int proxy_use_fdpass;

Expand Down
5 changes: 5 additions & 0 deletions ssh.1
Expand Up @@ -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
Expand Down
21 changes: 7 additions & 14 deletions ssh.c
Expand Up @@ -135,13 +135,6 @@ int need_controlpersist_detach = 0;
/* Copies of flags for ControlPersist foreground mux-client */
int ostdin_null_flag, 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.
Expand Down Expand Up @@ -721,7 +714,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':
Expand Down Expand Up @@ -1319,7 +1312,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.no_shell)
fatal("Cannot fork into background without a command "
"to execute.");
Expand Down Expand Up @@ -1738,7 +1731,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)
Expand All @@ -1752,7 +1745,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",
Expand Down Expand Up @@ -2133,9 +2126,9 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo)
options.stdin_null = 1;
options.no_shell = 1;
tty_flag = 0;
if (!fork_after_authentication_flag)
if (!options.fork_after_authentication)
need_controlpersist_detach = 1;
fork_after_authentication_flag = 1;
options.fork_after_authentication = 1;
}
/*
* ControlPersist mux listen socket setup failed, attempt the
Expand Down Expand Up @@ -2182,7 +2175,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 "
Expand Down
43 changes: 41 additions & 2 deletions ssh_config.5
Expand Up @@ -682,6 +682,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.
Expand Down Expand Up @@ -1690,8 +1729,8 @@ program will be put in the background.
(This does not work if
.Nm ssh
needs to ask for a password or passphrase; see also the
.Fl f
option.)
.Cm ForkAfterAuthentication
configuration option.)
The argument to this keyword must be
.Cm yes
(same as the
Expand Down

0 comments on commit 792101d

Please sign in to comment.