summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-08-11 09:49:57 +0000
committerDamien Miller <djm@mindrot.org>2020-08-27 11:27:01 +1000
commitd0a195c89e26766d3eb8f3e4e2a00ebc98b57795 (patch)
tree4479d2c36da47752ca6b09bfc8dc4a0e6d2af97c
parente9c2002891a7b8e66f4140557a982978f372e5a3 (diff)
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
-rw-r--r--readconf.c85
-rw-r--r--readconf.h3
-rw-r--r--ssh_config.523
-rw-r--r--sshconnect.c5
4 files changed, 89 insertions, 27 deletions
diff --git a/readconf.c b/readconf.c
index a810736a4..94b67e1c6 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.333 2020/07/17 07:09:24 dtucker Exp $ */ 1/* $OpenBSD: readconf.c,v 1.334 2020/08/11 09:49:57 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -877,6 +877,21 @@ static const struct multistate multistate_compression[] = {
877 { NULL, -1 } 877 { NULL, -1 }
878}; 878};
879 879
880static int
881parse_multistate_value(const char *arg, const char *filename, int linenum,
882 const struct multistate *multistate_ptr)
883{
884 int i;
885
886 if (!arg || *arg == '\0')
887 fatal("%s line %d: missing argument.", filename, linenum);
888 for (i = 0; multistate_ptr[i].key != NULL; i++) {
889 if (strcasecmp(arg, multistate_ptr[i].key) == 0)
890 return multistate_ptr[i].value;
891 }
892 return -1;
893}
894
880/* 895/*
881 * Processes a single option line as used in the configuration files. This 896 * Processes a single option line as used in the configuration files. This
882 * only sets those values that have not already been set. 897 * only sets those values that have not already been set.
@@ -1000,19 +1015,11 @@ parse_time:
1000 multistate_ptr = multistate_flag; 1015 multistate_ptr = multistate_flag;
1001 parse_multistate: 1016 parse_multistate:
1002 arg = strdelim(&s); 1017 arg = strdelim(&s);
1003 if (!arg || *arg == '\0') 1018 if ((value = parse_multistate_value(arg, filename, linenum,
1004 fatal("%s line %d: missing argument.", 1019 multistate_ptr)) == -1) {
1005 filename, linenum);
1006 value = -1;
1007 for (i = 0; multistate_ptr[i].key != NULL; i++) {
1008 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1009 value = multistate_ptr[i].value;
1010 break;
1011 }
1012 }
1013 if (value == -1)
1014 fatal("%s line %d: unsupported option \"%s\".", 1020 fatal("%s line %d: unsupported option \"%s\".",
1015 filename, linenum, arg); 1021 filename, linenum, arg);
1022 }
1016 if (*activep && *intptr == -1) 1023 if (*activep && *intptr == -1)
1017 *intptr = value; 1024 *intptr = value;
1018 break; 1025 break;
@@ -1800,9 +1807,42 @@ parse_keytypes:
1800 goto parse_keytypes; 1807 goto parse_keytypes;
1801 1808
1802 case oAddKeysToAgent: 1809 case oAddKeysToAgent:
1803 intptr = &options->add_keys_to_agent; 1810 arg = strdelim(&s);
1804 multistate_ptr = multistate_yesnoaskconfirm; 1811 arg2 = strdelim(&s);
1805 goto parse_multistate; 1812 value = parse_multistate_value(arg, filename, linenum,
1813 multistate_yesnoaskconfirm);
1814 value2 = 0; /* unlimited lifespan by default */
1815 if (value == 3 && arg2 != NULL) {
1816 /* allow "AddKeysToAgent confirm 5m" */
1817 if ((value2 = convtime(arg2)) == -1 || value2 > INT_MAX)
1818 fatal("%s line %d: invalid time value.",
1819 filename, linenum);
1820 } else if (value == -1 && arg2 == NULL) {
1821 if ((value2 = convtime(arg)) == -1 || value2 > INT_MAX)
1822 fatal("%s line %d: unsupported option",
1823 filename, linenum);
1824 value = 1; /* yes */
1825 } else if (value == -1 || arg2 != NULL) {
1826 fatal("%s line %d: unsupported option",
1827 filename, linenum);
1828 }
1829 if (*activep && options->add_keys_to_agent == -1) {
1830 options->add_keys_to_agent = value;
1831 options->add_keys_to_agent_lifespan = value2;
1832 }
1833 break;
1834
1835 arg = strdelim(&s);
1836 if (!arg || *arg == '\0')
1837 fatal("%s line %d: missing time value.",
1838 filename, linenum);
1839 if (strcmp(arg, "none") == 0)
1840 value = -1;
1841 else if ((value = convtime(arg)) == -1 || value > INT_MAX)
1842 fatal("%s line %d: invalid time value.",
1843 filename, linenum);
1844 if (*activep && *intptr == -1)
1845 *intptr = value;
1806 1846
1807 case oIdentityAgent: 1847 case oIdentityAgent:
1808 charptr = &options->identity_agent; 1848 charptr = &options->identity_agent;
@@ -2016,6 +2056,7 @@ initialize_options(Options * options)
2016 options->permit_local_command = -1; 2056 options->permit_local_command = -1;
2017 options->remote_command = NULL; 2057 options->remote_command = NULL;
2018 options->add_keys_to_agent = -1; 2058 options->add_keys_to_agent = -1;
2059 options->add_keys_to_agent_lifespan = -1;
2019 options->identity_agent = NULL; 2060 options->identity_agent = NULL;
2020 options->visual_host_key = -1; 2061 options->visual_host_key = -1;
2021 options->ip_qos_interactive = -1; 2062 options->ip_qos_interactive = -1;
@@ -2123,8 +2164,10 @@ fill_default_options(Options * options)
2123 if (options->number_of_password_prompts == -1) 2164 if (options->number_of_password_prompts == -1)
2124 options->number_of_password_prompts = 3; 2165 options->number_of_password_prompts = 3;
2125 /* options->hostkeyalgorithms, default set in myproposals.h */ 2166 /* options->hostkeyalgorithms, default set in myproposals.h */
2126 if (options->add_keys_to_agent == -1) 2167 if (options->add_keys_to_agent == -1) {
2127 options->add_keys_to_agent = 0; 2168 options->add_keys_to_agent = 0;
2169 options->add_keys_to_agent_lifespan = 0;
2170 }
2128 if (options->num_identity_files == 0) { 2171 if (options->num_identity_files == 0) {
2129 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0); 2172 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
2130 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0); 2173 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
@@ -2728,7 +2771,6 @@ dump_client_config(Options *o, const char *host)
2728 dump_cfg_int(oPort, o->port); 2771 dump_cfg_int(oPort, o->port);
2729 2772
2730 /* Flag options */ 2773 /* Flag options */
2731 dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
2732 dump_cfg_fmtint(oAddressFamily, o->address_family); 2774 dump_cfg_fmtint(oAddressFamily, o->address_family);
2733 dump_cfg_fmtint(oBatchMode, o->batch_mode); 2775 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2734 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); 2776 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
@@ -2816,6 +2858,15 @@ dump_client_config(Options *o, const char *host)
2816 2858
2817 /* Special cases */ 2859 /* Special cases */
2818 2860
2861 /* AddKeysToAgent */
2862 if (o->add_keys_to_agent_lifespan <= 0)
2863 dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
2864 else {
2865 printf("addkeystoagent%s %d\n",
2866 o->add_keys_to_agent == 3 ? " confirm" : "",
2867 o->add_keys_to_agent_lifespan);
2868 }
2869
2819 /* oForwardAgent */ 2870 /* oForwardAgent */
2820 if (o->forward_agent_sock_path == NULL) 2871 if (o->forward_agent_sock_path == NULL)
2821 dump_cfg_fmtint(oForwardAgent, o->forward_agent); 2872 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
diff --git a/readconf.h b/readconf.h
index e143a1082..d6a15550d 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.133 2020/04/03 02:27:12 dtucker Exp $ */ 1/* $OpenBSD: readconf.h,v 1.134 2020/08/11 09:49:57 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -97,6 +97,7 @@ typedef struct {
97 struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; 97 struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
98 98
99 int add_keys_to_agent; 99 int add_keys_to_agent;
100 int add_keys_to_agent_lifespan;
100 char *identity_agent; /* Optional path to ssh-agent socket */ 101 char *identity_agent; /* Optional path to ssh-agent socket */
101 102
102 /* Local TCP/IP forward requests. */ 103 /* Local TCP/IP forward requests. */
diff --git a/ssh_config.5 b/ssh_config.5
index 2b635410f..6be1f1aa2 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh_config.5,v 1.331 2020/07/17 05:59:05 jmc Exp $ 36.\" $OpenBSD: ssh_config.5,v 1.332 2020/08/11 09:49:57 djm Exp $
37.Dd $Mdocdate: July 17 2020 $ 37.Dd $Mdocdate: August 11 2020 $
38.Dt SSH_CONFIG 5 38.Dt SSH_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -245,13 +245,22 @@ option was specified to
245If this option is set to 245If this option is set to
246.Cm no , 246.Cm no ,
247no keys are added to the agent. 247no keys are added to the agent.
248Alternately, this option may be specified as a time interval
249using the format described in the
250.Sx TIME FORMATS
251section of
252.Xr sshd_config 5
253to specify the key's lifetime in
254.Xr ssh-agent 1 ,
255after which it will automatically be removed.
248The argument must be 256The argument must be
249.Cm yes ,
250.Cm confirm ,
251.Cm ask ,
252or
253.Cm no 257.Cm no
254(the default). 258(the default),
259.Cm yes ,
260.Cm confirm
261(optionally followed by a time interval),
262.Cm ask
263or a time interval.
255.It Cm AddressFamily 264.It Cm AddressFamily
256Specifies which address family to use when connecting. 265Specifies which address family to use when connecting.
257Valid arguments are 266Valid arguments are
diff --git a/sshconnect.c b/sshconnect.c
index f6d8a1bcf..63a97d039 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.330 2020/07/17 03:43:42 dtucker Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.331 2020/08/11 09:49:57 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * 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,
1433 if (sshkey_is_sk(private)) 1433 if (sshkey_is_sk(private))
1434 skprovider = options.sk_provider; 1434 skprovider = options.sk_provider;
1435 if ((r = ssh_add_identity_constrained(auth_sock, private, 1435 if ((r = ssh_add_identity_constrained(auth_sock, private,
1436 comment == NULL ? authfile : comment, 0, 1436 comment == NULL ? authfile : comment,
1437 options.add_keys_to_agent_lifespan,
1437 (options.add_keys_to_agent == 3), 0, skprovider)) == 0) 1438 (options.add_keys_to_agent == 3), 0, skprovider)) == 0)
1438 debug("identity added to agent: %s", authfile); 1439 debug("identity added to agent: %s", authfile);
1439 else 1440 else