diff options
Diffstat (limited to 'readconf.c')
-rw-r--r-- | readconf.c | 76 |
1 files changed, 34 insertions, 42 deletions
diff --git a/readconf.c b/readconf.c index 41f36aa8d..efcf2d628 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.279 2017/09/21 19:16:53 markus Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.283 2018/02/23 15:58:37 markus 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 |
@@ -156,7 +156,7 @@ typedef enum { | |||
156 | oPubkeyAuthentication, | 156 | oPubkeyAuthentication, |
157 | oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, | 157 | oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, |
158 | oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, | 158 | oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, |
159 | oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, | 159 | oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider, |
160 | oClearAllForwardings, oNoHostAuthenticationForLocalhost, | 160 | oClearAllForwardings, oNoHostAuthenticationForLocalhost, |
161 | oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, | 161 | oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, |
162 | oAddressFamily, oGssAuthentication, oGssDelegateCreds, | 162 | oAddressFamily, oGssAuthentication, oGssDelegateCreds, |
@@ -280,6 +280,7 @@ static struct { | |||
280 | { "preferredauthentications", oPreferredAuthentications }, | 280 | { "preferredauthentications", oPreferredAuthentications }, |
281 | { "hostkeyalgorithms", oHostKeyAlgorithms }, | 281 | { "hostkeyalgorithms", oHostKeyAlgorithms }, |
282 | { "bindaddress", oBindAddress }, | 282 | { "bindaddress", oBindAddress }, |
283 | { "bindinterface", oBindInterface }, | ||
283 | { "clearallforwardings", oClearAllForwardings }, | 284 | { "clearallforwardings", oClearAllForwardings }, |
284 | { "enablesshkeysign", oEnableSSHKeysign }, | 285 | { "enablesshkeysign", oEnableSSHKeysign }, |
285 | { "verifyhostkeydns", oVerifyHostKeyDNS }, | 286 | { "verifyhostkeydns", oVerifyHostKeyDNS }, |
@@ -699,34 +700,6 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
699 | return result; | 700 | return result; |
700 | } | 701 | } |
701 | 702 | ||
702 | /* Check and prepare a domain name: removes trailing '.' and lowercases */ | ||
703 | static void | ||
704 | valid_domain(char *name, const char *filename, int linenum) | ||
705 | { | ||
706 | size_t i, l = strlen(name); | ||
707 | u_char c, last = '\0'; | ||
708 | |||
709 | if (l == 0) | ||
710 | fatal("%s line %d: empty hostname suffix", filename, linenum); | ||
711 | if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) | ||
712 | fatal("%s line %d: hostname suffix \"%.100s\" " | ||
713 | "starts with invalid character", filename, linenum, name); | ||
714 | for (i = 0; i < l; i++) { | ||
715 | c = tolower((u_char)name[i]); | ||
716 | name[i] = (char)c; | ||
717 | if (last == '.' && c == '.') | ||
718 | fatal("%s line %d: hostname suffix \"%.100s\" contains " | ||
719 | "consecutive separators", filename, linenum, name); | ||
720 | if (c != '.' && c != '-' && !isalnum(c) && | ||
721 | c != '_') /* technically invalid, but common */ | ||
722 | fatal("%s line %d: hostname suffix \"%.100s\" contains " | ||
723 | "invalid characters", filename, linenum, name); | ||
724 | last = c; | ||
725 | } | ||
726 | if (name[l - 1] == '.') | ||
727 | name[l - 1] = '\0'; | ||
728 | } | ||
729 | |||
730 | /* | 703 | /* |
731 | * Returns the number of the token pointed to by cp or oBadOption. | 704 | * Returns the number of the token pointed to by cp or oBadOption. |
732 | */ | 705 | */ |
@@ -861,6 +834,7 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, | |||
861 | const struct multistate *multistate_ptr; | 834 | const struct multistate *multistate_ptr; |
862 | struct allowed_cname *cname; | 835 | struct allowed_cname *cname; |
863 | glob_t gl; | 836 | glob_t gl; |
837 | const char *errstr; | ||
864 | 838 | ||
865 | if (activep == NULL) { /* We are processing a command line directive */ | 839 | if (activep == NULL) { /* We are processing a command line directive */ |
866 | cmdline = 1; | 840 | cmdline = 1; |
@@ -1162,6 +1136,10 @@ parse_char_array: | |||
1162 | charptr = &options->bind_address; | 1136 | charptr = &options->bind_address; |
1163 | goto parse_string; | 1137 | goto parse_string; |
1164 | 1138 | ||
1139 | case oBindInterface: | ||
1140 | charptr = &options->bind_interface; | ||
1141 | goto parse_string; | ||
1142 | |||
1165 | case oPKCS11Provider: | 1143 | case oPKCS11Provider: |
1166 | charptr = &options->pkcs11_provider; | 1144 | charptr = &options->pkcs11_provider; |
1167 | goto parse_string; | 1145 | goto parse_string; |
@@ -1195,15 +1173,9 @@ parse_command: | |||
1195 | intptr = &options->port; | 1173 | intptr = &options->port; |
1196 | parse_int: | 1174 | parse_int: |
1197 | arg = strdelim(&s); | 1175 | arg = strdelim(&s); |
1198 | if (!arg || *arg == '\0') | 1176 | if ((errstr = atoi_err(arg, &value)) != NULL) |
1199 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 1177 | fatal("%s line %d: integer value %s.", |
1200 | if (arg[0] < '0' || arg[0] > '9') | 1178 | filename, linenum, errstr); |
1201 | fatal("%.200s line %d: Bad number.", filename, linenum); | ||
1202 | |||
1203 | /* Octal, decimal, or hex format? */ | ||
1204 | value = strtol(arg, &endofnumber, 0); | ||
1205 | if (arg == endofnumber) | ||
1206 | fatal("%.200s line %d: Bad number.", filename, linenum); | ||
1207 | if (*activep && *intptr == -1) | 1179 | if (*activep && *intptr == -1) |
1208 | *intptr = value; | 1180 | *intptr = value; |
1209 | break; | 1181 | break; |
@@ -1600,7 +1572,10 @@ parse_keytypes: | |||
1600 | case oCanonicalDomains: | 1572 | case oCanonicalDomains: |
1601 | value = options->num_canonical_domains != 0; | 1573 | value = options->num_canonical_domains != 0; |
1602 | while ((arg = strdelim(&s)) != NULL && *arg != '\0') { | 1574 | while ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
1603 | valid_domain(arg, filename, linenum); | 1575 | if (!valid_domain(arg, 1, &errstr)) { |
1576 | fatal("%s line %d: %s", filename, linenum, | ||
1577 | errstr); | ||
1578 | } | ||
1604 | if (!*activep || value) | 1579 | if (!*activep || value) |
1605 | continue; | 1580 | continue; |
1606 | if (options->num_canonical_domains >= MAX_CANON_DOMAINS) | 1581 | if (options->num_canonical_domains >= MAX_CANON_DOMAINS) |
@@ -1872,6 +1847,7 @@ initialize_options(Options * options) | |||
1872 | options->log_level = SYSLOG_LEVEL_NOT_SET; | 1847 | options->log_level = SYSLOG_LEVEL_NOT_SET; |
1873 | options->preferred_authentications = NULL; | 1848 | options->preferred_authentications = NULL; |
1874 | options->bind_address = NULL; | 1849 | options->bind_address = NULL; |
1850 | options->bind_interface = NULL; | ||
1875 | options->pkcs11_provider = NULL; | 1851 | options->pkcs11_provider = NULL; |
1876 | options->enable_ssh_keysign = - 1; | 1852 | options->enable_ssh_keysign = - 1; |
1877 | options->no_host_authentication_for_localhost = - 1; | 1853 | options->no_host_authentication_for_localhost = - 1; |
@@ -2015,6 +1991,7 @@ fill_default_options(Options * options) | |||
2015 | #endif | 1991 | #endif |
2016 | add_identity_file(options, "~/", | 1992 | add_identity_file(options, "~/", |
2017 | _PATH_SSH_CLIENT_ID_ED25519, 0); | 1993 | _PATH_SSH_CLIENT_ID_ED25519, 0); |
1994 | add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0); | ||
2018 | } | 1995 | } |
2019 | if (options->escape_char == -1) | 1996 | if (options->escape_char == -1) |
2020 | options->escape_char = '~'; | 1997 | options->escape_char = '~'; |
@@ -2347,11 +2324,13 @@ parse_jump(const char *s, Options *o, int active) | |||
2347 | 2324 | ||
2348 | if (first) { | 2325 | if (first) { |
2349 | /* First argument and configuration is active */ | 2326 | /* First argument and configuration is active */ |
2350 | if (parse_user_host_port(cp, &user, &host, &port) != 0) | 2327 | if (parse_ssh_uri(cp, &user, &host, &port) == -1 || |
2328 | parse_user_host_port(cp, &user, &host, &port) != 0) | ||
2351 | goto out; | 2329 | goto out; |
2352 | } else { | 2330 | } else { |
2353 | /* Subsequent argument or inactive configuration */ | 2331 | /* Subsequent argument or inactive configuration */ |
2354 | if (parse_user_host_port(cp, NULL, NULL, NULL) != 0) | 2332 | if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 || |
2333 | parse_user_host_port(cp, NULL, NULL, NULL) != 0) | ||
2355 | goto out; | 2334 | goto out; |
2356 | } | 2335 | } |
2357 | first = 0; /* only check syntax for subsequent hosts */ | 2336 | first = 0; /* only check syntax for subsequent hosts */ |
@@ -2376,6 +2355,18 @@ parse_jump(const char *s, Options *o, int active) | |||
2376 | return ret; | 2355 | return ret; |
2377 | } | 2356 | } |
2378 | 2357 | ||
2358 | int | ||
2359 | parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp) | ||
2360 | { | ||
2361 | char *path; | ||
2362 | int r; | ||
2363 | |||
2364 | r = parse_uri("ssh", uri, userp, hostp, portp, &path); | ||
2365 | if (r == 0 && path != NULL) | ||
2366 | r = -1; /* path not allowed */ | ||
2367 | return r; | ||
2368 | } | ||
2369 | |||
2379 | /* XXX the following is a near-vebatim copy from servconf.c; refactor */ | 2370 | /* XXX the following is a near-vebatim copy from servconf.c; refactor */ |
2380 | static const char * | 2371 | static const char * |
2381 | fmt_multistate_int(int val, const struct multistate *m) | 2372 | fmt_multistate_int(int val, const struct multistate *m) |
@@ -2578,6 +2569,7 @@ dump_client_config(Options *o, const char *host) | |||
2578 | 2569 | ||
2579 | /* String options */ | 2570 | /* String options */ |
2580 | dump_cfg_string(oBindAddress, o->bind_address); | 2571 | dump_cfg_string(oBindAddress, o->bind_address); |
2572 | dump_cfg_string(oBindInterface, o->bind_interface); | ||
2581 | dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); | 2573 | dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); |
2582 | dump_cfg_string(oControlPath, o->control_path); | 2574 | dump_cfg_string(oControlPath, o->control_path); |
2583 | dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms); | 2575 | dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms); |