summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'readconf.c')
-rw-r--r--readconf.c113
1 files changed, 112 insertions, 1 deletions
diff --git a/readconf.c b/readconf.c
index 9340effd0..de8eb7cd3 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.207 2013/10/14 23:28:23 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.208 2013/10/16 02:31:45 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
@@ -144,6 +144,8 @@ typedef enum {
144 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 144 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
145 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, 145 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
146 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, 146 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
147 oCanonicalDomains, oCanonicaliseHostname, oCanonicaliseMaxDots,
148 oCanonicaliseFallbackLocal, oCanonicalisePermittedCNAMEs,
147 oIgnoredUnknownOption, oDeprecated, oUnsupported 149 oIgnoredUnknownOption, oDeprecated, oUnsupported
148} OpCodes; 150} OpCodes;
149 151
@@ -257,6 +259,11 @@ static struct {
257 { "ipqos", oIPQoS }, 259 { "ipqos", oIPQoS },
258 { "requesttty", oRequestTTY }, 260 { "requesttty", oRequestTTY },
259 { "proxyusefdpass", oProxyUseFdpass }, 261 { "proxyusefdpass", oProxyUseFdpass },
262 { "canonicaldomains", oCanonicalDomains },
263 { "canonicalisefallbacklocal", oCanonicaliseFallbackLocal },
264 { "canonicalisehostname", oCanonicaliseHostname },
265 { "canonicalisemaxdots", oCanonicaliseMaxDots },
266 { "canonicalisepermittedcnames", oCanonicalisePermittedCNAMEs },
260 { "ignoreunknown", oIgnoreUnknown }, 267 { "ignoreunknown", oIgnoreUnknown },
261 268
262 { NULL, oBadOption } 269 { NULL, oBadOption }
@@ -535,6 +542,34 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
535 return result; 542 return result;
536} 543}
537 544
545/* Check and prepare a domain name: removes trailing '.' and lowercases */
546static void
547valid_domain(char *name, const char *filename, int linenum)
548{
549 size_t i, l = strlen(name);
550 u_char c, last = '\0';
551
552 if (l == 0)
553 fatal("%s line %d: empty hostname suffix", filename, linenum);
554 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
555 fatal("%s line %d: hostname suffix \"%.100s\" "
556 "starts with invalid character", filename, linenum, name);
557 for (i = 0; i < l; i++) {
558 c = tolower((u_char)name[i]);
559 name[i] = (char)c;
560 if (last == '.' && c == '.')
561 fatal("%s line %d: hostname suffix \"%.100s\" contains "
562 "consecutive separators", filename, linenum, name);
563 if (c != '.' && c != '-' && !isalnum(c) &&
564 c != '_') /* technically invalid, but common */
565 fatal("%s line %d: hostname suffix \"%.100s\" contains "
566 "invalid characters", filename, linenum, name);
567 last = c;
568 }
569 if (name[l - 1] == '.')
570 name[l - 1] = '\0';
571}
572
538/* 573/*
539 * Returns the number of the token pointed to by cp or oBadOption. 574 * Returns the number of the token pointed to by cp or oBadOption.
540 */ 575 */
@@ -609,6 +644,14 @@ static const struct multistate multistate_requesttty[] = {
609 { "auto", REQUEST_TTY_AUTO }, 644 { "auto", REQUEST_TTY_AUTO },
610 { NULL, -1 } 645 { NULL, -1 }
611}; 646};
647static const struct multistate multistate_canonicalisehostname[] = {
648 { "true", SSH_CANONICALISE_YES },
649 { "false", SSH_CANONICALISE_NO },
650 { "yes", SSH_CANONICALISE_YES },
651 { "no", SSH_CANONICALISE_NO },
652 { "always", SSH_CANONICALISE_ALWAYS },
653 { NULL, -1 }
654};
612 655
613/* 656/*
614 * Processes a single option line as used in the configuration files. This 657 * Processes a single option line as used in the configuration files. This
@@ -628,6 +671,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
628 size_t len; 671 size_t len;
629 Forward fwd; 672 Forward fwd;
630 const struct multistate *multistate_ptr; 673 const struct multistate *multistate_ptr;
674 struct allowed_cname *cname;
631 675
632 if (activep == NULL) { /* We are processing a command line directive */ 676 if (activep == NULL) { /* We are processing a command line directive */
633 cmdline = 1; 677 cmdline = 1;
@@ -1263,6 +1307,62 @@ parse_int:
1263 intptr = &options->proxy_use_fdpass; 1307 intptr = &options->proxy_use_fdpass;
1264 goto parse_flag; 1308 goto parse_flag;
1265 1309
1310 case oCanonicalDomains:
1311 value = options->num_canonical_domains != 0;
1312 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1313 valid_domain(arg, filename, linenum);
1314 if (!*activep || value)
1315 continue;
1316 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1317 fatal("%s line %d: too many hostname suffixes.",
1318 filename, linenum);
1319 options->canonical_domains[
1320 options->num_canonical_domains++] = xstrdup(arg);
1321 }
1322 break;
1323
1324 case oCanonicalisePermittedCNAMEs:
1325 value = options->num_permitted_cnames != 0;
1326 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1327 /* Either '*' for everything or 'list:list' */
1328 if (strcmp(arg, "*") == 0)
1329 arg2 = arg;
1330 else {
1331 lowercase(arg);
1332 if ((arg2 = strchr(arg, ':')) == NULL ||
1333 arg2[1] == '\0') {
1334 fatal("%s line %d: "
1335 "Invalid permitted CNAME \"%s\"",
1336 filename, linenum, arg);
1337 }
1338 *arg2 = '\0';
1339 arg2++;
1340 }
1341 if (!*activep || value)
1342 continue;
1343 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1344 fatal("%s line %d: too many permitted CNAMEs.",
1345 filename, linenum);
1346 cname = options->permitted_cnames +
1347 options->num_permitted_cnames++;
1348 cname->source_list = xstrdup(arg);
1349 cname->target_list = xstrdup(arg2);
1350 }
1351 break;
1352
1353 case oCanonicaliseHostname:
1354 intptr = &options->canonicalise_hostname;
1355 multistate_ptr = multistate_canonicalisehostname;
1356 goto parse_multistate;
1357
1358 case oCanonicaliseMaxDots:
1359 intptr = &options->canonicalise_max_dots;
1360 goto parse_int;
1361
1362 case oCanonicaliseFallbackLocal:
1363 intptr = &options->canonicalise_fallback_local;
1364 goto parse_flag;
1365
1266 case oDeprecated: 1366 case oDeprecated:
1267 debug("%s line %d: Deprecated option \"%s\"", 1367 debug("%s line %d: Deprecated option \"%s\"",
1268 filename, linenum, keyword); 1368 filename, linenum, keyword);
@@ -1426,6 +1526,11 @@ initialize_options(Options * options)
1426 options->request_tty = -1; 1526 options->request_tty = -1;
1427 options->proxy_use_fdpass = -1; 1527 options->proxy_use_fdpass = -1;
1428 options->ignored_unknown = NULL; 1528 options->ignored_unknown = NULL;
1529 options->num_canonical_domains = 0;
1530 options->num_permitted_cnames = 0;
1531 options->canonicalise_max_dots = -1;
1532 options->canonicalise_fallback_local = -1;
1533 options->canonicalise_hostname = -1;
1429} 1534}
1430 1535
1431/* 1536/*
@@ -1579,6 +1684,12 @@ fill_default_options(Options * options)
1579 options->request_tty = REQUEST_TTY_AUTO; 1684 options->request_tty = REQUEST_TTY_AUTO;
1580 if (options->proxy_use_fdpass == -1) 1685 if (options->proxy_use_fdpass == -1)
1581 options->proxy_use_fdpass = 0; 1686 options->proxy_use_fdpass = 0;
1687 if (options->canonicalise_max_dots == -1)
1688 options->canonicalise_max_dots = 1;
1689 if (options->canonicalise_fallback_local == -1)
1690 options->canonicalise_fallback_local = 1;
1691 if (options->canonicalise_hostname == -1)
1692 options->canonicalise_hostname = SSH_CANONICALISE_NO;
1582#define CLEAR_ON_NONE(v) \ 1693#define CLEAR_ON_NONE(v) \
1583 do { \ 1694 do { \
1584 if (v != NULL && strcasecmp(v, "none") == 0) { \ 1695 if (v != NULL && strcasecmp(v, "none") == 0) { \