Bugzilla – Attachment 2466 Details for
Bug 2267
Host matching uses modified hostname as well as original
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
attempt #2
canon2.diff (text/plain), 16.32 KB, created by
Damien Miller
on 2014-09-01 14:12:17 AEST
(
hide
)
Description:
attempt #2
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2014-09-01 14:12:17 AEST
Size:
16.32 KB
patch
obsolete
>Index: ssh_config.5 >=================================================================== >RCS file: /var/cvs/openssh/ssh_config.5,v >retrieving revision 1.191 >diff -u -p -r1.191 ssh_config.5 >--- ssh_config.5 18 Jul 2014 04:11:26 -0000 1.191 >+++ ssh_config.5 1 Sep 2014 04:08:16 -0000 >@@ -65,7 +65,10 @@ The configuration files contain sections > .Dq Host > specifications, and that section is only applied for hosts that > match one of the patterns given in the specification. >-The matched host name is the one given on the command line. >+The matched host name is usually the one given on the command line >+(see the >+.Cm RereadConfig >+option for exceptions.) > .Pp > Since the first obtained value for each parameter is used, more > host-specific declarations should be given near the beginning of the >@@ -109,10 +112,12 @@ A single > .Ql * > as a pattern can be used to provide global > defaults for all hosts. >-The host is the >+The host is usually the > .Ar hostname >-argument given on the command line (i.e. the name is not converted to >-a canonicalized host name before matching). >+argument given on the command line >+(see the >+.Cm RereadConfig >+option for exceptions.) > .Pp > A pattern entry may be negated by prefixing it with an exclamation mark > .Pq Sq !\& . >@@ -134,19 +139,39 @@ or > keyword) to be used only when the conditions following the > .Cm Match > keyword are satisfied. >-Match conditions are specified using one or more keyword/criteria pairs >+Match conditions are specified using one or more critera > or the single token > .Cm all >-which matches all criteria. >-The available keywords are: >+which always matches. >+The available criteria keywords are: >+.Cm canonical , > .Cm exec , > .Cm host , > .Cm originalhost , > .Cm user , > and > .Cm localuser . >+The >+.Cm all >+criteria must appear alone. >+Other criteria may be combined arbitrarily. >+All criteria but >+.Cm all >+and >+.Cm canonical >+require an argument. >+Criteria may be negated by prepending an exclamation mark >+.Pq Sq !\& . > .Pp > The >+.Cm canonical >+keywork matches only when the configuration file is being re-parsed >+after hostname canonicalization (see the >+.Cm CanonicalizeHostname >+option.) >+This may be useful to specify conditions that work with canonical host >+names only. >+The > .Cm exec > keyword executes the specified command under the user's shell. > If the command returns a zero exit status then the condition is considered true. >@@ -775,6 +800,12 @@ The default is the name given on the com > Numeric IP addresses are also permitted (both on the command line and in > .Cm HostName > specifications). >+.Pp >+If this option is enabled and results in the target hostname >+changing, then the configuration files are processed again using the new >+target name to pick up any new configuration in matching >+.Cm Host >+stanzas. > .It Cm IdentitiesOnly > Specifies that > .Xr ssh 1 >@@ -1204,6 +1235,27 @@ will only succeed if the server's > .Cm GatewayPorts > option is enabled (see > .Xr sshd_config 5 ) . >+.It Cm RereadConfig >+Controls whether >+.Xr ssh 1 >+re-reads its configuration files a second time. >+Re-reading the configuration files may allow >+.Cm Host >+and >+.Cm Match >+blocks to pick up changes to the target host name caused by >+hostname canonicalisation or >+.Cm HostName >+directives. >+The argument may be one of >+.Dq no >+to indicate that the configuration should never be re-read, >+.Dq yes >+to always re-read the configuration, or >+.Dq if-canon >+to only re-read the configuration if hostname canonicalisation is enabled. >+The default is >+.Dq if-canon . > .It Cm RequestTTY > Specifies whether to request a pseudo-tty for the session. > The argument may be one of: >Index: ssh.c >=================================================================== >RCS file: /var/cvs/openssh/ssh.c,v >retrieving revision 1.405 >diff -u -p -r1.405 ssh.c >--- ssh.c 18 Jul 2014 05:04:11 -0000 1.405 >+++ ssh.c 1 Sep 2014 04:08:17 -0000 >@@ -384,27 +384,29 @@ resolve_canonicalize(char **hostp, int p > * file if the user specifies a config file on the command line. > */ > static void >-process_config_files(struct passwd *pw) >+process_config_files(const char *host_arg, struct passwd *pw, int post_canon) > { > char buf[MAXPATHLEN]; > int r; > > if (config != NULL) { > if (strcasecmp(config, "none") != 0 && >- !read_config_file(config, pw, host, &options, >- SSHCONF_USERCONF)) >+ !read_config_file(config, pw, host, host_arg, &options, >+ SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) > fatal("Can't open user config file %.100s: " > "%.100s", config, strerror(errno)); > } else { > r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, > _PATH_SSH_USER_CONFFILE); > if (r > 0 && (size_t)r < sizeof(buf)) >- (void)read_config_file(buf, pw, host, &options, >- SSHCONF_CHECKPERM|SSHCONF_USERCONF); >+ (void)read_config_file(buf, pw, host, host_arg, >+ &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | >+ (post_canon ? SSHCONF_POSTCANON : 0)); > > /* Read systemwide configuration file after user config. */ >- (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host, >- &options, 0); >+ (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, >+ host, host_arg, &options, >+ post_canon ? SSHCONF_POSTCANON : 0); > } > } > >@@ -788,9 +790,9 @@ main(int ac, char **av) > break; > case 'o': > line = xstrdup(optarg); >- if (process_config_line(&options, pw, host ? host : "", >- line, "command-line", 0, NULL, SSHCONF_USERCONF) >- != 0) >+ if (process_config_line(&options, pw, >+ host ? host : "", host ? host : "", line, >+ "command-line", 0, NULL, SSHCONF_USERCONF) != 0) > exit(255); > free(line); > break; >@@ -899,7 +901,7 @@ main(int ac, char **av) > ); > > /* Parse the configuration files */ >- process_config_files(pw); >+ process_config_files(host_arg, pw, 0); > > /* Hostname canonicalisation needs a few options filled. */ > fill_default_options_for_canonicalization(&options); >@@ -944,13 +946,10 @@ main(int ac, char **av) > check_follow_cname(&host, cname); > } > >- /* >- * If the target hostname has changed as a result of canonicalisation >- * then re-parse the configuration files as new stanzas may match. >- */ >- if (strcasecmp(host_arg, host) != 0) { >- debug("Hostname has changed; re-reading configuration"); >- process_config_files(pw); >+ if (options.reread_config == 1 || (options.reread_config == 2 && >+ options.canonicalize_hostname != 0)) { >+ debug("Re-reading configuration"); >+ process_config_files(host_arg, pw, 1); > } > > /* Fill configuration defaults. */ >Index: readconf.c >=================================================================== >RCS file: /var/cvs/openssh/readconf.c,v >retrieving revision 1.203 >diff -u -p -r1.203 readconf.c >--- readconf.c 18 Jul 2014 04:11:26 -0000 1.203 >+++ readconf.c 1 Sep 2014 04:08:18 -0000 >@@ -150,7 +150,7 @@ typedef enum { > oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, > oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, > oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, >- oStreamLocalBindMask, oStreamLocalBindUnlink, >+ oStreamLocalBindMask, oStreamLocalBindUnlink, oRereadConfig, > oIgnoredUnknownOption, oDeprecated, oUnsupported > } OpCodes; > >@@ -266,6 +266,7 @@ static struct { > { "streamlocalbindmask", oStreamLocalBindMask }, > { "streamlocalbindunlink", oStreamLocalBindUnlink }, > { "ignoreunknown", oIgnoreUnknown }, >+ { "rereadconfig", oRereadConfig }, > > { NULL, oBadOption } > }; >@@ -476,11 +477,12 @@ execute_in_shell(const char *cmd) > */ > static int > match_cfg_line(Options *options, char **condition, struct passwd *pw, >- const char *host_arg, const char *filename, int linenum) >+ const char *host_arg, const char *original_host, int post_canon, >+ const char *filename, int linenum) > { >- char *arg, *attrib, *cmd, *cp = *condition, *host; >+ char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; > const char *ruser; >- int r, port, result = 1, attributes = 0; >+ int r, port, this_result, result = 1, attributes = 0, negate; > size_t len; > char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; > >@@ -497,21 +499,38 @@ match_cfg_line(Options *options, char ** > } else > host = xstrdup(host_arg); > >- debug3("checking match for '%s' host %s", cp, host); >- while ((attrib = strdelim(&cp)) && *attrib != '\0') { >+ debug2("checking match for '%s' host %s originally %s", >+ cp, host, original_host); >+ while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { >+ criteria = NULL; >+ this_result = 1; > attributes++; >+ negate = attrib[0] == '!'; >+ if (negate) >+ attrib++; >+ /* criteria "all" and "canonical" have no argument */ > if (strcasecmp(attrib, "all") == 0) { > if (attributes != 1 || > ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { >- error("'all' cannot be combined with other " >- "Match attributes"); >+ error("%.200s line %d: '%s' cannot be combined " >+ "with other Match attributes", >+ filename, linenum, oattrib); > result = -1; > goto out; > } > *condition = cp; >- result = 1; >+ result = negate ? 0 : 1; > goto out; >+ } else if (strcasecmp(attrib, "canonical") == 0) { >+ r = !!post_canon; /* force bitmask member to boolean */ >+ if (r == (negate ? 1 : 0)) >+ this_result = result = 0; >+ debug3("%.200s line %d: %smatched '%s'", >+ filename, linenum, >+ this_result ? "" : "not ", oattrib); >+ continue; > } >+ /* All other criteria require an argument */ > if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { > error("Missing Match criteria for %s", attrib); > result = -1; >@@ -519,31 +538,25 @@ match_cfg_line(Options *options, char ** > } > len = strlen(arg); > if (strcasecmp(attrib, "host") == 0) { >- if (match_hostname(host, arg, len) != 1) >- result = 0; >- else >- debug("%.200s line %d: matched 'Host %.100s' ", >- filename, linenum, host); >+ criteria = xstrdup(host); >+ r = match_hostname(host, arg, len) == 1; >+ if (r == (negate ? 1 : 0)) >+ this_result = result = 0; > } else if (strcasecmp(attrib, "originalhost") == 0) { >- if (match_hostname(host_arg, arg, len) != 1) >- result = 0; >- else >- debug("%.200s line %d: matched " >- "'OriginalHost %.100s' ", >- filename, linenum, host_arg); >+ criteria = xstrdup(original_host); >+ r = match_hostname(original_host, arg, len) == 1; >+ if (r == (negate ? 1 : 0)) >+ this_result = result = 0; > } else if (strcasecmp(attrib, "user") == 0) { >- if (match_pattern_list(ruser, arg, len, 0) != 1) >- result = 0; >- else >- debug("%.200s line %d: matched 'User %.100s' ", >- filename, linenum, ruser); >+ criteria = xstrdup(ruser); >+ r = match_pattern_list(ruser, arg, len, 0) == 1; >+ if (r == (negate ? 1 : 0)) >+ this_result = result = 0; > } else if (strcasecmp(attrib, "localuser") == 0) { >- if (match_pattern_list(pw->pw_name, arg, len, 0) != 1) >- result = 0; >- else >- debug("%.200s line %d: matched " >- "'LocalUser %.100s' ", >- filename, linenum, pw->pw_name); >+ criteria = xstrdup(pw->pw_name); >+ r = match_pattern_list(pw->pw_name, arg, len, 0) == 1; >+ if (r == (negate ? 1 : 0)) >+ this_result = result = 0; > } else if (strcasecmp(attrib, "exec") == 0) { > if (gethostname(thishost, sizeof(thishost)) == -1) > fatal("gethostname: %s", strerror(errno)); >@@ -556,45 +569,46 @@ match_cfg_line(Options *options, char ** > "d", pw->pw_dir, > "h", host, > "l", thishost, >- "n", host_arg, >+ "n", original_host, > "p", portstr, > "r", ruser, > "u", pw->pw_name, > (char *)NULL); > if (result != 1) { > /* skip execution if prior predicate failed */ >- debug("%.200s line %d: skipped exec \"%.100s\"", >- filename, linenum, cmd); >- } else { >- r = execute_in_shell(cmd); >- if (r == -1) { >- fatal("%.200s line %d: match exec " >- "'%.100s' error", filename, >- linenum, cmd); >- } else if (r == 0) { >- debug("%.200s line %d: matched " >- "'exec \"%.100s\"'", filename, >- linenum, cmd); >- } else { >- debug("%.200s line %d: no match " >- "'exec \"%.100s\"'", filename, >- linenum, cmd); >- result = 0; >- } >+ debug3("%.200s line %d: skipped exec " >+ "\"%.100s\"", filename, linenum, cmd); >+ free(cmd); >+ continue; > } >+ r = execute_in_shell(cmd); >+ if (r == -1) { >+ fatal("%.200s line %d: match exec " >+ "'%.100s' error", filename, >+ linenum, cmd); >+ } >+ criteria = xstrdup(cmd); > free(cmd); >+ /* Force exit status to boolean */ >+ r = r == 0; >+ if (r == (negate ? 1 : 0)) >+ this_result = result = 0; > } else { > error("Unsupported Match attribute %s", attrib); > result = -1; > goto out; > } >+ debug3("%.200s line %d: %smatched '%s \"%.100s\"' ", >+ filename, linenum, this_result ? "": "not ", >+ oattrib, criteria); >+ free(criteria); > } > if (attributes == 0) { > error("One or more attributes required for Match"); > result = -1; > goto out; > } >- debug3("match %sfound", result ? "" : "not "); >+ debug2("match %sfound", result ? "" : "not "); > *condition = cp; > out: > free(host); >@@ -711,6 +725,14 @@ static const struct multistate multistat > { "always", SSH_CANONICALISE_ALWAYS }, > { NULL, -1 } > }; >+static const struct multistate multistate_reread_config[] = { >+ { "true", SSH_REREAD_YES }, >+ { "false", SSH_REREAD_NO }, >+ { "yes", SSH_REREAD_YES }, >+ { "no", SSH_REREAD_NO }, >+ { "if-canon", SSH_REREAD_CANON }, >+ { NULL, -1 } >+}; > > /* > * Processes a single option line as used in the configuration files. This >@@ -719,7 +741,8 @@ static const struct multistate multistat > #define WHITESPACE " \t\r\n" > int > process_config_line(Options *options, struct passwd *pw, const char *host, >- char *line, const char *filename, int linenum, int *activep, int userconfig) >+ const char *original_host, char *line, const char *filename, >+ int linenum, int *activep, int flags) > { > char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; > char **cpptr, fwdarg[256]; >@@ -947,7 +970,8 @@ parse_time: > if (*intptr >= SSH_MAX_IDENTITY_FILES) > fatal("%.200s line %d: Too many identity files specified (max %d).", > filename, linenum, SSH_MAX_IDENTITY_FILES); >- add_identity_file(options, NULL, arg, userconfig); >+ add_identity_file(options, NULL, >+ arg, flags & SSHCONF_USERCONF); > } > break; > >@@ -1195,8 +1219,8 @@ parse_int: > if (cmdline) > fatal("Host directive not supported as a command-line " > "option"); >- value = match_cfg_line(options, &s, pw, host, >- filename, linenum); >+ value = match_cfg_line(options, &s, pw, host, original_host, >+ flags & SSHCONF_POSTCANON, filename, linenum); > if (value < 0) > fatal("%.200s line %d: Bad Match condition", filename, > linenum); >@@ -1433,6 +1457,11 @@ parse_int: > intptr = &options->fwd_opts.streamlocal_bind_unlink; > goto parse_flag; > >+ case oRereadConfig: >+ intptr = &options->reread_config; >+ multistate_ptr = multistate_reread_config; >+ goto parse_multistate; >+ > case oDeprecated: > debug("%s line %d: Deprecated option \"%s\"", > filename, linenum, keyword); >@@ -1444,7 +1473,7 @@ parse_int: > return 0; > > default: >- fatal("process_config_line: Unimplemented opcode %d", opcode); >+ fatal("%s: Unimplemented opcode %d", __func__, opcode); > } > > /* Check that there is no garbage at end of line. */ >@@ -1464,7 +1493,7 @@ parse_int: > > int > read_config_file(const char *filename, struct passwd *pw, const char *host, >- Options *options, int flags) >+ const char *original_host, Options *options, int flags) > { > FILE *f; > char line[1024]; >@@ -1495,8 +1524,8 @@ read_config_file(const char *filename, s > while (fgets(line, sizeof(line), f)) { > /* Update line number counter. */ > linenum++; >- if (process_config_line(options, pw, host, line, filename, >- linenum, &active, flags & SSHCONF_USERCONF) != 0) >+ if (process_config_line(options, pw, host, original_host, >+ line, filename, linenum, &active, flags) != 0) > bad_options++; > } > fclose(f); >@@ -1609,6 +1638,7 @@ initialize_options(Options * options) > options->canonicalize_max_dots = -1; > options->canonicalize_fallback_local = -1; > options->canonicalize_hostname = -1; >+ options->reread_config = -1; > } > > /* >@@ -1786,6 +1816,8 @@ fill_default_options(Options * options) > options->canonicalize_fallback_local = 1; > if (options->canonicalize_hostname == -1) > options->canonicalize_hostname = SSH_CANONICALISE_NO; >+ if (options->reread_config == -1) >+ options->reread_config = SSH_REREAD_CANON; > #define CLEAR_ON_NONE(v) \ > do { \ > if (option_clear_or_none(v)) { \
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2267
:
2465
|
2466
|
2467
|
2469
|
2470