Krister Bergman
2004-Jan-19 09:09 UTC
Security suggestion concering SSH and port forwarding.
Hi, sorry if it is the wrong approuch to suggest improvments to OpenSSH, but here comes my suggestion: 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. Example scenario: You're on a privat network, behind a firewall. You're letting port 22 in to your linux machine. A few trusted people have normal accounts on this machine allowing them to use -L to forward ports to other machines on the private network. Still you want to give other, less trusted people, access to file areas on the same machine. You want to keep this as secure as possible and wants to give them accounts allowing them fileaccess to a certain chroot:ed environment by using the scponlyc shell. You do NOT want these people to be able to, for example, use port forwarding to access some less secure W*ndows machines in the private network. I know a workaround would be to use two different ssh servers with two different sshd_config files, each allowing only a certain range of users and one allowing port forwaring, and one not allowing it. A nicer solution would be if it could be specified in the sshd_config which users are allowed to use port forwarding. Please cc: all answers to me, since I'm not a member of this mailing list. Best Regards Krister Bergman
Darren Tucker
2004-Jan-19 09:54 UTC
Security suggestion concering SSH and port forwarding.
Krister Bergman wrote:> sorry if it is the wrong approuch to suggest improvments to OpenSSH, > but here comes my suggestion: > > 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.If you're using public-key authentication you can use the no-port-forwarding flag on the key: $ man sshd AUTHORIZED_KEYS FILE FORMAT [snip] no-port-forwarding Forbids TCP/IP forwarding when this key is used for authentica- tion. Any port forward requests by the client will return an error. This might be used, e.g., in connection with the command option. -- Darren Tucker (dtucker at zip.com.au) GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69 Good judgement comes with experience. Unfortunately, the experience usually comes from bad judgement.
Ben Lindstrom
2004-Jan-19 09:58 UTC
Security suggestion concering SSH and port forwarding.
What is wrong with using public keys? Refer to "man sshd" under "authorized keys format" you can set what command that key is good for, if they can do port forward, from what IP it is valid, etc. - Ben On Mon, 19 Jan 2004, Krister Bergman wrote:> Hi, > > sorry if it is the wrong approuch to suggest improvments to OpenSSH, > but here comes my suggestion: > > 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. > > Example scenario: > > You're on a privat network, behind a firewall. You're letting port 22 in > to your linux machine. A few trusted people have normal accounts on this > machine allowing them to use -L to forward ports to other machines on the > private network. > > Still you want to give other, less trusted people, access to file areas on > the same machine. You want to keep this as secure as possible and wants to > give them accounts allowing them fileaccess to a certain chroot:ed > environment by using the scponlyc shell. You do NOT want these people to > be able to, for example, use port forwarding to access some less secure > W*ndows machines in the private network. > > I know a workaround would be to use two different ssh servers with two > different sshd_config files, each allowing only a certain range of users > and one allowing port forwaring, and one not allowing it. > > A nicer solution would be if it could be specified in the sshd_config > which users are allowed to use port forwarding. > > Please cc: all answers to me, since I'm not a member of this mailing list. > > > > Best Regards > > Krister Bergman > > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > http://www.mindrot.org/mailman/listinfo/openssh-unix-dev >
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 */