Security suggestion concering SSH and port forwarding.

Tony Finch dot at dotat.at
Mon Jan 19 21:36:43 EST 2004


Krister Bergman <bell at milliways.st> wrote:
>
>I recently stumbled upon the scponly shell which in it's chroot:ed form is
>an ideal solution when you want to share some files with people you trust
>more or less.
>
>The problem is, if you use the scponlyc as shell, port forwarding is still
>allowed. This can of course be dissallowed in sshd_config, but not only
>for certian users and/or groups.

The patch below includes a little bit of infrastructure for bringing
together a lot of sshd's internal authorization decisions, for features
like port forwarding, agent forwarding, X11 forwarding, environment
setting, running commands, etc. etc. which at the moment aren't consistent
across different kinds of authentication mechanisms.

It also includes some code for restricting which ports can be forwarded,
to prevent exactly the kind of probing you want to prevent. Unfortunately
we can't just turn off TCP forwarding, and we can't require the use of
key-based authentication, both for user support reasons.

Unfortunately the infrastructure part is not well fleshed out, so it
only provides a limited degree of control over what different users
can and cannot do.

Tony.
-- 
f.a.n.finch  <dot at dotat.at>  http://dotat.at/
MULL OF KINTYRE TO ARDNAMURCHAN POINT: WEST 7 TO GALE 8 EASING 6 OR 7 LATER.
RAIN. MODERATE GENERALLY, BUT OCCASIONALLY POOR. ROUGH OR VERY ROUGH.


--- auth-options.c	28 Jan 2003 18:06:50 -0000	1.1.1.2
+++ auth-options.c	29 Jan 2003 20:39:19 -0000	1.7
@@ -133,7 +135,7 @@
 			goto next_option;
 		}
 		cp = "environment=\"";
-		if (options.permit_user_env &&
+		if (!auth_restricted(RESTRICT_ENV, pw) &&
 		    strncasecmp(opts, cp, strlen(cp)) == 0) {
 			char *s;
 			struct envstring *new_envstring;
@@ -217,8 +219,6 @@
 		}
 		cp = "permitopen=\"";
 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
-			char host[256], sport[6];
-			u_short port;
 			char *patterns = xmalloc(strlen(opts) + 1);
 
 			opts += strlen(cp);
@@ -243,8 +243,7 @@
 			}
 			patterns[i] = 0;
 			opts++;
-			if (sscanf(patterns, "%255[^:]:%5[0-9]", host, sport) != 2 &&
-			    sscanf(patterns, "%255[^/]/%5[0-9]", host, sport) != 2) {
+			if (channel_add_permitted_opens(patterns) < 0) {
 				debug("%.100s, line %lu: Bad permitopen specification "
 				    "<%.100s>", file, linenum, patterns);
 				auth_debug_add("%.100s, line %lu: "
@@ -252,16 +251,6 @@
 				xfree(patterns);
 				goto bad_option;
 			}
-			if ((port = a2port(sport)) == 0) {
-				debug("%.100s, line %lu: Bad permitopen port <%.100s>",
-				    file, linenum, sport);
-				auth_debug_add("%.100s, line %lu: "
-				    "Bad permitopen port", file, linenum);
-				xfree(patterns);
-				goto bad_option;
-			}
-			if (options.allow_tcp_forwarding)
-				channel_add_permitted_opens(host, port);
 			xfree(patterns);
 			goto next_option;
 		}
--- auth-pam.c	28 Jan 2003 18:06:51 -0000	1.1.1.2
+++ auth-pam.c	29 Jan 2003 20:39:19 -0000	1.2
@@ -358,7 +360,7 @@
 		no_port_forwarding_flag &= ~2;
 		no_agent_forwarding_flag &= ~2;
 		no_x11_forwarding_flag &= ~2;
-		if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
+		if (!auth_restricted(RESTRICT_TCP, auth_get_user()))
 			channel_permit_all_opens();
 #endif
 	}
--- auth.c	28 Jan 2003 18:06:51 -0000	1.1.1.2
+++ auth.c	29 Jan 2003 21:26:11 -0000	1.4
@@ -291,6 +293,31 @@
 	return 0;
 }
 
+/*
+ * Is the user subject to this restriction?
+ */
+int
+auth_restricted(int restriction, struct passwd *pw)
+{
+	debug2("user shell is %s", pw->pw_shell);
+	if ((options.restrictions & restriction) &&
+	    options.restricted_shell != NULL &&
+	    strcmp(options.restricted_shell, pw->pw_shell) == 0) {
+		debug("Restricted shell (%d)", restriction);
+		return 1;
+	} else if ((restriction & RESTRICT_AGENT) && no_agent_forwarding_flag)
+		return 1;
+	else if ((restriction & RESTRICT_ENV) && !options.permit_user_env)
+		return 1;
+	else if ((restriction & RESTRICT_TCP) &&
+	    (!options.allow_tcp_forwarding || no_port_forwarding_flag))
+		return 1;
+	else if ((restriction & RESTRICT_X11) &&
+	    (!options.x11_forwarding || no_x11_forwarding_flag))
+		return 1;
+	else
+		return 0;
+}
 
 /*
  * Given a template and a passwd structure, build a filename
--- auth.h	28 Jan 2003 18:06:51 -0000	1.1.1.2
+++ auth.h	29 Jan 2003 20:39:19 -0000	1.3
@@ -142,6 +143,7 @@
 void	auth_log(Authctxt *, int, char *, char *);
 void	userauth_finish(Authctxt *, int, char *);
 int	auth_root_allowed(char *);
+int	auth_restricted(int, struct passwd *);
 
 char	*auth2_read_banner(void);
 
--- channels.c	28 Jan 2003 18:06:51 -0000	1.1.1.2
+++ channels.c	24 Mar 2003 19:39:58 -0000	1.5
@@ -96,6 +98,10 @@
 
 /* Number of permitted host/port pairs in the array. */
 static int num_permitted_opens = 0;
+
+/* Don't allow any more to be added. */
+static int fix_permitted_opens = 0;
+
 /*
  * If this is true, all opens are permitted.  This is the case on the server
  * on which we have to trust the client anyway, and the user could do
@@ -1972,7 +1978,7 @@
 }
 
 void
-channel_input_port_open(int type, u_int32_t seq, void *ctxt)
+channel_input_port_open(int type, u_int32_t seq, void *ctxt, int loud)
 {
 	Channel *c = NULL;
 	u_short host_port;
@@ -1991,6 +1997,9 @@
 	packet_check_eom();
 	sock = channel_connect_to(host, host_port);
 	if (sock != -1) {
+		if (loud)
+			log("TCP forwarding connection to %s port %d",
+			    host, host_port);
 		c = channel_new("connected socket",
 		    SSH_CHANNEL_CONNECTING, sock, sock, -1, 0, 0, 0,
 		    originator_string, 1);
@@ -2004,6 +2013,18 @@
 	xfree(host);
 }
 
+void
+channel_input_port_open_quiet(int type, u_int32_t seq, void *ctxt)
+{
+	channel_input_port_open(type, seq, ctxt, 0);
+}
+
+void
+channel_input_port_open_loud(int type, u_int32_t seq, void *ctxt)
+{
+	channel_input_port_open(type, seq, ctxt, 1);
+}
+
 
 /* -- tcp forwarding */
 
@@ -2209,6 +2230,8 @@
 				  port);
 #endif
 	/* Initiate forwarding */
+	log("TCP forwarding listening on port %d %s", port,
+	    gateway_ports ? "open" : "private");
 	channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports);
 
 	/* Free the argument string. */
@@ -2227,10 +2250,31 @@
 		all_opens_permitted = 1;
 }
 
+/*
+ * If the server-wide configuration specifies some permitted_opens
+ * then don't allow users to add to them.
+ */
 void
-channel_add_permitted_opens(char *host, int port)
+channel_fix_permitted_opens(void)
 {
-	if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
+	if (num_permitted_opens != 0)
+		fix_permitted_opens = 1;
+}
+
+int
+channel_add_permitted_opens(char *hostport)
+{
+	char host[256], sport[6];
+	u_short port;
+
+	if (sscanf(hostport, "%255[^:]:%5[0-9]", host, sport) != 2 &&
+	    sscanf(hostport, "%255[^/]/%5[0-9]", host, sport) != 2)
+		return -1;
+	if ((port = a2port(sport)) == 0)
+		return -1;
+
+	if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION ||
+	    fix_permitted_opens)
 		fatal("channel_request_remote_forwarding: too many forwards");
 	debug("allow port forwarding to host %s port %d", host, port);
 
@@ -2239,6 +2283,7 @@
 	num_permitted_opens++;
 
 	all_opens_permitted = 0;
+	return 0;
 }
 
 void
@@ -2246,6 +2291,8 @@
 {
 	int i;
 
+	if (fix_permitted_opens)
+		return;
 	for (i = 0; i < num_permitted_opens; i++)
 		xfree(permitted_opens[i].host_to_connect);
 	num_permitted_opens = 0;
@@ -2448,6 +2495,7 @@
 		    0, xstrdup("X11 inet listener"), 1);
 		nc->single_connection = single_connection;
 	}
+	log("X11 forwarding listening on port %d", 6000+display_number);
 
 	/* Return the display number for the DISPLAY environment variable. */
 	*display_numberp = display_number;
--- channels.h	28 Jan 2003 18:06:51 -0000	1.1.1.2
+++ channels.h	28 Jan 2003 19:06:35 -0000	1.4
@@ -176,7 +177,9 @@
 void	 channel_input_oclose(int, u_int32_t, void *);
 void	 channel_input_open_confirmation(int, u_int32_t, void *);
 void	 channel_input_open_failure(int, u_int32_t, void *);
-void	 channel_input_port_open(int, u_int32_t, void *);
+void	 channel_input_port_open(int, u_int32_t, void *, int);
+void	 channel_input_port_open_loud(int, u_int32_t, void *);
+void	 channel_input_port_open_quiet(int, u_int32_t, void *);
 void	 channel_input_window_adjust(int, u_int32_t, void *);
 
 /* file descriptor handling (read/write) */
@@ -194,7 +197,8 @@
 /* tcp forwarding */
 void	 channel_set_af(int af);
 void     channel_permit_all_opens(void);
-void	 channel_add_permitted_opens(char *, int);
+void     channel_fix_permitted_opens(void);
+int	 channel_add_permitted_opens(char *);
 void	 channel_clear_permitted_opens(void);
 void     channel_input_port_forward_request(int, int);
 int	 channel_connect_to(const char *, u_short);
--- clientloop.c	28 Jan 2003 18:06:51 -0000	1.1.1.2
+++ clientloop.c	28 Jan 2003 19:06:35 -0000	1.3
@@ -1342,7 +1344,7 @@
 	dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
 	dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
 	dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
-	dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
+	dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open_quiet);
 	dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status);
 	dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data);
 	dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);
--- readconf.c	28 Jan 2003 18:06:52 -0000	1.1.1.2
+++ readconf.c	24 Mar 2003 16:03:01 -0000	1.2
@@ -114,6 +116,7 @@
 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
+	oVersionAddendum,
 	oDeprecated
 } OpCodes;
 
@@ -186,6 +189,7 @@
 	{ "smartcarddevice", oSmartcardDevice },
 	{ "clearallforwardings", oClearAllForwardings },
 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
+	{ "versionaddendum", oVersionAddendum },
 	{ NULL, oBadOption }
 };
 
@@ -667,6 +671,13 @@
 		}
 		if (*activep && *intptr == -1)
 			*intptr = value;
+		break;
+
+	case oVersionAddendum:
+		ssh_version_set_addendum(strtok(s, "\n"));
+		do {
+			arg = strdelim(&s);
+		} while (arg != NULL && *arg != '\0');
 		break;
 
 	case oDeprecated:
--- servconf.c	28 Jan 2003 18:06:52 -0000	1.1.1.2
+++ servconf.c	24 Mar 2003 16:03:01 -0000	1.9
@@ -39,6 +41,7 @@
 #include "cipher.h"
 #include "kex.h"
 #include "mac.h"
+#include "channels.h"
 
 static void add_listen_addr(ServerOptions *, char *, u_short);
 static void add_one_listen_addr(ServerOptions *, char *, u_short);
@@ -102,6 +105,9 @@
 	options->challenge_response_authentication = -1;
 	options->permit_empty_passwd = -1;
 	options->permit_user_env = -1;
+	options->permit_tcp_listen = -1;
+	options->restricted_shell = NULL;
+	options->restrictions = -1;
 	options->use_login = -1;
 	options->compression = -1;
 	options->allow_tcp_forwarding = -1;
@@ -226,6 +232,10 @@
 		options->permit_empty_passwd = 0;
 	if (options->permit_user_env == -1)
 		options->permit_user_env = 0;
+	if (options->permit_tcp_listen == -1)
+		options->permit_tcp_listen = 1;
+	if (options->restrictions == -1)
+		options->restrictions = 0;
 	if (options->use_login == -1)
 		options->use_login = 0;
 	if (options->compression == -1)
@@ -234,6 +244,7 @@
 		options->allow_tcp_forwarding = 1;
 	if (options->gateway_ports == -1)
 		options->gateway_ports = 0;
+	channel_fix_permitted_opens();
 	if (options->max_startups == -1)
 		options->max_startups = 10;
 	if (options->max_startups_rate == -1)
@@ -294,6 +305,7 @@
 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
 	sStrictModes, sEmptyPasswd, sKeepAlives,
+	sPermitTcpConnect, sPermitTcpListen, sRestrictedShell,
 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
@@ -301,7 +313,7 @@
 	sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
-	sUsePrivilegeSeparation,
+	sUsePrivilegeSeparation, sVersionAddendum,
 	sDeprecated
 } ServerOpCodes;
 
@@ -355,6 +367,7 @@
 	{ "x11displayoffset", sX11DisplayOffset },
 	{ "x11uselocalhost", sX11UseLocalhost },
 	{ "xauthlocation", sXAuthLocation },
+	{ "restrictedshell", sRestrictedShell },
 	{ "strictmodes", sStrictModes },
 	{ "permitemptypasswords", sEmptyPasswd },
 	{ "permituserenvironment", sPermitUserEnvironment },
@@ -362,6 +375,8 @@
 	{ "compression", sCompression },
 	{ "keepalive", sKeepAlives },
 	{ "allowtcpforwarding", sAllowTcpForwarding },
+	{ "permittcpconnect", sPermitTcpConnect },
+	{ "permittcplisten", sPermitTcpListen },
 	{ "allowusers", sAllowUsers },
 	{ "denyusers", sDenyUsers },
 	{ "allowgroups", sAllowGroups },
@@ -379,7 +394,8 @@
 	{ "clientalivecountmax", sClientAliveCountMax },
 	{ "authorizedkeysfile", sAuthorizedKeysFile },
 	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
-	{ "useprivilegeseparation", sUsePrivilegeSeparation},
+	{ "useprivilegeseparation", sUsePrivilegeSeparation },
+	{ "versionaddendum", sVersionAddendum },
 	{ NULL, sBadOption }
 };
 
@@ -705,6 +721,30 @@
 		charptr = &options->xauth_location;
 		goto parse_filename;
 
+	case sRestrictedShell:
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: missing restrictions.",
+			    filename, linenum);
+		options->restrictions = 0;
+		while ((p = strsep(&arg, ",")) != NULL) {
+			if (strcasecmp(p, "agent") == 0)
+				options->restrictions |= RESTRICT_AGENT;
+			else if (strcasecmp(p, "env") == 0)
+				options->restrictions |= RESTRICT_ENV;
+			else if (strcasecmp(p, "rc") == 0)
+				options->restrictions |= RESTRICT_RC;
+			else if (strcasecmp(p, "tcp") == 0)
+				options->restrictions |= RESTRICT_TCP;
+			else if (strcasecmp(p, "x11") == 0)
+				options->restrictions |= RESTRICT_X11;
+			else
+				fatal("%s line %d: unknown restriction %s.",
+				    filename, linenum, p);
+		}
+		charptr = &options->restricted_shell;
+		goto parse_filename;
+
 	case sStrictModes:
 		intptr = &options->strict_modes;
 		goto parse_flag;
@@ -763,6 +803,22 @@
 		intptr = &options->allow_tcp_forwarding;
 		goto parse_flag;
 
+	case sPermitTcpConnect:
+		arg = strdelim(&cp);
+		p = NULL;
+		if (!arg || *arg == '\0')
+			p = "missing";
+		if (channel_add_permitted_opens(arg) < 0)
+			p = "bad";
+		if (p != NULL)
+			fatal("%.200s, line %d: %s inet addr:port.",
+			    filename, linenum, p);
+		break;
+
+	case sPermitTcpListen:
+		intptr = &options->permit_tcp_listen;
+		goto parse_flag;
+
 	case sUsePrivilegeSeparation:
 		intptr = &use_privsep;
 		goto parse_flag;
@@ -908,6 +964,13 @@
 	case sClientAliveCountMax:
 		intptr = &options->client_alive_count_max;
 		goto parse_int;
+
+	case sVersionAddendum:
+		ssh_version_set_addendum(strtok(cp, "\n"));
+		do {
+			arg = strdelim(&cp);
+		} while (arg != NULL && *arg != '\0');
+		break;
 
 	case sDeprecated:
 		log("%s line %d: Deprecated option %s",
--- servconf.h	28 Jan 2003 18:06:52 -0000	1.1.1.2
+++ servconf.h	29 Jan 2003 21:26:12 -0000	1.7
@@ -32,6 +33,13 @@
 #define	PERMIT_NO_PASSWD	2
 #define	PERMIT_YES		3
 
+/* restrictions */
+#define	RESTRICT_AGENT		1
+#define	RESTRICT_ENV		2
+#define	RESTRICT_RC		4
+#define	RESTRICT_TCP		8
+#define	RESTRICT_X11		16
+
 
 typedef struct {
 	u_int num_ports;
@@ -98,6 +106,9 @@
 	int     permit_empty_passwd;	/* If false, do not permit empty
 					 * passwords. */
 	int     permit_user_env;	/* If true, read ~/.ssh/environment */
+	int     permit_tcp_listen;	/* If true allow -R forwarding */
+	char   *restricted_shell;	/* Restrict users with this shell */
+	int     restrictions;		/* How they are restricted */
 	int     use_login;	/* If true, login(1) is used */
 	int     compression;	/* If true, compression is allowed */
 	int	allow_tcp_forwarding;
--- serverloop.c	28 Jan 2003 18:06:52 -0000	1.1.1.2
+++ serverloop.c	24 Mar 2003 20:53:06 -0000	1.7
@@ -872,6 +874,7 @@
 	xfree(originator);
 	if (sock < 0)
 		return NULL;
+	log("TCP forwarding connection to %s port %d", target, target_port);
 	c = channel_new(ctype, SSH_CHANNEL_CONNECTING,
 	    sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
 	    CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1);
@@ -977,8 +980,8 @@
 		    listen_address, listen_port);
 
 		/* check permissions */
-		if (!options.allow_tcp_forwarding ||
-		    no_port_forwarding_flag
+		if (!options.permit_tcp_listen ||
+		    auth_restricted(RESTRICT_TCP, pw)
 #ifndef NO_IPPORT_RESERVED_CONCEPT
 		    || (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)
 #endif
@@ -987,6 +990,8 @@
 			packet_send_debug("Server has disabled port forwarding.");
 		} else {
 			/* Start listening on the port */
+			log("TCP forwarding listening on %s port %d",
+			    listen_address, listen_port);
 			success = channel_setup_remote_fwd_listener(
 			    listen_address, listen_port, options.gateway_ports);
 		}
@@ -1061,7 +1066,7 @@
 	dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
 	dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
 	dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
-	dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
+	dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open_loud);
 }
 static void
 server_init_dispatch_15(void)
--- session.c	28 Jan 2003 18:06:52 -0000	1.1.1.2
+++ session.c	29 Jan 2003 20:39:20 -0000	1.7
@@ -212,7 +214,7 @@
 	}
 
 	/* setup the channel layer */
-	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
+	if (!auth_restricted(RESTRICT_TCP, authctxt->pw))
 		channel_permit_all_opens();
 
 	if (compat20)
@@ -312,7 +314,7 @@
 			break;
 
 		case SSH_CMSG_AGENT_REQUEST_FORWARDING:
-			if (no_agent_forwarding_flag || compat13) {
+			if (auth_restricted(RESTRICT_AGENT, s->pw) || compat13) {
 				debug("Authentication agent forwarding not permitted for this authentication.");
 				break;
 			}
@@ -321,11 +323,7 @@
 			break;
 
 		case SSH_CMSG_PORT_FORWARD_REQUEST:
-			if (no_port_forwarding_flag) {
-				debug("Port forwarding not permitted for this authentication.");
-				break;
-			}
-			if (!options.allow_tcp_forwarding) {
+			if (auth_restricted(RESTRICT_TCP, s->pw)) {
 				debug("Port forwarding not permitted.");
 				break;
 			}
@@ -1085,7 +1083,7 @@
 		    auth_sock_name);
 
 	/* read $HOME/.ssh/environment. */
-	if (options.permit_user_env && !options.use_login) {
+	if (!options.use_login && !auth_restricted(RESTRICT_ENV, pw)) {
 		snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
 		    strcmp(pw->pw_dir, "/") ? pw->pw_dir : "");
 		read_environment_file(&env, &envsize, buf);
@@ -1102,6 +1100,10 @@
 /*
  * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
  * first in this order).
+ *
+ * A properly-implemented restricted shell doesn't need the
+ * restriction tests, but they're useful for reducing the
+ * amount of noise in the process accounting logs.
  */
 static void
 do_rc_files(Session *s, const char *shell)
@@ -1111,11 +1113,12 @@
 	int do_xauth;
 	struct stat st;
 
-	do_xauth =
+	do_xauth = !auth_restricted(RESTRICT_X11, s->pw) &&
 	    s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
 
 	/* ignore _PATH_SSH_USER_RC for subsystems */
-	if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
+	if (!s->is_subsystem && !auth_restricted(RESTRICT_RC, s->pw) &&
+	    (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
 		snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
 		    shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
 		if (debug_flag)
@@ -1723,8 +1726,8 @@
 {
 	static int called = 0;
 	packet_check_eom();
-	if (no_agent_forwarding_flag) {
-		debug("session_auth_agent_req: no_agent_forwarding_flag");
+	if (auth_restricted(RESTRICT_AGENT, s->pw)) {
+		debug("session_auth_agent_req: agent forwarding disabled");
 		return 0;
 	}
 	if (called) {
@@ -2019,12 +2022,8 @@
 	char display[512], auth_display[512];
 	char hostname[MAXHOSTNAMELEN];
 
-	if (no_x11_forwarding_flag) {
-		packet_send_debug("X11 forwarding disabled in user configuration file.");
-		return 0;
-	}
-	if (!options.x11_forwarding) {
-		debug("X11 forwarding disabled in server configuration file.");
+	if (auth_restricted(RESTRICT_X11, s->pw)) {
+		packet_send_debug("X11 forwarding disabled.");
 		return 0;
 	}
 	if (!options.xauth_location ||
--- ssh_config.5	28 Jan 2003 18:06:53 -0000	1.1.1.2
+++ ssh_config.5	24 Mar 2003 16:03:01 -0000	1.2
@@ -611,6 +612,10 @@
 Specifies a file to use for the user
 host key database instead of
 .Pa $HOME/.ssh/known_hosts .
+.It Cm VersionAddendum
+Specifies a string to append to the regular version string to identify
+OS- or site-specific modifications.
+The default is empty.
 .It Cm XAuthLocation
 Specifies the full pathname of the
 .Xr xauth 1
--- sshd_config	28 Jan 2003 18:06:53 -0000	1.1.1.2
+++ sshd_config	23 Mar 2003 19:40:37 -0000	1.6
@@ -76,12 +77,16 @@
 #X11Forwarding no
 #X11DisplayOffset 10
 #X11UseLocalhost yes
+#AllowTcpForwarding yes
+#PermitTcpListen yes
+#PermitTcpConnect
 #PrintMotd yes
 #PrintLastLog yes
 #KeepAlive yes
 #UseLogin no
 #UsePrivilegeSeparation yes
 #PermitUserEnvironment no
+#RestrictedShell
 #Compression yes
 
 #MaxStartups 10
--- sshd_config.5	28 Jan 2003 18:06:53 -0000	1.1.1.2
+++ sshd_config.5	24 Mar 2003 16:03:01 -0000	1.9
@@ -465,6 +466,35 @@
 If this option is set to
 .Dq no
 root is not allowed to login.
+.It Cm PermitTcpConnect
+Restricts TCP forwarding from the client so that
+only certain connection destinations are permitted.
+In the absence of any
+.Cm PermitTcpConnect
+options, any outgoing connection is permitted
+(although per-key restrictions may be imposed by
+.Cm permitopen=""
+options in
+.Pa authorized_keys
+files).
+If
+.Cm PermitTcpConnect
+options are present then
+.Nm sshd
+will only allow connections to the
+.Ar host Ns : Ns Ar port
+pairs that are specified.
+Multiple permitted destinations may be specified using multiple
+.Cm PermitTcpConnect
+options.
+IPv6 addresses may be specified using the syntax
+.Ar host Ns / Ns Ar port
+for the argument instead of
+.Ar host Ns : Ns Ar port .
+.It Cm PermitTcpListen
+Specifies whether TCP forwarding to the client is allowed.
+The default is
+.Dq yes .
 .It Cm PermitUserEnvironment
 Specifies whether
 .Pa ~/.ssh/environment
@@ -533,6 +563,29 @@
 The default is
 .Dq yes .
 Note that this option applies to protocol version 2 only.
+.It Cm RestrictedShell
+This option selectively turns off various features
+for users with the shell specified in the second argument.
+The first argument is a comma-separated list, as follows.
+If
+.Dq agent
+is specified then agent forwarding is disabled.
+If
+.Dq env
+is specified then
+.Cm PermitUserEnvironment
+is turned off.
+If
+.Dq rc
+is specified then
+.Pa ~/.ssh/rc
+is not run.
+If
+.Dq tcp
+is specified then TCP port forwarding is disabled.
+If
+.Dq x11
+is specified then X11 fowarding is disabled.
 .It Cm RhostsAuthentication
 Specifies whether authentication using rhosts or /etc/hosts.equiv
 files is sufficient.
@@ -620,6 +673,10 @@
 very same IP address.
 The default is
 .Dq no .
+.It Cm VersionAddendum
+Specifies a string to append to the regular version string to identify
+OS- or site-specific modifications.
+The default is empty.
 .It Cm X11DisplayOffset
 Specifies the first display number available for
 .Nm sshd Ns 's
--- version.h	28 Jan 2003 18:06:53 -0000	1.1.1.2
+++ version.h	24 Mar 2003 16:03:01 -0000	1.2
@@ -1,4 +1,14 @@
 /* $OpenBSD: version.h,v 1.35 2002/10/01 13:24:50 markus Exp $ */
+/* $FreeBSD: src/crypto/openssh/version.h,v 1.19 2003/02/03 11:11:36 des Exp $ */
+/* $Cambridge: hermes/src/openssh/version.h,v 1.2 2003/03/24 16:03:01 fanf2 Exp $ */
 
-#define SSH_VERSION	"OpenSSH_3.5p1"
+#ifndef SSH_VERSION
+
+#define SSH_VERSION             (ssh_version_get())
+#define SSH_VERSION_BASE        "OpenSSH_3.5p1"
+#define SSH_VERSION_ADDENDUM    "noAJ"
+
+const char *ssh_version_get(void);
+void ssh_version_set_addendum(const char *add);
+#endif /* SSH_VERSION */
 




More information about the openssh-unix-dev mailing list