File openssh-7.9p1-match-final--from-fedora-31-gsi-openssh-package-modified-SLE_15_SP1.patch of Package gsi-openssh
diff -Nur openssh-7.9p1.orig/readconf.c openssh-7.9p1/readconf.c
--- openssh-7.9p1.orig/readconf.c 2019-12-10 17:07:03.023776117 +0100
+++ openssh-7.9p1/readconf.c 2019-12-10 17:08:04.368152304 +0100
@@ -135,10 +135,11 @@
static int read_config_file_depth(const char *filename, struct passwd *pw,
const char *host, const char *original_host, Options *options,
- int flags, int *activep, int depth);
+ int flags, int *activep, int *want_final_pass, int depth);
static int process_config_line_depth(Options *options, struct passwd *pw,
const char *host, const char *original_host, char *line,
- const char *filename, int linenum, int *activep, int flags, int depth);
+ const char *filename, int linenum, int *activep, int flags,
+ int *want_final_pass, int depth);
/* Keyword tokens. */
@@ -553,8 +554,8 @@
*/
static int
match_cfg_line(Options *options, char **condition, struct passwd *pw,
- const char *host_arg, const char *original_host, int post_canon,
- const char *filename, int linenum)
+ const char *host_arg, const char *original_host, int final_pass,
+ int *want_final_pass, const char *filename, int linenum)
{
char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
const char *ruser;
@@ -568,7 +569,7 @@
*/
port = options->port <= 0 ? default_ssh_port() : options->port;
ruser = options->user == NULL ? pw->pw_name : options->user;
- if (post_canon) {
+ if (final_pass) {
host = xstrdup(options->hostname);
} else if (options->hostname != NULL) {
/* NB. Please keep in sync with ssh.c:main() */
@@ -600,8 +601,16 @@
goto out;
}
attributes++;
- if (strcasecmp(attrib, "canonical") == 0) {
- r = !!post_canon; /* force bitmask member to boolean */
+ if (strcasecmp(attrib, "canonical") == 0 ||
+ strcasecmp(attrib, "final") == 0) {
+ /*
+ * If the config requests "Match final" then remember
+ * this so we can perform a second pass later.
+ */
+ if (strcasecmp(attrib, "final") == 0 &&
+ want_final_pass != NULL)
+ *want_final_pass = 1;
+ r = !!final_pass; /* force bitmask member to boolean */
if (r == (negate ? 1 : 0))
this_result = result = 0;
debug3("%.200s line %d: %smatched '%s'",
@@ -838,14 +847,14 @@
int linenum, int *activep, int flags)
{
return process_config_line_depth(options, pw, host, original_host,
- line, filename, linenum, activep, flags, 0);
+ line, filename, linenum, activep, flags, NULL, 0);
}
#define WHITESPACE " \t\r\n"
static int
process_config_line_depth(Options *options, struct passwd *pw, const char *host,
const char *original_host, char *line, const char *filename,
- int linenum, int *activep, int flags, int depth)
+ int linenum, int *activep, int flags, int *want_final_pass, int depth)
{
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
char **cpptr, fwdarg[256];
@@ -1373,7 +1382,8 @@
fatal("Host directive not supported as a command-line "
"option");
value = match_cfg_line(options, &s, pw, host, original_host,
- flags & SSHCONF_POSTCANON, filename, linenum);
+ flags & SSHCONF_FINAL, want_final_pass,
+ filename, linenum);
if (value < 0)
fatal("%.200s line %d: Bad Match condition", filename,
linenum);
@@ -1582,7 +1592,7 @@
pw, host, original_host, options,
flags | SSHCONF_CHECKPERM |
(oactive ? 0 : SSHCONF_NEVERMATCH),
- activep, depth + 1);
+ activep, want_final_pass, depth + 1);
if (r != 1 && errno != ENOENT) {
fatal("Can't open user config file "
"%.100s: %.100s", gl.gl_pathv[i],
@@ -1785,19 +1795,20 @@
*/
int
read_config_file(const char *filename, struct passwd *pw, const char *host,
- const char *original_host, Options *options, int flags)
+ const char *original_host, Options *options, int flags,
+ int *want_final_pass)
{
int active = 1;
return read_config_file_depth(filename, pw, host, original_host,
- options, flags, &active, 0);
+ options, flags, &active, want_final_pass, 0);
}
#define READCONF_MAX_DEPTH 16
static int
read_config_file_depth(const char *filename, struct passwd *pw,
const char *host, const char *original_host, Options *options,
- int flags, int *activep, int depth)
+ int flags, int *activep, int *want_final_pass, int depth)
{
FILE *f;
char *line = NULL;
@@ -1832,7 +1843,8 @@
/* Update line number counter. */
linenum++;
if (process_config_line_depth(options, pw, host, original_host,
- line, filename, linenum, activep, flags, depth) != 0)
+ line, filename, linenum, activep, flags, want_final_pass,
+ depth) != 0)
bad_options++;
}
free(line);
diff -Nur openssh-7.9p1.orig/readconf.h openssh-7.9p1/readconf.h
--- openssh-7.9p1.orig/readconf.h 2019-12-10 17:07:03.023776117 +0100
+++ openssh-7.9p1/readconf.h 2019-12-10 17:08:04.368152304 +0100
@@ -192,7 +192,7 @@
#define SSHCONF_CHECKPERM 1 /* check permissions on config file */
#define SSHCONF_USERCONF 2 /* user provided config file not system */
-#define SSHCONF_POSTCANON 4 /* After hostname canonicalisation */
+#define SSHCONF_FINAL 4 /* Final pass over config, after canon. */
#define SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */
#define SSH_UPDATE_HOSTKEYS_NO 0
@@ -211,7 +211,7 @@
int process_config_line(Options *, struct passwd *, const char *,
const char *, char *, const char *, int, int *, int);
int read_config_file(const char *, struct passwd *, const char *,
- const char *, Options *, int);
+ const char *, Options *, int, int *);
int parse_forward(struct Forward *, const char *, int, int);
int parse_jump(const char *, Options *, int);
int parse_ssh_uri(const char *, char **, char **, int *);
diff -Nur openssh-7.9p1.orig/ssh.c openssh-7.9p1/ssh.c
--- openssh-7.9p1.orig/ssh.c 2019-12-10 17:07:03.023776117 +0100
+++ openssh-7.9p1/ssh.c 2019-12-10 17:08:04.368152304 +0100
@@ -529,7 +529,8 @@
* file if the user specifies a config file on the command line.
*/
static void
-process_config_files(const char *host_name, struct passwd *pw, int post_canon)
+process_config_files(const char *host_name, struct passwd *pw, int final_pass,
+ int *want_final_pass)
{
char buf[PATH_MAX];
int r;
@@ -537,7 +538,8 @@
if (config != NULL) {
if (strcasecmp(config, "none") != 0 &&
!read_config_file(config, pw, host, host_name, &options,
- SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0)))
+ SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0),
+ want_final_pass))
fatal("Can't open user config file %.100s: "
"%.100s", config, strerror(errno));
} else {
@@ -578,12 +580,12 @@
if (r > 0 && (size_t)r < sizeof(buf))
(void)read_config_file(buf, pw, host, host_name,
&options, SSHCONF_CHECKPERM | SSHCONF_USERCONF |
- (post_canon ? SSHCONF_POSTCANON : 0));
+ (final_pass ? SSHCONF_FINAL : 0), want_final_pass);
/* Read systemwide configuration file after user config. */
(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
host, host_name, &options,
- post_canon ? SSHCONF_POSTCANON : 0);
+ final_pass ? SSHCONF_FINAL : 0, want_final_pass);
}
}
@@ -615,7 +617,7 @@
{
struct ssh *ssh = NULL;
int i, r, opt, exit_status, use_syslog, direct, timeout_ms;
- int was_addr, config_test = 0, opt_terminated = 0;
+ int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0;
char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile;
char cname[NI_MAXHOST];
struct stat st;
@@ -1130,7 +1132,9 @@
);
/* Parse the configuration files */
- process_config_files(host_arg, pw, 0);
+ process_config_files(host_arg, pw, 0, &want_final_pass);
+ if (want_final_pass)
+ debug("configuration requests final Match pass");
/* Hostname canonicalisation needs a few options filled. */
fill_default_options_for_canonicalization(&options);
@@ -1187,12 +1191,17 @@
* If canonicalisation is enabled then re-parse the configuration
* files as new stanzas may match.
*/
- if (options.canonicalize_hostname != 0) {
- debug("Re-reading configuration after hostname "
- "canonicalisation");
+ if (options.canonicalize_hostname != 0 && !want_final_pass) {
+ debug("hostname canonicalisation enabled, "
+ "will re-parse configuration");
+ want_final_pass = 1;
+ }
+
+ if (want_final_pass) {
+ debug("re-parsing configuration");
free(options.hostname);
options.hostname = xstrdup(host);
- process_config_files(host_arg, pw, 1);
+ process_config_files(host_arg, pw, 1, NULL);
/*
* Address resolution happens early with canonicalisation
* enabled and the port number may have changed since, so
diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5
--- openssh-7.9p1.orig/ssh_config.5 2019-12-10 17:07:03.023776117 +0100
+++ openssh-7.9p1/ssh_config.5 2019-12-10 17:08:04.368152304 +0100
@@ -145,6 +145,7 @@
which always matches.
The available criteria keywords are:
.Cm canonical ,
+.Cm final ,
.Cm exec ,
.Cm host ,
.Cm originalhost ,
@@ -154,12 +155,15 @@
The
.Cm all
criteria must appear alone or immediately after
-.Cm canonical .
+.Cm canonical
+or
+.Cm final .
Other criteria may be combined arbitrarily.
All criteria but
.Cm all
-and
.Cm canonical
+and
+.Cm final
require an argument.
Criteria may be negated by prepending an exclamation mark
.Pq Sq !\& .
@@ -172,6 +176,20 @@
option.)
This may be useful to specify conditions that work with canonical host
names only.
+.Pp
+The
+.Cm final
+keyword requests that the configuration be re-parsed (regardless of whether
+.Cm CanonicalizeHostname
+is enabled), and matches only during this final pass.
+If
+.Cm CanonicalizeHostname
+is enabled, then
+.Cm canonical
+and
+.Cm final
+match during the same pass.
+.Pp
The
.Cm exec
keyword executes the specified command under the user's shell.
diff -Nur openssh-7.9p1.orig/ssh-keysign.c openssh-7.9p1/ssh-keysign.c
--- openssh-7.9p1.orig/ssh-keysign.c 2018-10-17 02:01:20.000000000 +0200
+++ openssh-7.9p1/ssh-keysign.c 2019-12-10 17:08:04.368152304 +0100
@@ -210,7 +210,8 @@
/* verify that ssh-keysign is enabled by the admin */
initialize_options(&options);
- (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", &options, 0);
+ (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "",
+ &options, 0, NULL);
fill_default_options(&options);
if (options.enable_ssh_keysign != 1)
fatal("ssh-keysign not enabled in %s",