diff options
Diffstat (limited to 'readconf.c')
-rw-r--r-- | readconf.c | 95 |
1 files changed, 89 insertions, 6 deletions
diff --git a/readconf.c b/readconf.c index 9dcc383da..cb2999d82 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.256 2016/06/03 04:09:38 dtucker Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.257 2016/07/15 00:24:30 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 |
@@ -170,7 +170,7 @@ typedef enum { | |||
170 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, | 170 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, |
171 | oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, | 171 | oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, |
172 | oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, | 172 | oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, |
173 | oPubkeyAcceptedKeyTypes, | 173 | oPubkeyAcceptedKeyTypes, oProxyJump, |
174 | oIgnoredUnknownOption, oDeprecated, oUnsupported | 174 | oIgnoredUnknownOption, oDeprecated, oUnsupported |
175 | } OpCodes; | 175 | } OpCodes; |
176 | 176 | ||
@@ -295,6 +295,7 @@ static struct { | |||
295 | { "hostbasedkeytypes", oHostbasedKeyTypes }, | 295 | { "hostbasedkeytypes", oHostbasedKeyTypes }, |
296 | { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes }, | 296 | { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes }, |
297 | { "ignoreunknown", oIgnoreUnknown }, | 297 | { "ignoreunknown", oIgnoreUnknown }, |
298 | { "proxyjump", oProxyJump }, | ||
298 | 299 | ||
299 | { NULL, oBadOption } | 300 | { NULL, oBadOption } |
300 | }; | 301 | }; |
@@ -1121,6 +1122,9 @@ parse_char_array: | |||
1121 | 1122 | ||
1122 | case oProxyCommand: | 1123 | case oProxyCommand: |
1123 | charptr = &options->proxy_command; | 1124 | charptr = &options->proxy_command; |
1125 | /* Ignore ProxyCommand if ProxyJump already specified */ | ||
1126 | if (options->jump_host != NULL) | ||
1127 | charptr = &options->jump_host; /* Skip below */ | ||
1124 | parse_command: | 1128 | parse_command: |
1125 | if (s == NULL) | 1129 | if (s == NULL) |
1126 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 1130 | fatal("%.200s line %d: Missing argument.", filename, linenum); |
@@ -1129,6 +1133,18 @@ parse_command: | |||
1129 | *charptr = xstrdup(s + len); | 1133 | *charptr = xstrdup(s + len); |
1130 | return 0; | 1134 | return 0; |
1131 | 1135 | ||
1136 | case oProxyJump: | ||
1137 | if (s == NULL) { | ||
1138 | fatal("%.200s line %d: Missing argument.", | ||
1139 | filename, linenum); | ||
1140 | } | ||
1141 | len = strspn(s, WHITESPACE "="); | ||
1142 | if (parse_jump(s + len, options, *activep) == -1) { | ||
1143 | fatal("%.200s line %d: Invalid ProxyJump \"%s\"", | ||
1144 | filename, linenum, s + len); | ||
1145 | } | ||
1146 | return 0; | ||
1147 | |||
1132 | case oPort: | 1148 | case oPort: |
1133 | intptr = &options->port; | 1149 | intptr = &options->port; |
1134 | parse_int: | 1150 | parse_int: |
@@ -1789,6 +1805,10 @@ initialize_options(Options * options) | |||
1789 | options->hostname = NULL; | 1805 | options->hostname = NULL; |
1790 | options->host_key_alias = NULL; | 1806 | options->host_key_alias = NULL; |
1791 | options->proxy_command = NULL; | 1807 | options->proxy_command = NULL; |
1808 | options->jump_user = NULL; | ||
1809 | options->jump_host = NULL; | ||
1810 | options->jump_port = -1; | ||
1811 | options->jump_extra = NULL; | ||
1792 | options->user = NULL; | 1812 | options->user = NULL; |
1793 | options->escape_char = -1; | 1813 | options->escape_char = -1; |
1794 | options->num_system_hostfiles = 0; | 1814 | options->num_system_hostfiles = 0; |
@@ -2261,6 +2281,44 @@ parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remo | |||
2261 | return (0); | 2281 | return (0); |
2262 | } | 2282 | } |
2263 | 2283 | ||
2284 | int | ||
2285 | parse_jump(const char *s, Options *o, int active) | ||
2286 | { | ||
2287 | char *orig, *sdup, *cp; | ||
2288 | char *host = NULL, *user = NULL; | ||
2289 | int ret = -1, port = -1; | ||
2290 | |||
2291 | active &= o->proxy_command == NULL && o->jump_host == NULL; | ||
2292 | |||
2293 | orig = sdup = xstrdup(s); | ||
2294 | while ((cp = strsep(&sdup, ",")) && cp != NULL) { | ||
2295 | if (active) { | ||
2296 | /* First argument and configuration is active */ | ||
2297 | if (parse_user_host_port(cp, &user, &host, &port) != 0) | ||
2298 | goto out; | ||
2299 | } else { | ||
2300 | /* Subsequent argument or inactive configuration */ | ||
2301 | if (parse_user_host_port(cp, NULL, NULL, NULL) != 0) | ||
2302 | goto out; | ||
2303 | } | ||
2304 | active = 0; /* only check syntax for subsequent hosts */ | ||
2305 | } | ||
2306 | /* success */ | ||
2307 | free(orig); | ||
2308 | o->jump_user = user; | ||
2309 | o->jump_host = host; | ||
2310 | o->jump_port = port; | ||
2311 | o->proxy_command = xstrdup("none"); | ||
2312 | user = host = NULL; | ||
2313 | if ((cp = strchr(s, ',')) != NULL && cp[1] != '\0') | ||
2314 | o->jump_extra = xstrdup(cp + 1); | ||
2315 | ret = 0; | ||
2316 | out: | ||
2317 | free(user); | ||
2318 | free(host); | ||
2319 | return ret; | ||
2320 | } | ||
2321 | |||
2264 | /* XXX the following is a near-vebatim copy from servconf.c; refactor */ | 2322 | /* XXX the following is a near-vebatim copy from servconf.c; refactor */ |
2265 | static const char * | 2323 | static const char * |
2266 | fmt_multistate_int(int val, const struct multistate *m) | 2324 | fmt_multistate_int(int val, const struct multistate *m) |
@@ -2412,7 +2470,7 @@ void | |||
2412 | dump_client_config(Options *o, const char *host) | 2470 | dump_client_config(Options *o, const char *host) |
2413 | { | 2471 | { |
2414 | int i; | 2472 | int i; |
2415 | char vbuf[5]; | 2473 | char buf[8]; |
2416 | 2474 | ||
2417 | /* This is normally prepared in ssh_kex2 */ | 2475 | /* This is normally prepared in ssh_kex2 */ |
2418 | if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) | 2476 | if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) |
@@ -2490,7 +2548,6 @@ dump_client_config(Options *o, const char *host) | |||
2490 | dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC); | 2548 | dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC); |
2491 | dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); | 2549 | dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); |
2492 | dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); | 2550 | dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); |
2493 | dump_cfg_string(oProxyCommand, o->proxy_command); | ||
2494 | dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types); | 2551 | dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types); |
2495 | dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); | 2552 | dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); |
2496 | dump_cfg_string(oXAuthLocation, o->xauth_location); | 2553 | dump_cfg_string(oXAuthLocation, o->xauth_location); |
@@ -2551,8 +2608,8 @@ dump_client_config(Options *o, const char *host) | |||
2551 | if (o->escape_char == SSH_ESCAPECHAR_NONE) | 2608 | if (o->escape_char == SSH_ESCAPECHAR_NONE) |
2552 | printf("escapechar none\n"); | 2609 | printf("escapechar none\n"); |
2553 | else { | 2610 | else { |
2554 | vis(vbuf, o->escape_char, VIS_WHITE, 0); | 2611 | vis(buf, o->escape_char, VIS_WHITE, 0); |
2555 | printf("escapechar %s\n", vbuf); | 2612 | printf("escapechar %s\n", buf); |
2556 | } | 2613 | } |
2557 | 2614 | ||
2558 | /* oIPQoS */ | 2615 | /* oIPQoS */ |
@@ -2566,4 +2623,30 @@ dump_client_config(Options *o, const char *host) | |||
2566 | /* oStreamLocalBindMask */ | 2623 | /* oStreamLocalBindMask */ |
2567 | printf("streamlocalbindmask 0%o\n", | 2624 | printf("streamlocalbindmask 0%o\n", |
2568 | o->fwd_opts.streamlocal_bind_mask); | 2625 | o->fwd_opts.streamlocal_bind_mask); |
2626 | |||
2627 | /* oProxyCommand / oProxyJump */ | ||
2628 | if (o->jump_host == NULL) | ||
2629 | dump_cfg_string(oProxyCommand, o->proxy_command); | ||
2630 | else { | ||
2631 | /* Check for numeric addresses */ | ||
2632 | i = strchr(o->jump_host, ':') != NULL || | ||
2633 | strspn(o->jump_host, "1234567890.") == strlen(o->jump_host); | ||
2634 | snprintf(buf, sizeof(buf), "%d", o->jump_port); | ||
2635 | printf("proxyjump %s%s%s%s%s%s%s%s%s\n", | ||
2636 | /* optional user */ | ||
2637 | o->jump_user == NULL ? "" : o->jump_user, | ||
2638 | o->jump_user == NULL ? "" : "@", | ||
2639 | /* opening [ if hostname is numeric */ | ||
2640 | i ? "[" : "", | ||
2641 | /* mandatory hostname */ | ||
2642 | o->jump_host, | ||
2643 | /* closing ] if hostname is numeric */ | ||
2644 | i ? "]" : "", | ||
2645 | /* optional port number */ | ||
2646 | o->jump_port <= 0 ? "" : ":", | ||
2647 | o->jump_port <= 0 ? "" : buf, | ||
2648 | /* optional additional jump spec */ | ||
2649 | o->jump_extra == NULL ? "" : ",", | ||
2650 | o->jump_extra == NULL ? "" : o->jump_extra); | ||
2651 | } | ||
2569 | } | 2652 | } |