summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'readconf.c')
-rw-r--r--readconf.c76
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 */
703static void
704valid_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;
1196parse_int: 1174parse_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
2358int
2359parse_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 */
2380static const char * 2371static const char *
2381fmt_multistate_int(int val, const struct multistate *m) 2372fmt_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);