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 f63894f9c..88051db57 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, |
@@ -266,6 +266,7 @@ static struct { | |||
266 | { "preferredauthentications", oPreferredAuthentications }, | 266 | { "preferredauthentications", oPreferredAuthentications }, |
267 | { "hostkeyalgorithms", oHostKeyAlgorithms }, | 267 | { "hostkeyalgorithms", oHostKeyAlgorithms }, |
268 | { "bindaddress", oBindAddress }, | 268 | { "bindaddress", oBindAddress }, |
269 | { "bindinterface", oBindInterface }, | ||
269 | { "clearallforwardings", oClearAllForwardings }, | 270 | { "clearallforwardings", oClearAllForwardings }, |
270 | { "enablesshkeysign", oEnableSSHKeysign }, | 271 | { "enablesshkeysign", oEnableSSHKeysign }, |
271 | { "verifyhostkeydns", oVerifyHostKeyDNS }, | 272 | { "verifyhostkeydns", oVerifyHostKeyDNS }, |
@@ -683,34 +684,6 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
683 | return result; | 684 | return result; |
684 | } | 685 | } |
685 | 686 | ||
686 | /* Check and prepare a domain name: removes trailing '.' and lowercases */ | ||
687 | static void | ||
688 | valid_domain(char *name, const char *filename, int linenum) | ||
689 | { | ||
690 | size_t i, l = strlen(name); | ||
691 | u_char c, last = '\0'; | ||
692 | |||
693 | if (l == 0) | ||
694 | fatal("%s line %d: empty hostname suffix", filename, linenum); | ||
695 | if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) | ||
696 | fatal("%s line %d: hostname suffix \"%.100s\" " | ||
697 | "starts with invalid character", filename, linenum, name); | ||
698 | for (i = 0; i < l; i++) { | ||
699 | c = tolower((u_char)name[i]); | ||
700 | name[i] = (char)c; | ||
701 | if (last == '.' && c == '.') | ||
702 | fatal("%s line %d: hostname suffix \"%.100s\" contains " | ||
703 | "consecutive separators", filename, linenum, name); | ||
704 | if (c != '.' && c != '-' && !isalnum(c) && | ||
705 | c != '_') /* technically invalid, but common */ | ||
706 | fatal("%s line %d: hostname suffix \"%.100s\" contains " | ||
707 | "invalid characters", filename, linenum, name); | ||
708 | last = c; | ||
709 | } | ||
710 | if (name[l - 1] == '.') | ||
711 | name[l - 1] = '\0'; | ||
712 | } | ||
713 | |||
714 | /* | 687 | /* |
715 | * Returns the number of the token pointed to by cp or oBadOption. | 688 | * Returns the number of the token pointed to by cp or oBadOption. |
716 | */ | 689 | */ |
@@ -845,6 +818,7 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, | |||
845 | const struct multistate *multistate_ptr; | 818 | const struct multistate *multistate_ptr; |
846 | struct allowed_cname *cname; | 819 | struct allowed_cname *cname; |
847 | glob_t gl; | 820 | glob_t gl; |
821 | const char *errstr; | ||
848 | 822 | ||
849 | if (activep == NULL) { /* We are processing a command line directive */ | 823 | if (activep == NULL) { /* We are processing a command line directive */ |
850 | cmdline = 1; | 824 | cmdline = 1; |
@@ -1126,6 +1100,10 @@ parse_char_array: | |||
1126 | charptr = &options->bind_address; | 1100 | charptr = &options->bind_address; |
1127 | goto parse_string; | 1101 | goto parse_string; |
1128 | 1102 | ||
1103 | case oBindInterface: | ||
1104 | charptr = &options->bind_interface; | ||
1105 | goto parse_string; | ||
1106 | |||
1129 | case oPKCS11Provider: | 1107 | case oPKCS11Provider: |
1130 | charptr = &options->pkcs11_provider; | 1108 | charptr = &options->pkcs11_provider; |
1131 | goto parse_string; | 1109 | goto parse_string; |
@@ -1159,15 +1137,9 @@ parse_command: | |||
1159 | intptr = &options->port; | 1137 | intptr = &options->port; |
1160 | parse_int: | 1138 | parse_int: |
1161 | arg = strdelim(&s); | 1139 | arg = strdelim(&s); |
1162 | if (!arg || *arg == '\0') | 1140 | if ((errstr = atoi_err(arg, &value)) != NULL) |
1163 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 1141 | fatal("%s line %d: integer value %s.", |
1164 | if (arg[0] < '0' || arg[0] > '9') | 1142 | filename, linenum, errstr); |
1165 | fatal("%.200s line %d: Bad number.", filename, linenum); | ||
1166 | |||
1167 | /* Octal, decimal, or hex format? */ | ||
1168 | value = strtol(arg, &endofnumber, 0); | ||
1169 | if (arg == endofnumber) | ||
1170 | fatal("%.200s line %d: Bad number.", filename, linenum); | ||
1171 | if (*activep && *intptr == -1) | 1143 | if (*activep && *intptr == -1) |
1172 | *intptr = value; | 1144 | *intptr = value; |
1173 | break; | 1145 | break; |
@@ -1562,7 +1534,10 @@ parse_keytypes: | |||
1562 | case oCanonicalDomains: | 1534 | case oCanonicalDomains: |
1563 | value = options->num_canonical_domains != 0; | 1535 | value = options->num_canonical_domains != 0; |
1564 | while ((arg = strdelim(&s)) != NULL && *arg != '\0') { | 1536 | while ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
1565 | valid_domain(arg, filename, linenum); | 1537 | if (!valid_domain(arg, 1, &errstr)) { |
1538 | fatal("%s line %d: %s", filename, linenum, | ||
1539 | errstr); | ||
1540 | } | ||
1566 | if (!*activep || value) | 1541 | if (!*activep || value) |
1567 | continue; | 1542 | continue; |
1568 | if (options->num_canonical_domains >= MAX_CANON_DOMAINS) | 1543 | if (options->num_canonical_domains >= MAX_CANON_DOMAINS) |
@@ -1830,6 +1805,7 @@ initialize_options(Options * options) | |||
1830 | options->log_level = SYSLOG_LEVEL_NOT_SET; | 1805 | options->log_level = SYSLOG_LEVEL_NOT_SET; |
1831 | options->preferred_authentications = NULL; | 1806 | options->preferred_authentications = NULL; |
1832 | options->bind_address = NULL; | 1807 | options->bind_address = NULL; |
1808 | options->bind_interface = NULL; | ||
1833 | options->pkcs11_provider = NULL; | 1809 | options->pkcs11_provider = NULL; |
1834 | options->enable_ssh_keysign = - 1; | 1810 | options->enable_ssh_keysign = - 1; |
1835 | options->no_host_authentication_for_localhost = - 1; | 1811 | options->no_host_authentication_for_localhost = - 1; |
@@ -1967,6 +1943,7 @@ fill_default_options(Options * options) | |||
1967 | #endif | 1943 | #endif |
1968 | add_identity_file(options, "~/", | 1944 | add_identity_file(options, "~/", |
1969 | _PATH_SSH_CLIENT_ID_ED25519, 0); | 1945 | _PATH_SSH_CLIENT_ID_ED25519, 0); |
1946 | add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0); | ||
1970 | } | 1947 | } |
1971 | if (options->escape_char == -1) | 1948 | if (options->escape_char == -1) |
1972 | options->escape_char = '~'; | 1949 | options->escape_char = '~'; |
@@ -2294,11 +2271,13 @@ parse_jump(const char *s, Options *o, int active) | |||
2294 | 2271 | ||
2295 | if (first) { | 2272 | if (first) { |
2296 | /* First argument and configuration is active */ | 2273 | /* First argument and configuration is active */ |
2297 | if (parse_user_host_port(cp, &user, &host, &port) != 0) | 2274 | if (parse_ssh_uri(cp, &user, &host, &port) == -1 || |
2275 | parse_user_host_port(cp, &user, &host, &port) != 0) | ||
2298 | goto out; | 2276 | goto out; |
2299 | } else { | 2277 | } else { |
2300 | /* Subsequent argument or inactive configuration */ | 2278 | /* Subsequent argument or inactive configuration */ |
2301 | if (parse_user_host_port(cp, NULL, NULL, NULL) != 0) | 2279 | if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 || |
2280 | parse_user_host_port(cp, NULL, NULL, NULL) != 0) | ||
2302 | goto out; | 2281 | goto out; |
2303 | } | 2282 | } |
2304 | first = 0; /* only check syntax for subsequent hosts */ | 2283 | first = 0; /* only check syntax for subsequent hosts */ |
@@ -2323,6 +2302,18 @@ parse_jump(const char *s, Options *o, int active) | |||
2323 | return ret; | 2302 | return ret; |
2324 | } | 2303 | } |
2325 | 2304 | ||
2305 | int | ||
2306 | parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp) | ||
2307 | { | ||
2308 | char *path; | ||
2309 | int r; | ||
2310 | |||
2311 | r = parse_uri("ssh", uri, userp, hostp, portp, &path); | ||
2312 | if (r == 0 && path != NULL) | ||
2313 | r = -1; /* path not allowed */ | ||
2314 | return r; | ||
2315 | } | ||
2316 | |||
2326 | /* XXX the following is a near-vebatim copy from servconf.c; refactor */ | 2317 | /* XXX the following is a near-vebatim copy from servconf.c; refactor */ |
2327 | static const char * | 2318 | static const char * |
2328 | fmt_multistate_int(int val, const struct multistate *m) | 2319 | fmt_multistate_int(int val, const struct multistate *m) |
@@ -2525,6 +2516,7 @@ dump_client_config(Options *o, const char *host) | |||
2525 | 2516 | ||
2526 | /* String options */ | 2517 | /* String options */ |
2527 | dump_cfg_string(oBindAddress, o->bind_address); | 2518 | dump_cfg_string(oBindAddress, o->bind_address); |
2519 | dump_cfg_string(oBindInterface, o->bind_interface); | ||
2528 | dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); | 2520 | dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); |
2529 | dump_cfg_string(oControlPath, o->control_path); | 2521 | dump_cfg_string(oControlPath, o->control_path); |
2530 | dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms); | 2522 | dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms); |