[openssh-commits] [openssh] 01/07: upstream commit

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Apr 15 13:00:55 AEST 2016


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit dc7990be865450574c7940c9880567f5d2555b37
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Fri Apr 15 00:30:19 2016 +0000

    upstream commit
    
    Include directive for ssh_config(5); feedback & ok markus@
    
    Upstream-ID: ae3b76e2e343322b9f74acde6f1e1c5f027d5fff
---
 readconf.c   | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
 readconf.h   |   3 +-
 ssh.1        |   5 +--
 ssh_config.5 |  23 ++++++++++--
 4 files changed, 131 insertions(+), 16 deletions(-)

diff --git a/readconf.c b/readconf.c
index d63e596..b348c96 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.251 2016/04/06 06:42:17 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.252 2016/04/15 00:30:19 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -39,6 +39,11 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#ifdef USE_SYSTEM_GLOB
+# include <glob.h>
+#else
+# include "openbsd-compat/glob.h"
+#endif
 #ifdef HAVE_UTIL_H
 #include <util.h>
 #endif
@@ -125,11 +130,18 @@
 
 */
 
+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);
+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);
+
 /* Keyword tokens. */
 
 typedef enum {
 	oBadOption,
-	oHost, oMatch,
+	oHost, oMatch, oInclude,
 	oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
 	oGatewayPorts, oExitOnForwardFailure,
 	oPasswordAuthentication, oRSAAuthentication,
@@ -258,6 +270,7 @@ static struct {
 	{ "controlmaster", oControlMaster },
 	{ "controlpersist", oControlPersist },
 	{ "hashknownhosts", oHashKnownHosts },
+	{ "include", oInclude },
 	{ "tunnel", oTunnel },
 	{ "tunneldevice", oTunnelDevice },
 	{ "localcommand", oLocalCommand },
@@ -783,22 +796,32 @@ static const struct multistate multistate_canonicalizehostname[] = {
  * Processes a single option line as used in the configuration files. This
  * only sets those values that have not already been set.
  */
-#define WHITESPACE " \t\r\n"
 int
 process_config_line(Options *options, struct passwd *pw, const char *host,
     const char *original_host, char *line, const char *filename,
     int linenum, int *activep, int flags)
 {
+	return process_config_line_depth(options, pw, host, original_host,
+	    line, filename, linenum, activep, flags, 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)
+{
 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
 	char **cpptr, fwdarg[256];
 	u_int i, *uintptr, max_entries = 0;
-	int negated, opcode, *intptr, value, value2, cmdline = 0;
+	int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
 	LogLevel *log_level_ptr;
 	long long val64;
 	size_t len;
 	struct Forward fwd;
 	const struct multistate *multistate_ptr;
 	struct allowed_cname *cname;
+	glob_t gl;
 
 	if (activep == NULL) { /* We are processing a command line directive */
 		cmdline = 1;
@@ -1258,6 +1281,8 @@ parse_keytypes:
 		*activep = 0;
 		arg2 = NULL;
 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
+			if ((flags & SSHCONF_NEVERMATCH) != 0)
+				break;
 			negated = *arg == '!';
 			if (negated)
 				arg++;
@@ -1290,7 +1315,7 @@ parse_keytypes:
 		if (value < 0)
 			fatal("%.200s line %d: Bad Match condition", filename,
 			    linenum);
-		*activep = value;
+		*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
 		break;
 
 	case oEscapeChar:
@@ -1418,6 +1443,63 @@ parse_keytypes:
 		intptr = &options->visual_host_key;
 		goto parse_flag;
 
+	case oInclude:
+		if (cmdline)
+			fatal("Include directive not supported as a "
+			    "command-line option");
+		value = 0;
+		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
+			/*
+			 * Ensure all paths are anchored. User configuration
+			 * files may begin with '~/' but system configurations
+			 * must not. If the path is relative, then treat it
+			 * as living in ~/.ssh for user configurations or
+			 * /etc/ssh for system ones.
+			 */
+			if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
+				fatal("%.200s line %d: bad include path %s.",
+				    filename, linenum, arg);
+			if (*arg != '/' && *arg != '~') {
+				xasprintf(&arg2, "%s/%s",
+				    (flags & SSHCONF_USERCONF) ?
+				    "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
+			} else
+				arg2 = xstrdup(arg);
+			memset(&gl, 0, sizeof(gl));
+			r = glob(arg2, GLOB_TILDE, NULL, &gl);
+			if (r == GLOB_NOMATCH) {
+				debug("%.200s line %d: include %s matched no "
+				    "files",filename, linenum, arg2);
+				continue;
+			} else if (r != 0 || gl.gl_pathc < 0)
+				fatal("%.200s line %d: glob failed for %s.",
+				    filename, linenum, arg2);
+			free(arg2);
+			oactive = *activep;
+			for (i = 0; i < (u_int)gl.gl_pathc; i++) {
+				debug3("%.200s line %d: Including file %s "
+				    "depth %d%s", filename, linenum,
+				    gl.gl_pathv[i], depth,
+				    oactive ? "" : " (parse only)");
+				r = read_config_file_depth(gl.gl_pathv[i],
+				    pw, host, original_host, options,
+				    flags | SSHCONF_CHECKPERM |
+				    (oactive ? 0 : SSHCONF_NEVERMATCH),
+				    activep, depth + 1);
+				/*
+				 * don't let Match in includes clobber the
+				 * containing file's Match state.
+				 */
+				*activep = oactive;
+				if (r != 1)
+					value = -1;
+			}
+			globfree(&gl);
+		}
+		if (value != 0)
+			return value;
+		break;
+
 	case oIPQoS:
 		arg = strdelim(&s);
 		if ((value = parse_ipqos(arg)) == -1)
@@ -1576,22 +1658,35 @@ parse_keytypes:
 	return 0;
 }
 
-
 /*
  * Reads the config file and modifies the options accordingly.  Options
  * should already be initialized before this call.  This never returns if
  * there is an error.  If the file does not exist, this returns 0.
  */
-
 int
 read_config_file(const char *filename, struct passwd *pw, const char *host,
     const char *original_host, Options *options, int flags)
 {
+	int active = 1;
+
+	return read_config_file_depth(filename, pw, host, original_host,
+	    options, flags, &active, 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)
+{
 	FILE *f;
 	char line[1024];
-	int active, linenum;
+	int linenum;
 	int bad_options = 0;
 
+	if (depth < 0 || depth > READCONF_MAX_DEPTH)
+		fatal("Too many recursive configuration includes");
+
 	if ((f = fopen(filename, "r")) == NULL)
 		return 0;
 
@@ -1611,13 +1706,12 @@ read_config_file(const char *filename, struct passwd *pw, const char *host,
 	 * Mark that we are now processing the options.  This flag is turned
 	 * on/off by Host specifications.
 	 */
-	active = 1;
 	linenum = 0;
 	while (fgets(line, sizeof(line), f)) {
 		/* Update line number counter. */
 		linenum++;
-		if (process_config_line(options, pw, host, original_host,
-		    line, filename, linenum, &active, flags) != 0)
+		if (process_config_line_depth(options, pw, host, original_host,
+		    line, filename, linenum, activep, flags, depth) != 0)
 			bad_options++;
 	}
 	fclose(f);
diff --git a/readconf.h b/readconf.h
index c84d068..5f44510 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.113 2016/01/14 16:17:40 markus Exp $ */
+/* $OpenBSD: readconf.h,v 1.114 2016/04/15 00:30:19 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
@@ -179,6 +179,7 @@ typedef struct {
 #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_NEVERMATCH	8  /* Match/Host never matches; internal only */
 
 #define SSH_UPDATE_HOSTKEYS_NO	0
 #define SSH_UPDATE_HOSTKEYS_YES	1
diff --git a/ssh.1 b/ssh.1
index cc53343..85309ec 100644
--- a/ssh.1
+++ b/ssh.1
@@ -33,8 +33,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh.1,v 1.369 2016/02/17 07:38:19 jmc Exp $
-.Dd $Mdocdate: February 17 2016 $
+.\" $OpenBSD: ssh.1,v 1.370 2016/04/15 00:30:19 djm Exp $
+.Dd $Mdocdate: April 15 2016 $
 .Dt SSH 1
 .Os
 .Sh NAME
@@ -503,6 +503,7 @@ For full details of the options listed below, and their possible values, see
 .It HostName
 .It IdentityFile
 .It IdentitiesOnly
+.It Include
 .It IPQoS
 .It KbdInteractiveAuthentication
 .It KbdInteractiveDevices
diff --git a/ssh_config.5 b/ssh_config.5
index caf13a6..880f110 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,8 +33,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh_config.5,v 1.228 2016/02/20 23:01:46 sobrado Exp $
-.Dd $Mdocdate: February 20 2016 $
+.\" $OpenBSD: ssh_config.5,v 1.229 2016/04/15 00:30:19 djm Exp $
+.Dd $Mdocdate: April 15 2016 $
 .Dt SSH_CONFIG 5
 .Os
 .Sh NAME
@@ -1019,6 +1019,25 @@ It is recommended that
 .Cm IgnoreUnknown
 be listed early in the configuration file as it will not be applied
 to unknown options that appear before it.
+.It Cm Include
+Include the specified configuration file(s).
+Multiple path names may be specified and each pathname may contain
+.Xr glob 3
+wildcards and, for user configurations, shell-like
+.Dq ~
+references to user home directories.
+Files without absolute paths are assumed to be in
+.Pa ~/.ssh
+if included in a user configurations file or
+.Pa /etc/ssh
+if included from the system configuration file.
+.Cm Include
+directive may appear inside a
+.Cm Match
+or
+.Cm Host
+block
+to perform conditional inclusion.
 .It Cm IPQoS
 Specifies the IPv4 type-of-service or DSCP class for connections.
 Accepted values are

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list