diff options
-rw-r--r-- | readconf.c | 85 | ||||
-rw-r--r-- | readconf.h | 3 | ||||
-rw-r--r-- | ssh_config.5 | 23 | ||||
-rw-r--r-- | sshconnect.c | 5 |
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 | ||
880 | static int | ||
881 | parse_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 | |||
245 | If this option is set to | 245 | If this option is set to |
246 | .Cm no , | 246 | .Cm no , |
247 | no keys are added to the agent. | 247 | no keys are added to the agent. |
248 | Alternately, this option may be specified as a time interval | ||
249 | using the format described in the | ||
250 | .Sx TIME FORMATS | ||
251 | section of | ||
252 | .Xr sshd_config 5 | ||
253 | to specify the key's lifetime in | ||
254 | .Xr ssh-agent 1 , | ||
255 | after which it will automatically be removed. | ||
248 | The argument must be | 256 | The argument must be |
249 | .Cm yes , | ||
250 | .Cm confirm , | ||
251 | .Cm ask , | ||
252 | or | ||
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 | ||
263 | or a time interval. | ||
255 | .It Cm AddressFamily | 264 | .It Cm AddressFamily |
256 | Specifies which address family to use when connecting. | 265 | Specifies which address family to use when connecting. |
257 | Valid arguments are | 266 | Valid 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 |