diff options
Diffstat (limited to 'readconf.c')
-rw-r--r-- | readconf.c | 190 |
1 files changed, 142 insertions, 48 deletions
diff --git a/readconf.c b/readconf.c index efcf2d628..a3d42f2ae 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.283 2018/02/23 15:58:37 markus Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.297 2018/08/12 20:19:13 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 |
@@ -53,6 +53,7 @@ | |||
53 | 53 | ||
54 | #include "xmalloc.h" | 54 | #include "xmalloc.h" |
55 | #include "ssh.h" | 55 | #include "ssh.h" |
56 | #include "ssherr.h" | ||
56 | #include "compat.h" | 57 | #include "compat.h" |
57 | #include "cipher.h" | 58 | #include "cipher.h" |
58 | #include "pathnames.h" | 59 | #include "pathnames.h" |
@@ -163,7 +164,7 @@ typedef enum { | |||
163 | oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, | 164 | oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, |
164 | oGssServerIdentity, | 165 | oGssServerIdentity, |
165 | oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, | 166 | oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, |
166 | oSendEnv, oControlPath, oControlMaster, oControlPersist, | 167 | oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, |
167 | oHashKnownHosts, | 168 | oHashKnownHosts, |
168 | oTunnel, oTunnelDevice, | 169 | oTunnel, oTunnelDevice, |
169 | oLocalCommand, oPermitLocalCommand, oRemoteCommand, | 170 | oLocalCommand, oPermitLocalCommand, oRemoteCommand, |
@@ -194,6 +195,7 @@ static struct { | |||
194 | { "userknownhostsfile2", oDeprecated }, | 195 | { "userknownhostsfile2", oDeprecated }, |
195 | { "useroaming", oDeprecated }, | 196 | { "useroaming", oDeprecated }, |
196 | { "usersh", oDeprecated }, | 197 | { "usersh", oDeprecated }, |
198 | { "useprivilegedport", oDeprecated }, | ||
197 | 199 | ||
198 | /* Unsupported options */ | 200 | /* Unsupported options */ |
199 | { "afstokenpassing", oUnsupported }, | 201 | { "afstokenpassing", oUnsupported }, |
@@ -236,7 +238,6 @@ static struct { | |||
236 | { "exitonforwardfailure", oExitOnForwardFailure }, | 238 | { "exitonforwardfailure", oExitOnForwardFailure }, |
237 | { "xauthlocation", oXAuthLocation }, | 239 | { "xauthlocation", oXAuthLocation }, |
238 | { "gatewayports", oGatewayPorts }, | 240 | { "gatewayports", oGatewayPorts }, |
239 | { "useprivilegedport", oUsePrivilegedPort }, | ||
240 | { "passwordauthentication", oPasswordAuthentication }, | 241 | { "passwordauthentication", oPasswordAuthentication }, |
241 | { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, | 242 | { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, |
242 | { "kbdinteractivedevices", oKbdInteractiveDevices }, | 243 | { "kbdinteractivedevices", oKbdInteractiveDevices }, |
@@ -244,7 +245,7 @@ static struct { | |||
244 | { "dsaauthentication", oPubkeyAuthentication }, /* alias */ | 245 | { "dsaauthentication", oPubkeyAuthentication }, /* alias */ |
245 | { "hostbasedauthentication", oHostbasedAuthentication }, | 246 | { "hostbasedauthentication", oHostbasedAuthentication }, |
246 | { "challengeresponseauthentication", oChallengeResponseAuthentication }, | 247 | { "challengeresponseauthentication", oChallengeResponseAuthentication }, |
247 | { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ | 248 | { "skeyauthentication", oUnsupported }, |
248 | { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ | 249 | { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ |
249 | { "identityfile", oIdentityFile }, | 250 | { "identityfile", oIdentityFile }, |
250 | { "identityfile2", oIdentityFile }, /* obsolete */ | 251 | { "identityfile2", oIdentityFile }, /* obsolete */ |
@@ -291,6 +292,7 @@ static struct { | |||
291 | { "serveraliveinterval", oServerAliveInterval }, | 292 | { "serveraliveinterval", oServerAliveInterval }, |
292 | { "serveralivecountmax", oServerAliveCountMax }, | 293 | { "serveralivecountmax", oServerAliveCountMax }, |
293 | { "sendenv", oSendEnv }, | 294 | { "sendenv", oSendEnv }, |
295 | { "setenv", oSetEnv }, | ||
294 | { "controlpath", oControlPath }, | 296 | { "controlpath", oControlPath }, |
295 | { "controlmaster", oControlMaster }, | 297 | { "controlmaster", oControlMaster }, |
296 | { "controlpersist", oControlPersist }, | 298 | { "controlpersist", oControlPersist }, |
@@ -335,12 +337,8 @@ void | |||
335 | add_local_forward(Options *options, const struct Forward *newfwd) | 337 | add_local_forward(Options *options, const struct Forward *newfwd) |
336 | { | 338 | { |
337 | struct Forward *fwd; | 339 | struct Forward *fwd; |
338 | extern uid_t original_real_uid; | ||
339 | int i; | 340 | int i; |
340 | 341 | ||
341 | if (!bind_permitted(newfwd->listen_port, original_real_uid) && | ||
342 | newfwd->listen_path == NULL) | ||
343 | fatal("Privileged ports can only be forwarded by root."); | ||
344 | /* Don't add duplicates */ | 342 | /* Don't add duplicates */ |
345 | for (i = 0; i < options->num_local_forwards; i++) { | 343 | for (i = 0; i < options->num_local_forwards; i++) { |
346 | if (forward_equals(newfwd, options->local_forwards + i)) | 344 | if (forward_equals(newfwd, options->local_forwards + i)) |
@@ -498,7 +496,6 @@ execute_in_shell(const char *cmd) | |||
498 | char *shell; | 496 | char *shell; |
499 | pid_t pid; | 497 | pid_t pid; |
500 | int devnull, status; | 498 | int devnull, status; |
501 | extern uid_t original_real_uid; | ||
502 | 499 | ||
503 | if ((shell = getenv("SHELL")) == NULL) | 500 | if ((shell = getenv("SHELL")) == NULL) |
504 | shell = _PATH_BSHELL; | 501 | shell = _PATH_BSHELL; |
@@ -513,9 +510,6 @@ execute_in_shell(const char *cmd) | |||
513 | if ((pid = fork()) == 0) { | 510 | if ((pid = fork()) == 0) { |
514 | char *argv[4]; | 511 | char *argv[4]; |
515 | 512 | ||
516 | /* Child. Permanently give up superuser privileges. */ | ||
517 | permanently_drop_suid(original_real_uid); | ||
518 | |||
519 | /* Redirect child stdin and stdout. Leave stderr */ | 513 | /* Redirect child stdin and stdout. Leave stderr */ |
520 | if (dup2(devnull, STDIN_FILENO) == -1) | 514 | if (dup2(devnull, STDIN_FILENO) == -1) |
521 | fatal("dup2: %s", strerror(errno)); | 515 | fatal("dup2: %s", strerror(errno)); |
@@ -567,6 +561,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
567 | const char *ruser; | 561 | const char *ruser; |
568 | int r, port, this_result, result = 1, attributes = 0, negate; | 562 | int r, port, this_result, result = 1, attributes = 0, negate; |
569 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | 563 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
564 | char uidstr[32]; | ||
570 | 565 | ||
571 | /* | 566 | /* |
572 | * Configuration is likely to be incomplete at this point so we | 567 | * Configuration is likely to be incomplete at this point so we |
@@ -647,6 +642,8 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
647 | strlcpy(shorthost, thishost, sizeof(shorthost)); | 642 | strlcpy(shorthost, thishost, sizeof(shorthost)); |
648 | shorthost[strcspn(thishost, ".")] = '\0'; | 643 | shorthost[strcspn(thishost, ".")] = '\0'; |
649 | snprintf(portstr, sizeof(portstr), "%d", port); | 644 | snprintf(portstr, sizeof(portstr), "%d", port); |
645 | snprintf(uidstr, sizeof(uidstr), "%llu", | ||
646 | (unsigned long long)pw->pw_uid); | ||
650 | 647 | ||
651 | cmd = percent_expand(arg, | 648 | cmd = percent_expand(arg, |
652 | "L", shorthost, | 649 | "L", shorthost, |
@@ -657,6 +654,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
657 | "p", portstr, | 654 | "p", portstr, |
658 | "r", ruser, | 655 | "r", ruser, |
659 | "u", pw->pw_name, | 656 | "u", pw->pw_name, |
657 | "i", uidstr, | ||
660 | (char *)NULL); | 658 | (char *)NULL); |
661 | if (result != 1) { | 659 | if (result != 1) { |
662 | /* skip execution if prior predicate failed */ | 660 | /* skip execution if prior predicate failed */ |
@@ -700,6 +698,35 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
700 | return result; | 698 | return result; |
701 | } | 699 | } |
702 | 700 | ||
701 | /* Remove environment variable by pattern */ | ||
702 | static void | ||
703 | rm_env(Options *options, const char *arg, const char *filename, int linenum) | ||
704 | { | ||
705 | int i, j; | ||
706 | char *cp; | ||
707 | |||
708 | /* Remove an environment variable */ | ||
709 | for (i = 0; i < options->num_send_env; ) { | ||
710 | cp = xstrdup(options->send_env[i]); | ||
711 | if (!match_pattern(cp, arg + 1)) { | ||
712 | free(cp); | ||
713 | i++; | ||
714 | continue; | ||
715 | } | ||
716 | debug3("%s line %d: removing environment %s", | ||
717 | filename, linenum, cp); | ||
718 | free(cp); | ||
719 | free(options->send_env[i]); | ||
720 | options->send_env[i] = NULL; | ||
721 | for (j = i; j < options->num_send_env - 1; j++) { | ||
722 | options->send_env[j] = options->send_env[j + 1]; | ||
723 | options->send_env[j + 1] = NULL; | ||
724 | } | ||
725 | options->num_send_env--; | ||
726 | /* NB. don't increment i */ | ||
727 | } | ||
728 | } | ||
729 | |||
703 | /* | 730 | /* |
704 | * Returns the number of the token pointed to by cp or oBadOption. | 731 | * Returns the number of the token pointed to by cp or oBadOption. |
705 | */ | 732 | */ |
@@ -934,10 +961,6 @@ parse_time: | |||
934 | intptr = &options->exit_on_forward_failure; | 961 | intptr = &options->exit_on_forward_failure; |
935 | goto parse_flag; | 962 | goto parse_flag; |
936 | 963 | ||
937 | case oUsePrivilegedPort: | ||
938 | intptr = &options->use_privileged_port; | ||
939 | goto parse_flag; | ||
940 | |||
941 | case oPasswordAuthentication: | 964 | case oPasswordAuthentication: |
942 | intptr = &options->password_authentication; | 965 | intptr = &options->password_authentication; |
943 | goto parse_flag; | 966 | goto parse_flag; |
@@ -1397,11 +1420,41 @@ parse_keytypes: | |||
1397 | filename, linenum); | 1420 | filename, linenum); |
1398 | if (!*activep) | 1421 | if (!*activep) |
1399 | continue; | 1422 | continue; |
1400 | if (options->num_send_env >= MAX_SEND_ENV) | 1423 | if (*arg == '-') { |
1401 | fatal("%s line %d: too many send env.", | 1424 | /* Removing an env var */ |
1425 | rm_env(options, arg, filename, linenum); | ||
1426 | continue; | ||
1427 | } else { | ||
1428 | /* Adding an env var */ | ||
1429 | if (options->num_send_env >= INT_MAX) | ||
1430 | fatal("%s line %d: too many send env.", | ||
1431 | filename, linenum); | ||
1432 | options->send_env = xrecallocarray( | ||
1433 | options->send_env, options->num_send_env, | ||
1434 | options->num_send_env + 1, | ||
1435 | sizeof(*options->send_env)); | ||
1436 | options->send_env[options->num_send_env++] = | ||
1437 | xstrdup(arg); | ||
1438 | } | ||
1439 | } | ||
1440 | break; | ||
1441 | |||
1442 | case oSetEnv: | ||
1443 | value = options->num_setenv; | ||
1444 | while ((arg = strdelimw(&s)) != NULL && *arg != '\0') { | ||
1445 | if (strchr(arg, '=') == NULL) | ||
1446 | fatal("%s line %d: Invalid SetEnv.", | ||
1447 | filename, linenum); | ||
1448 | if (!*activep || value != 0) | ||
1449 | continue; | ||
1450 | /* Adding a setenv var */ | ||
1451 | if (options->num_setenv >= INT_MAX) | ||
1452 | fatal("%s line %d: too many SetEnv.", | ||
1402 | filename, linenum); | 1453 | filename, linenum); |
1403 | options->send_env[options->num_send_env++] = | 1454 | options->setenv = xrecallocarray( |
1404 | xstrdup(arg); | 1455 | options->setenv, options->num_setenv, |
1456 | options->num_setenv + 1, sizeof(*options->setenv)); | ||
1457 | options->setenv[options->num_setenv++] = xstrdup(arg); | ||
1405 | } | 1458 | } |
1406 | break; | 1459 | break; |
1407 | 1460 | ||
@@ -1726,7 +1779,8 @@ read_config_file_depth(const char *filename, struct passwd *pw, | |||
1726 | int flags, int *activep, int depth) | 1779 | int flags, int *activep, int depth) |
1727 | { | 1780 | { |
1728 | FILE *f; | 1781 | FILE *f; |
1729 | char line[4096]; | 1782 | char *line = NULL; |
1783 | size_t linesize = 0; | ||
1730 | int linenum; | 1784 | int linenum; |
1731 | int bad_options = 0; | 1785 | int bad_options = 0; |
1732 | 1786 | ||
@@ -1752,15 +1806,14 @@ read_config_file_depth(const char *filename, struct passwd *pw, | |||
1752 | * on/off by Host specifications. | 1806 | * on/off by Host specifications. |
1753 | */ | 1807 | */ |
1754 | linenum = 0; | 1808 | linenum = 0; |
1755 | while (fgets(line, sizeof(line), f)) { | 1809 | while (getline(&line, &linesize, f) != -1) { |
1756 | /* Update line number counter. */ | 1810 | /* Update line number counter. */ |
1757 | linenum++; | 1811 | linenum++; |
1758 | if (strlen(line) == sizeof(line) - 1) | ||
1759 | fatal("%s line %d too long", filename, linenum); | ||
1760 | if (process_config_line_depth(options, pw, host, original_host, | 1812 | if (process_config_line_depth(options, pw, host, original_host, |
1761 | line, filename, linenum, activep, flags, depth) != 0) | 1813 | line, filename, linenum, activep, flags, depth) != 0) |
1762 | bad_options++; | 1814 | bad_options++; |
1763 | } | 1815 | } |
1816 | free(line); | ||
1764 | fclose(f); | 1817 | fclose(f); |
1765 | if (bad_options > 0) | 1818 | if (bad_options > 0) |
1766 | fatal("%s: terminating, %d bad configuration options", | 1819 | fatal("%s: terminating, %d bad configuration options", |
@@ -1798,7 +1851,6 @@ initialize_options(Options * options) | |||
1798 | options->fwd_opts.gateway_ports = -1; | 1851 | options->fwd_opts.gateway_ports = -1; |
1799 | options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; | 1852 | options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; |
1800 | options->fwd_opts.streamlocal_bind_unlink = -1; | 1853 | options->fwd_opts.streamlocal_bind_unlink = -1; |
1801 | options->use_privileged_port = -1; | ||
1802 | options->pubkey_authentication = -1; | 1854 | options->pubkey_authentication = -1; |
1803 | options->challenge_response_authentication = -1; | 1855 | options->challenge_response_authentication = -1; |
1804 | options->gss_authentication = -1; | 1856 | options->gss_authentication = -1; |
@@ -1857,7 +1909,10 @@ initialize_options(Options * options) | |||
1857 | options->verify_host_key_dns = -1; | 1909 | options->verify_host_key_dns = -1; |
1858 | options->server_alive_interval = -1; | 1910 | options->server_alive_interval = -1; |
1859 | options->server_alive_count_max = -1; | 1911 | options->server_alive_count_max = -1; |
1912 | options->send_env = NULL; | ||
1860 | options->num_send_env = 0; | 1913 | options->num_send_env = 0; |
1914 | options->setenv = NULL; | ||
1915 | options->num_setenv = 0; | ||
1861 | options->control_path = NULL; | 1916 | options->control_path = NULL; |
1862 | options->control_master = -1; | 1917 | options->control_master = -1; |
1863 | options->control_persist = -1; | 1918 | options->control_persist = -1; |
@@ -1911,6 +1966,9 @@ fill_default_options_for_canonicalization(Options *options) | |||
1911 | void | 1966 | void |
1912 | fill_default_options(Options * options) | 1967 | fill_default_options(Options * options) |
1913 | { | 1968 | { |
1969 | char *all_cipher, *all_mac, *all_kex, *all_key; | ||
1970 | int r; | ||
1971 | |||
1914 | if (options->forward_agent == -1) | 1972 | if (options->forward_agent == -1) |
1915 | options->forward_agent = 0; | 1973 | options->forward_agent = 0; |
1916 | if (options->forward_x11 == -1) | 1974 | if (options->forward_x11 == -1) |
@@ -1940,8 +1998,6 @@ fill_default_options(Options * options) | |||
1940 | options->fwd_opts.streamlocal_bind_mask = 0177; | 1998 | options->fwd_opts.streamlocal_bind_mask = 0177; |
1941 | if (options->fwd_opts.streamlocal_bind_unlink == -1) | 1999 | if (options->fwd_opts.streamlocal_bind_unlink == -1) |
1942 | options->fwd_opts.streamlocal_bind_unlink = 0; | 2000 | options->fwd_opts.streamlocal_bind_unlink = 0; |
1943 | if (options->use_privileged_port == -1) | ||
1944 | options->use_privileged_port = 0; | ||
1945 | if (options->pubkey_authentication == -1) | 2001 | if (options->pubkey_authentication == -1) |
1946 | options->pubkey_authentication = 1; | 2002 | options->pubkey_authentication = 1; |
1947 | if (options->challenge_response_authentication == -1) | 2003 | if (options->challenge_response_authentication == -1) |
@@ -2051,9 +2107,9 @@ fill_default_options(Options * options) | |||
2051 | if (options->visual_host_key == -1) | 2107 | if (options->visual_host_key == -1) |
2052 | options->visual_host_key = 0; | 2108 | options->visual_host_key = 0; |
2053 | if (options->ip_qos_interactive == -1) | 2109 | if (options->ip_qos_interactive == -1) |
2054 | options->ip_qos_interactive = IPTOS_LOWDELAY; | 2110 | options->ip_qos_interactive = IPTOS_DSCP_AF21; |
2055 | if (options->ip_qos_bulk == -1) | 2111 | if (options->ip_qos_bulk == -1) |
2056 | options->ip_qos_bulk = IPTOS_THROUGHPUT; | 2112 | options->ip_qos_bulk = IPTOS_DSCP_CS1; |
2057 | if (options->request_tty == -1) | 2113 | if (options->request_tty == -1) |
2058 | options->request_tty = REQUEST_TTY_AUTO; | 2114 | options->request_tty = REQUEST_TTY_AUTO; |
2059 | if (options->proxy_use_fdpass == -1) | 2115 | if (options->proxy_use_fdpass == -1) |
@@ -2068,14 +2124,28 @@ fill_default_options(Options * options) | |||
2068 | options->fingerprint_hash = SSH_FP_HASH_DEFAULT; | 2124 | options->fingerprint_hash = SSH_FP_HASH_DEFAULT; |
2069 | if (options->update_hostkeys == -1) | 2125 | if (options->update_hostkeys == -1) |
2070 | options->update_hostkeys = 0; | 2126 | options->update_hostkeys = 0; |
2071 | if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || | 2127 | |
2072 | kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || | 2128 | /* Expand KEX name lists */ |
2073 | kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || | 2129 | all_cipher = cipher_alg_list(',', 0); |
2074 | kex_assemble_names(KEX_DEFAULT_PK_ALG, | 2130 | all_mac = mac_alg_list(','); |
2075 | &options->hostbased_key_types) != 0 || | 2131 | all_kex = kex_alg_list(','); |
2076 | kex_assemble_names(KEX_DEFAULT_PK_ALG, | 2132 | all_key = sshkey_alg_list(0, 0, 1, ','); |
2077 | &options->pubkey_key_types) != 0) | 2133 | #define ASSEMBLE(what, defaults, all) \ |
2078 | fatal("%s: kex_assemble_names failed", __func__); | 2134 | do { \ |
2135 | if ((r = kex_assemble_names(&options->what, \ | ||
2136 | defaults, all)) != 0) \ | ||
2137 | fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ | ||
2138 | } while (0) | ||
2139 | ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); | ||
2140 | ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); | ||
2141 | ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); | ||
2142 | ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); | ||
2143 | ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); | ||
2144 | #undef ASSEMBLE | ||
2145 | free(all_cipher); | ||
2146 | free(all_mac); | ||
2147 | free(all_kex); | ||
2148 | free(all_key); | ||
2079 | 2149 | ||
2080 | #define CLEAR_ON_NONE(v) \ | 2150 | #define CLEAR_ON_NONE(v) \ |
2081 | do { \ | 2151 | do { \ |
@@ -2089,6 +2159,12 @@ fill_default_options(Options * options) | |||
2089 | CLEAR_ON_NONE(options->proxy_command); | 2159 | CLEAR_ON_NONE(options->proxy_command); |
2090 | CLEAR_ON_NONE(options->control_path); | 2160 | CLEAR_ON_NONE(options->control_path); |
2091 | CLEAR_ON_NONE(options->revoked_host_keys); | 2161 | CLEAR_ON_NONE(options->revoked_host_keys); |
2162 | if (options->jump_host != NULL && | ||
2163 | strcmp(options->jump_host, "none") == 0 && | ||
2164 | options->jump_port == 0 && options->jump_user == NULL) { | ||
2165 | free(options->jump_host); | ||
2166 | options->jump_host = NULL; | ||
2167 | } | ||
2092 | /* options->identity_agent distinguishes NULL from 'none' */ | 2168 | /* options->identity_agent distinguishes NULL from 'none' */ |
2093 | /* options->user will be set in the main program if appropriate */ | 2169 | /* options->user will be set in the main program if appropriate */ |
2094 | /* options->hostname will be set in the main program if appropriate */ | 2170 | /* options->hostname will be set in the main program if appropriate */ |
@@ -2317,6 +2393,8 @@ parse_jump(const char *s, Options *o, int active) | |||
2317 | orig = sdup = xstrdup(s); | 2393 | orig = sdup = xstrdup(s); |
2318 | first = active; | 2394 | first = active; |
2319 | do { | 2395 | do { |
2396 | if (strcasecmp(s, "none") == 0) | ||
2397 | break; | ||
2320 | if ((cp = strrchr(sdup, ',')) == NULL) | 2398 | if ((cp = strrchr(sdup, ',')) == NULL) |
2321 | cp = sdup; /* last */ | 2399 | cp = sdup; /* last */ |
2322 | else | 2400 | else |
@@ -2337,14 +2415,19 @@ parse_jump(const char *s, Options *o, int active) | |||
2337 | } while (cp != sdup); | 2415 | } while (cp != sdup); |
2338 | /* success */ | 2416 | /* success */ |
2339 | if (active) { | 2417 | if (active) { |
2340 | o->jump_user = user; | 2418 | if (strcasecmp(s, "none") == 0) { |
2341 | o->jump_host = host; | 2419 | o->jump_host = xstrdup("none"); |
2342 | o->jump_port = port; | 2420 | o->jump_port = 0; |
2343 | o->proxy_command = xstrdup("none"); | 2421 | } else { |
2344 | user = host = NULL; | 2422 | o->jump_user = user; |
2345 | if ((cp = strrchr(s, ',')) != NULL && cp != s) { | 2423 | o->jump_host = host; |
2346 | o->jump_extra = xstrdup(s); | 2424 | o->jump_port = port; |
2347 | o->jump_extra[cp - s] = '\0'; | 2425 | o->proxy_command = xstrdup("none"); |
2426 | user = host = NULL; | ||
2427 | if ((cp = strrchr(s, ',')) != NULL && cp != s) { | ||
2428 | o->jump_extra = xstrdup(s); | ||
2429 | o->jump_extra[cp - s] = '\0'; | ||
2430 | } | ||
2348 | } | 2431 | } |
2349 | } | 2432 | } |
2350 | ret = 0; | 2433 | ret = 0; |
@@ -2401,6 +2484,8 @@ fmt_intarg(OpCodes code, int val) | |||
2401 | return fmt_multistate_int(val, multistate_requesttty); | 2484 | return fmt_multistate_int(val, multistate_requesttty); |
2402 | case oCanonicalizeHostname: | 2485 | case oCanonicalizeHostname: |
2403 | return fmt_multistate_int(val, multistate_canonicalizehostname); | 2486 | return fmt_multistate_int(val, multistate_canonicalizehostname); |
2487 | case oAddKeysToAgent: | ||
2488 | return fmt_multistate_int(val, multistate_yesnoaskconfirm); | ||
2404 | case oFingerprintHash: | 2489 | case oFingerprintHash: |
2405 | return ssh_digest_alg_name(val); | 2490 | return ssh_digest_alg_name(val); |
2406 | default: | 2491 | default: |
@@ -2508,11 +2593,14 @@ void | |||
2508 | dump_client_config(Options *o, const char *host) | 2593 | dump_client_config(Options *o, const char *host) |
2509 | { | 2594 | { |
2510 | int i; | 2595 | int i; |
2511 | char buf[8]; | 2596 | char buf[8], *all_key; |
2512 | 2597 | ||
2513 | /* This is normally prepared in ssh_kex2 */ | 2598 | /* This is normally prepared in ssh_kex2 */ |
2514 | if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) | 2599 | all_key = sshkey_alg_list(0, 0, 1, ','); |
2600 | if (kex_assemble_names( &o->hostkeyalgorithms, | ||
2601 | KEX_DEFAULT_PK_ALG, all_key) != 0) | ||
2515 | fatal("%s: kex_assemble_names failed", __func__); | 2602 | fatal("%s: kex_assemble_names failed", __func__); |
2603 | free(all_key); | ||
2516 | 2604 | ||
2517 | /* Most interesting options first: user, host, port */ | 2605 | /* Most interesting options first: user, host, port */ |
2518 | dump_cfg_string(oUser, o->user); | 2606 | dump_cfg_string(oUser, o->user); |
@@ -2520,6 +2608,7 @@ dump_client_config(Options *o, const char *host) | |||
2520 | dump_cfg_int(oPort, o->port); | 2608 | dump_cfg_int(oPort, o->port); |
2521 | 2609 | ||
2522 | /* Flag options */ | 2610 | /* Flag options */ |
2611 | dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent); | ||
2523 | dump_cfg_fmtint(oAddressFamily, o->address_family); | 2612 | dump_cfg_fmtint(oAddressFamily, o->address_family); |
2524 | dump_cfg_fmtint(oBatchMode, o->batch_mode); | 2613 | dump_cfg_fmtint(oBatchMode, o->batch_mode); |
2525 | dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); | 2614 | dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); |
@@ -2554,7 +2643,6 @@ dump_client_config(Options *o, const char *host) | |||
2554 | dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); | 2643 | dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); |
2555 | dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); | 2644 | dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); |
2556 | dump_cfg_fmtint(oTunnel, o->tun_open); | 2645 | dump_cfg_fmtint(oTunnel, o->tun_open); |
2557 | dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port); | ||
2558 | dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); | 2646 | dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); |
2559 | dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); | 2647 | dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); |
2560 | dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); | 2648 | dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); |
@@ -2576,6 +2664,7 @@ dump_client_config(Options *o, const char *host) | |||
2576 | dump_cfg_string(oHostKeyAlias, o->host_key_alias); | 2664 | dump_cfg_string(oHostKeyAlias, o->host_key_alias); |
2577 | dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); | 2665 | dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); |
2578 | dump_cfg_string(oIdentityAgent, o->identity_agent); | 2666 | dump_cfg_string(oIdentityAgent, o->identity_agent); |
2667 | dump_cfg_string(oIgnoreUnknown, o->ignored_unknown); | ||
2579 | dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); | 2668 | dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); |
2580 | dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); | 2669 | dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); |
2581 | dump_cfg_string(oLocalCommand, o->local_command); | 2670 | dump_cfg_string(oLocalCommand, o->local_command); |
@@ -2598,9 +2687,11 @@ dump_client_config(Options *o, const char *host) | |||
2598 | /* String array options */ | 2687 | /* String array options */ |
2599 | dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); | 2688 | dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); |
2600 | dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); | 2689 | dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); |
2690 | dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files); | ||
2601 | dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); | 2691 | dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); |
2602 | dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); | 2692 | dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); |
2603 | dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); | 2693 | dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); |
2694 | dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv); | ||
2604 | 2695 | ||
2605 | /* Special cases */ | 2696 | /* Special cases */ |
2606 | 2697 | ||
@@ -2658,6 +2749,9 @@ dump_client_config(Options *o, const char *host) | |||
2658 | printf("streamlocalbindmask 0%o\n", | 2749 | printf("streamlocalbindmask 0%o\n", |
2659 | o->fwd_opts.streamlocal_bind_mask); | 2750 | o->fwd_opts.streamlocal_bind_mask); |
2660 | 2751 | ||
2752 | /* oLogFacility */ | ||
2753 | printf("syslogfacility %s\n", log_facility_name(o->log_facility)); | ||
2754 | |||
2661 | /* oProxyCommand / oProxyJump */ | 2755 | /* oProxyCommand / oProxyJump */ |
2662 | if (o->jump_host == NULL) | 2756 | if (o->jump_host == NULL) |
2663 | dump_cfg_string(oProxyCommand, o->proxy_command); | 2757 | dump_cfg_string(oProxyCommand, o->proxy_command); |