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 88051db57..db5f2d547 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" |
@@ -161,7 +162,7 @@ typedef enum { | |||
161 | oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, | 162 | oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, |
162 | oAddressFamily, oGssAuthentication, oGssDelegateCreds, | 163 | oAddressFamily, oGssAuthentication, oGssDelegateCreds, |
163 | oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, | 164 | oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, |
164 | oSendEnv, oControlPath, oControlMaster, oControlPersist, | 165 | oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, |
165 | oHashKnownHosts, | 166 | oHashKnownHosts, |
166 | oTunnel, oTunnelDevice, | 167 | oTunnel, oTunnelDevice, |
167 | oLocalCommand, oPermitLocalCommand, oRemoteCommand, | 168 | oLocalCommand, oPermitLocalCommand, oRemoteCommand, |
@@ -190,6 +191,7 @@ static struct { | |||
190 | { "userknownhostsfile2", oDeprecated }, | 191 | { "userknownhostsfile2", oDeprecated }, |
191 | { "useroaming", oDeprecated }, | 192 | { "useroaming", oDeprecated }, |
192 | { "usersh", oDeprecated }, | 193 | { "usersh", oDeprecated }, |
194 | { "useprivilegedport", oDeprecated }, | ||
193 | 195 | ||
194 | /* Unsupported options */ | 196 | /* Unsupported options */ |
195 | { "afstokenpassing", oUnsupported }, | 197 | { "afstokenpassing", oUnsupported }, |
@@ -222,7 +224,6 @@ static struct { | |||
222 | { "exitonforwardfailure", oExitOnForwardFailure }, | 224 | { "exitonforwardfailure", oExitOnForwardFailure }, |
223 | { "xauthlocation", oXAuthLocation }, | 225 | { "xauthlocation", oXAuthLocation }, |
224 | { "gatewayports", oGatewayPorts }, | 226 | { "gatewayports", oGatewayPorts }, |
225 | { "useprivilegedport", oUsePrivilegedPort }, | ||
226 | { "passwordauthentication", oPasswordAuthentication }, | 227 | { "passwordauthentication", oPasswordAuthentication }, |
227 | { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, | 228 | { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, |
228 | { "kbdinteractivedevices", oKbdInteractiveDevices }, | 229 | { "kbdinteractivedevices", oKbdInteractiveDevices }, |
@@ -230,7 +231,7 @@ static struct { | |||
230 | { "dsaauthentication", oPubkeyAuthentication }, /* alias */ | 231 | { "dsaauthentication", oPubkeyAuthentication }, /* alias */ |
231 | { "hostbasedauthentication", oHostbasedAuthentication }, | 232 | { "hostbasedauthentication", oHostbasedAuthentication }, |
232 | { "challengeresponseauthentication", oChallengeResponseAuthentication }, | 233 | { "challengeresponseauthentication", oChallengeResponseAuthentication }, |
233 | { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ | 234 | { "skeyauthentication", oUnsupported }, |
234 | { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ | 235 | { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ |
235 | { "identityfile", oIdentityFile }, | 236 | { "identityfile", oIdentityFile }, |
236 | { "identityfile2", oIdentityFile }, /* obsolete */ | 237 | { "identityfile2", oIdentityFile }, /* obsolete */ |
@@ -277,6 +278,7 @@ static struct { | |||
277 | { "serveraliveinterval", oServerAliveInterval }, | 278 | { "serveraliveinterval", oServerAliveInterval }, |
278 | { "serveralivecountmax", oServerAliveCountMax }, | 279 | { "serveralivecountmax", oServerAliveCountMax }, |
279 | { "sendenv", oSendEnv }, | 280 | { "sendenv", oSendEnv }, |
281 | { "setenv", oSetEnv }, | ||
280 | { "controlpath", oControlPath }, | 282 | { "controlpath", oControlPath }, |
281 | { "controlmaster", oControlMaster }, | 283 | { "controlmaster", oControlMaster }, |
282 | { "controlpersist", oControlPersist }, | 284 | { "controlpersist", oControlPersist }, |
@@ -319,12 +321,8 @@ void | |||
319 | add_local_forward(Options *options, const struct Forward *newfwd) | 321 | add_local_forward(Options *options, const struct Forward *newfwd) |
320 | { | 322 | { |
321 | struct Forward *fwd; | 323 | struct Forward *fwd; |
322 | extern uid_t original_real_uid; | ||
323 | int i; | 324 | int i; |
324 | 325 | ||
325 | if (!bind_permitted(newfwd->listen_port, original_real_uid) && | ||
326 | newfwd->listen_path == NULL) | ||
327 | fatal("Privileged ports can only be forwarded by root."); | ||
328 | /* Don't add duplicates */ | 326 | /* Don't add duplicates */ |
329 | for (i = 0; i < options->num_local_forwards; i++) { | 327 | for (i = 0; i < options->num_local_forwards; i++) { |
330 | if (forward_equals(newfwd, options->local_forwards + i)) | 328 | if (forward_equals(newfwd, options->local_forwards + i)) |
@@ -482,7 +480,6 @@ execute_in_shell(const char *cmd) | |||
482 | char *shell; | 480 | char *shell; |
483 | pid_t pid; | 481 | pid_t pid; |
484 | int devnull, status; | 482 | int devnull, status; |
485 | extern uid_t original_real_uid; | ||
486 | 483 | ||
487 | if ((shell = getenv("SHELL")) == NULL) | 484 | if ((shell = getenv("SHELL")) == NULL) |
488 | shell = _PATH_BSHELL; | 485 | shell = _PATH_BSHELL; |
@@ -497,9 +494,6 @@ execute_in_shell(const char *cmd) | |||
497 | if ((pid = fork()) == 0) { | 494 | if ((pid = fork()) == 0) { |
498 | char *argv[4]; | 495 | char *argv[4]; |
499 | 496 | ||
500 | /* Child. Permanently give up superuser privileges. */ | ||
501 | permanently_drop_suid(original_real_uid); | ||
502 | |||
503 | /* Redirect child stdin and stdout. Leave stderr */ | 497 | /* Redirect child stdin and stdout. Leave stderr */ |
504 | if (dup2(devnull, STDIN_FILENO) == -1) | 498 | if (dup2(devnull, STDIN_FILENO) == -1) |
505 | fatal("dup2: %s", strerror(errno)); | 499 | fatal("dup2: %s", strerror(errno)); |
@@ -551,6 +545,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
551 | const char *ruser; | 545 | const char *ruser; |
552 | int r, port, this_result, result = 1, attributes = 0, negate; | 546 | int r, port, this_result, result = 1, attributes = 0, negate; |
553 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | 547 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
548 | char uidstr[32]; | ||
554 | 549 | ||
555 | /* | 550 | /* |
556 | * Configuration is likely to be incomplete at this point so we | 551 | * Configuration is likely to be incomplete at this point so we |
@@ -631,6 +626,8 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
631 | strlcpy(shorthost, thishost, sizeof(shorthost)); | 626 | strlcpy(shorthost, thishost, sizeof(shorthost)); |
632 | shorthost[strcspn(thishost, ".")] = '\0'; | 627 | shorthost[strcspn(thishost, ".")] = '\0'; |
633 | snprintf(portstr, sizeof(portstr), "%d", port); | 628 | snprintf(portstr, sizeof(portstr), "%d", port); |
629 | snprintf(uidstr, sizeof(uidstr), "%llu", | ||
630 | (unsigned long long)pw->pw_uid); | ||
634 | 631 | ||
635 | cmd = percent_expand(arg, | 632 | cmd = percent_expand(arg, |
636 | "L", shorthost, | 633 | "L", shorthost, |
@@ -641,6 +638,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
641 | "p", portstr, | 638 | "p", portstr, |
642 | "r", ruser, | 639 | "r", ruser, |
643 | "u", pw->pw_name, | 640 | "u", pw->pw_name, |
641 | "i", uidstr, | ||
644 | (char *)NULL); | 642 | (char *)NULL); |
645 | if (result != 1) { | 643 | if (result != 1) { |
646 | /* skip execution if prior predicate failed */ | 644 | /* skip execution if prior predicate failed */ |
@@ -684,6 +682,35 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
684 | return result; | 682 | return result; |
685 | } | 683 | } |
686 | 684 | ||
685 | /* Remove environment variable by pattern */ | ||
686 | static void | ||
687 | rm_env(Options *options, const char *arg, const char *filename, int linenum) | ||
688 | { | ||
689 | int i, j; | ||
690 | char *cp; | ||
691 | |||
692 | /* Remove an environment variable */ | ||
693 | for (i = 0; i < options->num_send_env; ) { | ||
694 | cp = xstrdup(options->send_env[i]); | ||
695 | if (!match_pattern(cp, arg + 1)) { | ||
696 | free(cp); | ||
697 | i++; | ||
698 | continue; | ||
699 | } | ||
700 | debug3("%s line %d: removing environment %s", | ||
701 | filename, linenum, cp); | ||
702 | free(cp); | ||
703 | free(options->send_env[i]); | ||
704 | options->send_env[i] = NULL; | ||
705 | for (j = i; j < options->num_send_env - 1; j++) { | ||
706 | options->send_env[j] = options->send_env[j + 1]; | ||
707 | options->send_env[j + 1] = NULL; | ||
708 | } | ||
709 | options->num_send_env--; | ||
710 | /* NB. don't increment i */ | ||
711 | } | ||
712 | } | ||
713 | |||
687 | /* | 714 | /* |
688 | * Returns the number of the token pointed to by cp or oBadOption. | 715 | * Returns the number of the token pointed to by cp or oBadOption. |
689 | */ | 716 | */ |
@@ -918,10 +945,6 @@ parse_time: | |||
918 | intptr = &options->exit_on_forward_failure; | 945 | intptr = &options->exit_on_forward_failure; |
919 | goto parse_flag; | 946 | goto parse_flag; |
920 | 947 | ||
921 | case oUsePrivilegedPort: | ||
922 | intptr = &options->use_privileged_port; | ||
923 | goto parse_flag; | ||
924 | |||
925 | case oPasswordAuthentication: | 948 | case oPasswordAuthentication: |
926 | intptr = &options->password_authentication; | 949 | intptr = &options->password_authentication; |
927 | goto parse_flag; | 950 | goto parse_flag; |
@@ -1359,11 +1382,41 @@ parse_keytypes: | |||
1359 | filename, linenum); | 1382 | filename, linenum); |
1360 | if (!*activep) | 1383 | if (!*activep) |
1361 | continue; | 1384 | continue; |
1362 | if (options->num_send_env >= MAX_SEND_ENV) | 1385 | if (*arg == '-') { |
1363 | fatal("%s line %d: too many send env.", | 1386 | /* Removing an env var */ |
1387 | rm_env(options, arg, filename, linenum); | ||
1388 | continue; | ||
1389 | } else { | ||
1390 | /* Adding an env var */ | ||
1391 | if (options->num_send_env >= INT_MAX) | ||
1392 | fatal("%s line %d: too many send env.", | ||
1393 | filename, linenum); | ||
1394 | options->send_env = xrecallocarray( | ||
1395 | options->send_env, options->num_send_env, | ||
1396 | options->num_send_env + 1, | ||
1397 | sizeof(*options->send_env)); | ||
1398 | options->send_env[options->num_send_env++] = | ||
1399 | xstrdup(arg); | ||
1400 | } | ||
1401 | } | ||
1402 | break; | ||
1403 | |||
1404 | case oSetEnv: | ||
1405 | value = options->num_setenv; | ||
1406 | while ((arg = strdelimw(&s)) != NULL && *arg != '\0') { | ||
1407 | if (strchr(arg, '=') == NULL) | ||
1408 | fatal("%s line %d: Invalid SetEnv.", | ||
1409 | filename, linenum); | ||
1410 | if (!*activep || value != 0) | ||
1411 | continue; | ||
1412 | /* Adding a setenv var */ | ||
1413 | if (options->num_setenv >= INT_MAX) | ||
1414 | fatal("%s line %d: too many SetEnv.", | ||
1364 | filename, linenum); | 1415 | filename, linenum); |
1365 | options->send_env[options->num_send_env++] = | 1416 | options->setenv = xrecallocarray( |
1366 | xstrdup(arg); | 1417 | options->setenv, options->num_setenv, |
1418 | options->num_setenv + 1, sizeof(*options->setenv)); | ||
1419 | options->setenv[options->num_setenv++] = xstrdup(arg); | ||
1367 | } | 1420 | } |
1368 | break; | 1421 | break; |
1369 | 1422 | ||
@@ -1688,7 +1741,8 @@ read_config_file_depth(const char *filename, struct passwd *pw, | |||
1688 | int flags, int *activep, int depth) | 1741 | int flags, int *activep, int depth) |
1689 | { | 1742 | { |
1690 | FILE *f; | 1743 | FILE *f; |
1691 | char line[4096]; | 1744 | char *line = NULL; |
1745 | size_t linesize = 0; | ||
1692 | int linenum; | 1746 | int linenum; |
1693 | int bad_options = 0; | 1747 | int bad_options = 0; |
1694 | 1748 | ||
@@ -1715,15 +1769,14 @@ read_config_file_depth(const char *filename, struct passwd *pw, | |||
1715 | * on/off by Host specifications. | 1769 | * on/off by Host specifications. |
1716 | */ | 1770 | */ |
1717 | linenum = 0; | 1771 | linenum = 0; |
1718 | while (fgets(line, sizeof(line), f)) { | 1772 | while (getline(&line, &linesize, f) != -1) { |
1719 | /* Update line number counter. */ | 1773 | /* Update line number counter. */ |
1720 | linenum++; | 1774 | linenum++; |
1721 | if (strlen(line) == sizeof(line) - 1) | ||
1722 | fatal("%s line %d too long", filename, linenum); | ||
1723 | if (process_config_line_depth(options, pw, host, original_host, | 1775 | if (process_config_line_depth(options, pw, host, original_host, |
1724 | line, filename, linenum, activep, flags, depth) != 0) | 1776 | line, filename, linenum, activep, flags, depth) != 0) |
1725 | bad_options++; | 1777 | bad_options++; |
1726 | } | 1778 | } |
1779 | free(line); | ||
1727 | fclose(f); | 1780 | fclose(f); |
1728 | if (bad_options > 0) | 1781 | if (bad_options > 0) |
1729 | fatal("%s: terminating, %d bad configuration options", | 1782 | fatal("%s: terminating, %d bad configuration options", |
@@ -1761,7 +1814,6 @@ initialize_options(Options * options) | |||
1761 | options->fwd_opts.gateway_ports = -1; | 1814 | options->fwd_opts.gateway_ports = -1; |
1762 | options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; | 1815 | options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; |
1763 | options->fwd_opts.streamlocal_bind_unlink = -1; | 1816 | options->fwd_opts.streamlocal_bind_unlink = -1; |
1764 | options->use_privileged_port = -1; | ||
1765 | options->pubkey_authentication = -1; | 1817 | options->pubkey_authentication = -1; |
1766 | options->challenge_response_authentication = -1; | 1818 | options->challenge_response_authentication = -1; |
1767 | options->gss_authentication = -1; | 1819 | options->gss_authentication = -1; |
@@ -1815,7 +1867,10 @@ initialize_options(Options * options) | |||
1815 | options->verify_host_key_dns = -1; | 1867 | options->verify_host_key_dns = -1; |
1816 | options->server_alive_interval = -1; | 1868 | options->server_alive_interval = -1; |
1817 | options->server_alive_count_max = -1; | 1869 | options->server_alive_count_max = -1; |
1870 | options->send_env = NULL; | ||
1818 | options->num_send_env = 0; | 1871 | options->num_send_env = 0; |
1872 | options->setenv = NULL; | ||
1873 | options->num_setenv = 0; | ||
1819 | options->control_path = NULL; | 1874 | options->control_path = NULL; |
1820 | options->control_master = -1; | 1875 | options->control_master = -1; |
1821 | options->control_persist = -1; | 1876 | options->control_persist = -1; |
@@ -1869,6 +1924,9 @@ fill_default_options_for_canonicalization(Options *options) | |||
1869 | void | 1924 | void |
1870 | fill_default_options(Options * options) | 1925 | fill_default_options(Options * options) |
1871 | { | 1926 | { |
1927 | char *all_cipher, *all_mac, *all_kex, *all_key; | ||
1928 | int r; | ||
1929 | |||
1872 | if (options->forward_agent == -1) | 1930 | if (options->forward_agent == -1) |
1873 | options->forward_agent = 0; | 1931 | options->forward_agent = 0; |
1874 | if (options->forward_x11 == -1) | 1932 | if (options->forward_x11 == -1) |
@@ -1898,8 +1956,6 @@ fill_default_options(Options * options) | |||
1898 | options->fwd_opts.streamlocal_bind_mask = 0177; | 1956 | options->fwd_opts.streamlocal_bind_mask = 0177; |
1899 | if (options->fwd_opts.streamlocal_bind_unlink == -1) | 1957 | if (options->fwd_opts.streamlocal_bind_unlink == -1) |
1900 | options->fwd_opts.streamlocal_bind_unlink = 0; | 1958 | options->fwd_opts.streamlocal_bind_unlink = 0; |
1901 | if (options->use_privileged_port == -1) | ||
1902 | options->use_privileged_port = 0; | ||
1903 | if (options->pubkey_authentication == -1) | 1959 | if (options->pubkey_authentication == -1) |
1904 | options->pubkey_authentication = 1; | 1960 | options->pubkey_authentication = 1; |
1905 | if (options->challenge_response_authentication == -1) | 1961 | if (options->challenge_response_authentication == -1) |
@@ -1998,9 +2054,9 @@ fill_default_options(Options * options) | |||
1998 | if (options->visual_host_key == -1) | 2054 | if (options->visual_host_key == -1) |
1999 | options->visual_host_key = 0; | 2055 | options->visual_host_key = 0; |
2000 | if (options->ip_qos_interactive == -1) | 2056 | if (options->ip_qos_interactive == -1) |
2001 | options->ip_qos_interactive = IPTOS_LOWDELAY; | 2057 | options->ip_qos_interactive = IPTOS_DSCP_AF21; |
2002 | if (options->ip_qos_bulk == -1) | 2058 | if (options->ip_qos_bulk == -1) |
2003 | options->ip_qos_bulk = IPTOS_THROUGHPUT; | 2059 | options->ip_qos_bulk = IPTOS_DSCP_CS1; |
2004 | if (options->request_tty == -1) | 2060 | if (options->request_tty == -1) |
2005 | options->request_tty = REQUEST_TTY_AUTO; | 2061 | options->request_tty = REQUEST_TTY_AUTO; |
2006 | if (options->proxy_use_fdpass == -1) | 2062 | if (options->proxy_use_fdpass == -1) |
@@ -2015,14 +2071,28 @@ fill_default_options(Options * options) | |||
2015 | options->fingerprint_hash = SSH_FP_HASH_DEFAULT; | 2071 | options->fingerprint_hash = SSH_FP_HASH_DEFAULT; |
2016 | if (options->update_hostkeys == -1) | 2072 | if (options->update_hostkeys == -1) |
2017 | options->update_hostkeys = 0; | 2073 | options->update_hostkeys = 0; |
2018 | if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || | 2074 | |
2019 | kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || | 2075 | /* Expand KEX name lists */ |
2020 | kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || | 2076 | all_cipher = cipher_alg_list(',', 0); |
2021 | kex_assemble_names(KEX_DEFAULT_PK_ALG, | 2077 | all_mac = mac_alg_list(','); |
2022 | &options->hostbased_key_types) != 0 || | 2078 | all_kex = kex_alg_list(','); |
2023 | kex_assemble_names(KEX_DEFAULT_PK_ALG, | 2079 | all_key = sshkey_alg_list(0, 0, 1, ','); |
2024 | &options->pubkey_key_types) != 0) | 2080 | #define ASSEMBLE(what, defaults, all) \ |
2025 | fatal("%s: kex_assemble_names failed", __func__); | 2081 | do { \ |
2082 | if ((r = kex_assemble_names(&options->what, \ | ||
2083 | defaults, all)) != 0) \ | ||
2084 | fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ | ||
2085 | } while (0) | ||
2086 | ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); | ||
2087 | ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); | ||
2088 | ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); | ||
2089 | ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); | ||
2090 | ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); | ||
2091 | #undef ASSEMBLE | ||
2092 | free(all_cipher); | ||
2093 | free(all_mac); | ||
2094 | free(all_kex); | ||
2095 | free(all_key); | ||
2026 | 2096 | ||
2027 | #define CLEAR_ON_NONE(v) \ | 2097 | #define CLEAR_ON_NONE(v) \ |
2028 | do { \ | 2098 | do { \ |
@@ -2036,6 +2106,12 @@ fill_default_options(Options * options) | |||
2036 | CLEAR_ON_NONE(options->proxy_command); | 2106 | CLEAR_ON_NONE(options->proxy_command); |
2037 | CLEAR_ON_NONE(options->control_path); | 2107 | CLEAR_ON_NONE(options->control_path); |
2038 | CLEAR_ON_NONE(options->revoked_host_keys); | 2108 | CLEAR_ON_NONE(options->revoked_host_keys); |
2109 | if (options->jump_host != NULL && | ||
2110 | strcmp(options->jump_host, "none") == 0 && | ||
2111 | options->jump_port == 0 && options->jump_user == NULL) { | ||
2112 | free(options->jump_host); | ||
2113 | options->jump_host = NULL; | ||
2114 | } | ||
2039 | /* options->identity_agent distinguishes NULL from 'none' */ | 2115 | /* options->identity_agent distinguishes NULL from 'none' */ |
2040 | /* options->user will be set in the main program if appropriate */ | 2116 | /* options->user will be set in the main program if appropriate */ |
2041 | /* options->hostname will be set in the main program if appropriate */ | 2117 | /* options->hostname will be set in the main program if appropriate */ |
@@ -2264,6 +2340,8 @@ parse_jump(const char *s, Options *o, int active) | |||
2264 | orig = sdup = xstrdup(s); | 2340 | orig = sdup = xstrdup(s); |
2265 | first = active; | 2341 | first = active; |
2266 | do { | 2342 | do { |
2343 | if (strcasecmp(s, "none") == 0) | ||
2344 | break; | ||
2267 | if ((cp = strrchr(sdup, ',')) == NULL) | 2345 | if ((cp = strrchr(sdup, ',')) == NULL) |
2268 | cp = sdup; /* last */ | 2346 | cp = sdup; /* last */ |
2269 | else | 2347 | else |
@@ -2284,14 +2362,19 @@ parse_jump(const char *s, Options *o, int active) | |||
2284 | } while (cp != sdup); | 2362 | } while (cp != sdup); |
2285 | /* success */ | 2363 | /* success */ |
2286 | if (active) { | 2364 | if (active) { |
2287 | o->jump_user = user; | 2365 | if (strcasecmp(s, "none") == 0) { |
2288 | o->jump_host = host; | 2366 | o->jump_host = xstrdup("none"); |
2289 | o->jump_port = port; | 2367 | o->jump_port = 0; |
2290 | o->proxy_command = xstrdup("none"); | 2368 | } else { |
2291 | user = host = NULL; | 2369 | o->jump_user = user; |
2292 | if ((cp = strrchr(s, ',')) != NULL && cp != s) { | 2370 | o->jump_host = host; |
2293 | o->jump_extra = xstrdup(s); | 2371 | o->jump_port = port; |
2294 | o->jump_extra[cp - s] = '\0'; | 2372 | o->proxy_command = xstrdup("none"); |
2373 | user = host = NULL; | ||
2374 | if ((cp = strrchr(s, ',')) != NULL && cp != s) { | ||
2375 | o->jump_extra = xstrdup(s); | ||
2376 | o->jump_extra[cp - s] = '\0'; | ||
2377 | } | ||
2295 | } | 2378 | } |
2296 | } | 2379 | } |
2297 | ret = 0; | 2380 | ret = 0; |
@@ -2348,6 +2431,8 @@ fmt_intarg(OpCodes code, int val) | |||
2348 | return fmt_multistate_int(val, multistate_requesttty); | 2431 | return fmt_multistate_int(val, multistate_requesttty); |
2349 | case oCanonicalizeHostname: | 2432 | case oCanonicalizeHostname: |
2350 | return fmt_multistate_int(val, multistate_canonicalizehostname); | 2433 | return fmt_multistate_int(val, multistate_canonicalizehostname); |
2434 | case oAddKeysToAgent: | ||
2435 | return fmt_multistate_int(val, multistate_yesnoaskconfirm); | ||
2351 | case oFingerprintHash: | 2436 | case oFingerprintHash: |
2352 | return ssh_digest_alg_name(val); | 2437 | return ssh_digest_alg_name(val); |
2353 | default: | 2438 | default: |
@@ -2455,11 +2540,14 @@ void | |||
2455 | dump_client_config(Options *o, const char *host) | 2540 | dump_client_config(Options *o, const char *host) |
2456 | { | 2541 | { |
2457 | int i; | 2542 | int i; |
2458 | char buf[8]; | 2543 | char buf[8], *all_key; |
2459 | 2544 | ||
2460 | /* This is normally prepared in ssh_kex2 */ | 2545 | /* This is normally prepared in ssh_kex2 */ |
2461 | if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) | 2546 | all_key = sshkey_alg_list(0, 0, 1, ','); |
2547 | if (kex_assemble_names( &o->hostkeyalgorithms, | ||
2548 | KEX_DEFAULT_PK_ALG, all_key) != 0) | ||
2462 | fatal("%s: kex_assemble_names failed", __func__); | 2549 | fatal("%s: kex_assemble_names failed", __func__); |
2550 | free(all_key); | ||
2463 | 2551 | ||
2464 | /* Most interesting options first: user, host, port */ | 2552 | /* Most interesting options first: user, host, port */ |
2465 | dump_cfg_string(oUser, o->user); | 2553 | dump_cfg_string(oUser, o->user); |
@@ -2467,6 +2555,7 @@ dump_client_config(Options *o, const char *host) | |||
2467 | dump_cfg_int(oPort, o->port); | 2555 | dump_cfg_int(oPort, o->port); |
2468 | 2556 | ||
2469 | /* Flag options */ | 2557 | /* Flag options */ |
2558 | dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent); | ||
2470 | dump_cfg_fmtint(oAddressFamily, o->address_family); | 2559 | dump_cfg_fmtint(oAddressFamily, o->address_family); |
2471 | dump_cfg_fmtint(oBatchMode, o->batch_mode); | 2560 | dump_cfg_fmtint(oBatchMode, o->batch_mode); |
2472 | dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); | 2561 | dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); |
@@ -2501,7 +2590,6 @@ dump_client_config(Options *o, const char *host) | |||
2501 | dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); | 2590 | dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); |
2502 | dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); | 2591 | dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); |
2503 | dump_cfg_fmtint(oTunnel, o->tun_open); | 2592 | dump_cfg_fmtint(oTunnel, o->tun_open); |
2504 | dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port); | ||
2505 | dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); | 2593 | dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); |
2506 | dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); | 2594 | dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); |
2507 | dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); | 2595 | dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); |
@@ -2523,6 +2611,7 @@ dump_client_config(Options *o, const char *host) | |||
2523 | dump_cfg_string(oHostKeyAlias, o->host_key_alias); | 2611 | dump_cfg_string(oHostKeyAlias, o->host_key_alias); |
2524 | dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); | 2612 | dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); |
2525 | dump_cfg_string(oIdentityAgent, o->identity_agent); | 2613 | dump_cfg_string(oIdentityAgent, o->identity_agent); |
2614 | dump_cfg_string(oIgnoreUnknown, o->ignored_unknown); | ||
2526 | dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); | 2615 | dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); |
2527 | dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); | 2616 | dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); |
2528 | dump_cfg_string(oLocalCommand, o->local_command); | 2617 | dump_cfg_string(oLocalCommand, o->local_command); |
@@ -2545,9 +2634,11 @@ dump_client_config(Options *o, const char *host) | |||
2545 | /* String array options */ | 2634 | /* String array options */ |
2546 | dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); | 2635 | dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); |
2547 | dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); | 2636 | dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); |
2637 | dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files); | ||
2548 | dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); | 2638 | dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); |
2549 | dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); | 2639 | dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); |
2550 | dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); | 2640 | dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); |
2641 | dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv); | ||
2551 | 2642 | ||
2552 | /* Special cases */ | 2643 | /* Special cases */ |
2553 | 2644 | ||
@@ -2605,6 +2696,9 @@ dump_client_config(Options *o, const char *host) | |||
2605 | printf("streamlocalbindmask 0%o\n", | 2696 | printf("streamlocalbindmask 0%o\n", |
2606 | o->fwd_opts.streamlocal_bind_mask); | 2697 | o->fwd_opts.streamlocal_bind_mask); |
2607 | 2698 | ||
2699 | /* oLogFacility */ | ||
2700 | printf("syslogfacility %s\n", log_facility_name(o->log_facility)); | ||
2701 | |||
2608 | /* oProxyCommand / oProxyJump */ | 2702 | /* oProxyCommand / oProxyJump */ |
2609 | if (o->jump_host == NULL) | 2703 | if (o->jump_host == NULL) |
2610 | dump_cfg_string(oProxyCommand, o->proxy_command); | 2704 | dump_cfg_string(oProxyCommand, o->proxy_command); |