upstream: let ssh_config(5)'s AddKeysToAgent keyword accept a time

limit for keys in addition to its current flag options. Time-limited keys
will automatically be removed from ssh-agent after their expiry time has
passed; ok markus@

OpenBSD-Commit-ID: 792e71cacbbc25faab5424cf80bee4a006119f94
This commit is contained in:
djm@openbsd.org 2020-08-11 09:49:57 +00:00 committed by Damien Miller
parent e9c2002891
commit d0a195c89e
4 changed files with 89 additions and 27 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.333 2020/07/17 07:09:24 dtucker Exp $ */ /* $OpenBSD: readconf.c,v 1.334 2020/08/11 09:49:57 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -877,6 +877,21 @@ static const struct multistate multistate_compression[] = {
{ NULL, -1 } { NULL, -1 }
}; };
static int
parse_multistate_value(const char *arg, const char *filename, int linenum,
const struct multistate *multistate_ptr)
{
int i;
if (!arg || *arg == '\0')
fatal("%s line %d: missing argument.", filename, linenum);
for (i = 0; multistate_ptr[i].key != NULL; i++) {
if (strcasecmp(arg, multistate_ptr[i].key) == 0)
return multistate_ptr[i].value;
}
return -1;
}
/* /*
* Processes a single option line as used in the configuration files. This * Processes a single option line as used in the configuration files. This
* only sets those values that have not already been set. * only sets those values that have not already been set.
@ -1000,19 +1015,11 @@ parse_time:
multistate_ptr = multistate_flag; multistate_ptr = multistate_flag;
parse_multistate: parse_multistate:
arg = strdelim(&s); arg = strdelim(&s);
if (!arg || *arg == '\0') if ((value = parse_multistate_value(arg, filename, linenum,
fatal("%s line %d: missing argument.", multistate_ptr)) == -1) {
filename, linenum);
value = -1;
for (i = 0; multistate_ptr[i].key != NULL; i++) {
if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
value = multistate_ptr[i].value;
break;
}
}
if (value == -1)
fatal("%s line %d: unsupported option \"%s\".", fatal("%s line %d: unsupported option \"%s\".",
filename, linenum, arg); filename, linenum, arg);
}
if (*activep && *intptr == -1) if (*activep && *intptr == -1)
*intptr = value; *intptr = value;
break; break;
@ -1800,9 +1807,42 @@ parse_keytypes:
goto parse_keytypes; goto parse_keytypes;
case oAddKeysToAgent: case oAddKeysToAgent:
intptr = &options->add_keys_to_agent; arg = strdelim(&s);
multistate_ptr = multistate_yesnoaskconfirm; arg2 = strdelim(&s);
goto parse_multistate; value = parse_multistate_value(arg, filename, linenum,
multistate_yesnoaskconfirm);
value2 = 0; /* unlimited lifespan by default */
if (value == 3 && arg2 != NULL) {
/* allow "AddKeysToAgent confirm 5m" */
if ((value2 = convtime(arg2)) == -1 || value2 > INT_MAX)
fatal("%s line %d: invalid time value.",
filename, linenum);
} else if (value == -1 && arg2 == NULL) {
if ((value2 = convtime(arg)) == -1 || value2 > INT_MAX)
fatal("%s line %d: unsupported option",
filename, linenum);
value = 1; /* yes */
} else if (value == -1 || arg2 != NULL) {
fatal("%s line %d: unsupported option",
filename, linenum);
}
if (*activep && options->add_keys_to_agent == -1) {
options->add_keys_to_agent = value;
options->add_keys_to_agent_lifespan = value2;
}
break;
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%s line %d: missing time value.",
filename, linenum);
if (strcmp(arg, "none") == 0)
value = -1;
else if ((value = convtime(arg)) == -1 || value > INT_MAX)
fatal("%s line %d: invalid time value.",
filename, linenum);
if (*activep && *intptr == -1)
*intptr = value;
case oIdentityAgent: case oIdentityAgent:
charptr = &options->identity_agent; charptr = &options->identity_agent;
@ -2016,6 +2056,7 @@ initialize_options(Options * options)
options->permit_local_command = -1; options->permit_local_command = -1;
options->remote_command = NULL; options->remote_command = NULL;
options->add_keys_to_agent = -1; options->add_keys_to_agent = -1;
options->add_keys_to_agent_lifespan = -1;
options->identity_agent = NULL; options->identity_agent = NULL;
options->visual_host_key = -1; options->visual_host_key = -1;
options->ip_qos_interactive = -1; options->ip_qos_interactive = -1;
@ -2123,8 +2164,10 @@ fill_default_options(Options * options)
if (options->number_of_password_prompts == -1) if (options->number_of_password_prompts == -1)
options->number_of_password_prompts = 3; options->number_of_password_prompts = 3;
/* options->hostkeyalgorithms, default set in myproposals.h */ /* options->hostkeyalgorithms, default set in myproposals.h */
if (options->add_keys_to_agent == -1) if (options->add_keys_to_agent == -1) {
options->add_keys_to_agent = 0; options->add_keys_to_agent = 0;
options->add_keys_to_agent_lifespan = 0;
}
if (options->num_identity_files == 0) { if (options->num_identity_files == 0) {
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0); add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0); add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
@ -2728,7 +2771,6 @@ dump_client_config(Options *o, const char *host)
dump_cfg_int(oPort, o->port); dump_cfg_int(oPort, o->port);
/* Flag options */ /* Flag options */
dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
dump_cfg_fmtint(oAddressFamily, o->address_family); dump_cfg_fmtint(oAddressFamily, o->address_family);
dump_cfg_fmtint(oBatchMode, o->batch_mode); dump_cfg_fmtint(oBatchMode, o->batch_mode);
dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
@ -2816,6 +2858,15 @@ dump_client_config(Options *o, const char *host)
/* Special cases */ /* Special cases */
/* AddKeysToAgent */
if (o->add_keys_to_agent_lifespan <= 0)
dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
else {
printf("addkeystoagent%s %d\n",
o->add_keys_to_agent == 3 ? " confirm" : "",
o->add_keys_to_agent_lifespan);
}
/* oForwardAgent */ /* oForwardAgent */
if (o->forward_agent_sock_path == NULL) if (o->forward_agent_sock_path == NULL)
dump_cfg_fmtint(oForwardAgent, o->forward_agent); dump_cfg_fmtint(oForwardAgent, o->forward_agent);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.h,v 1.133 2020/04/03 02:27:12 dtucker Exp $ */ /* $OpenBSD: readconf.h,v 1.134 2020/08/11 09:49:57 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -97,6 +97,7 @@ typedef struct {
struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
int add_keys_to_agent; int add_keys_to_agent;
int add_keys_to_agent_lifespan;
char *identity_agent; /* Optional path to ssh-agent socket */ char *identity_agent; /* Optional path to ssh-agent socket */
/* Local TCP/IP forward requests. */ /* Local TCP/IP forward requests. */

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: ssh_config.5,v 1.331 2020/07/17 05:59:05 jmc Exp $ .\" $OpenBSD: ssh_config.5,v 1.332 2020/08/11 09:49:57 djm Exp $
.Dd $Mdocdate: July 17 2020 $ .Dd $Mdocdate: August 11 2020 $
.Dt SSH_CONFIG 5 .Dt SSH_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -245,13 +245,22 @@ option was specified to
If this option is set to If this option is set to
.Cm no , .Cm no ,
no keys are added to the agent. no keys are added to the agent.
Alternately, this option may be specified as a time interval
using the format described in the
.Sx TIME FORMATS
section of
.Xr sshd_config 5
to specify the key's lifetime in
.Xr ssh-agent 1 ,
after which it will automatically be removed.
The argument must be The argument must be
.Cm yes ,
.Cm confirm ,
.Cm ask ,
or
.Cm no .Cm no
(the default). (the default),
.Cm yes ,
.Cm confirm
(optionally followed by a time interval),
.Cm ask
or a time interval.
.It Cm AddressFamily .It Cm AddressFamily
Specifies which address family to use when connecting. Specifies which address family to use when connecting.
Valid arguments are Valid arguments are

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.330 2020/07/17 03:43:42 dtucker Exp $ */ /* $OpenBSD: sshconnect.c,v 1.331 2020/08/11 09:49:57 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1433,7 +1433,8 @@ maybe_add_key_to_agent(const char *authfile, struct sshkey *private,
if (sshkey_is_sk(private)) if (sshkey_is_sk(private))
skprovider = options.sk_provider; skprovider = options.sk_provider;
if ((r = ssh_add_identity_constrained(auth_sock, private, if ((r = ssh_add_identity_constrained(auth_sock, private,
comment == NULL ? authfile : comment, 0, comment == NULL ? authfile : comment,
options.add_keys_to_agent_lifespan,
(options.add_keys_to_agent == 3), 0, skprovider)) == 0) (options.add_keys_to_agent == 3), 0, skprovider)) == 0)
debug("identity added to agent: %s", authfile); debug("identity added to agent: %s", authfile);
else else