diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | channels.c | 50 | ||||
-rw-r--r-- | channels.h | 4 | ||||
-rw-r--r-- | servconf.c | 29 | ||||
-rw-r--r-- | sshd_config.5 | 36 |
5 files changed, 120 insertions, 12 deletions
@@ -26,6 +26,17 @@ - dtucker@cvs.openbsd.org 2006/07/17 12:02:24 [auth-options.c] Use '\0' rather than 0 to terminates strings; ok djm@ + - dtucker@cvs.openbsd.org 2006/07/17 12:06:00 + [channels.c channels.h servconf.c sshd_config.5] + Add PermitOpen directive to sshd_config which is equivalent to the + "permitopen" key option. Allows server admin to allow TCP port + forwarding only two specific host/port pairs. Useful when combined + with Match. + If permitopen is used in both sshd_config and a key option, both + must allow a given connection before it will be permitted. + Note that users can still use external forwarders such as netcat, + so to be those must be controlled too for the limits to be effective. + Feedback & ok djm@, man page corrections & ok jmc@. 20060713 - (dtucker) [auth-krb5.c auth-pam.c] Still more errno.h @@ -4944,4 +4955,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4414 2006/07/24 04:01:43 djm Exp $ +$Id: ChangeLog,v 1.4415 2006/07/24 04:04:00 djm Exp $ @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.256 2006/07/17 01:31:09 stevesk Exp $ */ +/* $OpenBSD: channels.c,v 1.257 2006/07/17 12:06:00 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -106,11 +106,18 @@ typedef struct { u_short listen_port; /* Remote side should listen port number. */ } ForwardPermission; -/* List of all permitted host/port pairs to connect. */ +/* List of all permitted host/port pairs to connect by the user. */ static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; -/* Number of permitted host/port pairs in the array. */ +/* List of all permitted host/port pairs to connect by the admin. */ +static ForwardPermission permitted_adm_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; + +/* Number of permitted host/port pairs in the array permitted by the user. */ static int num_permitted_opens = 0; + +/* Number of permitted host/port pair in the array permitted by the admin. */ +static int num_adm_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 @@ -2647,6 +2654,19 @@ channel_add_permitted_opens(char *host, int port) } void +channel_add_adm_permitted_opens(char *host, int port) +{ + if (num_adm_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("channel_add_adm_permitted_opens: too many forwards"); + debug("allow port forwarding to host %s port %d", host, port); + + permitted_adm_opens[num_adm_permitted_opens].host_to_connect + = xstrdup(host); + permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port; + num_adm_permitted_opens++; +} + +void channel_clear_permitted_opens(void) { int i; @@ -2655,7 +2675,17 @@ channel_clear_permitted_opens(void) if (permitted_opens[i].host_to_connect != NULL) xfree(permitted_opens[i].host_to_connect); num_permitted_opens = 0; +} + +void +channel_clear_adm_permitted_opens(void) +{ + int i; + for (i = 0; i < num_adm_permitted_opens; i++) + if (permitted_adm_opens[i].host_to_connect != NULL) + xfree(permitted_adm_opens[i].host_to_connect); + num_adm_permitted_opens = 0; } /* return socket to remote host, port */ @@ -2734,7 +2764,7 @@ channel_connect_by_listen_address(u_short listen_port) int channel_connect_to(const char *host, u_short port) { - int i, permit; + int i, permit, permit_adm = 1; permit = all_opens_permitted; if (!permit) { @@ -2743,9 +2773,19 @@ channel_connect_to(const char *host, u_short port) permitted_opens[i].port_to_connect == port && strcmp(permitted_opens[i].host_to_connect, host) == 0) permit = 1; + } + if (num_adm_permitted_opens > 0) { + permit_adm = 0; + for (i = 0; i < num_adm_permitted_opens; i++) + if (permitted_adm_opens[i].host_to_connect != NULL && + permitted_adm_opens[i].port_to_connect == port && + strcmp(permitted_adm_opens[i].host_to_connect, host) + == 0) + permit_adm = 1; } - if (!permit) { + + if (!permit || !permit_adm) { logit("Received request to connect to host %.100s port %d, " "but the request was denied.", host, port); return -1; @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.85 2006/07/11 18:50:47 markus Exp $ */ +/* $OpenBSD: channels.h,v 1.86 2006/07/17 12:06:00 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -207,7 +207,9 @@ int channel_find_open(void); void channel_set_af(int af); void channel_permit_all_opens(void); void channel_add_permitted_opens(char *, int); +void channel_add_adm_permitted_opens(char *, int); void channel_clear_permitted_opens(void); +void channel_clear_adm_permitted_opens(void); int channel_input_port_forward_request(int, int); int channel_connect_to(const char *, u_short); int channel_connect_by_listen_address(u_short); @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.155 2006/07/17 01:31:09 stevesk Exp $ */ +/* $OpenBSD: servconf.c,v 1.156 2006/07/17 12:06:00 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved @@ -31,6 +31,7 @@ #include "kex.h" #include "mac.h" #include "match.h" +#include "channels.h" static void add_listen_addr(ServerOptions *, char *, u_short); static void add_one_listen_addr(ServerOptions *, char *, u_short); @@ -281,7 +282,7 @@ typedef enum { sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, - sMatch, + sMatch, sPermitOpen, sUsePrivilegeSeparation, sDeprecated, sUnsupported } ServerOpCodes; @@ -390,6 +391,8 @@ static struct { { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL }, { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL }, { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL }, + { "match", sMatch, SSHCFG_ALL }, + { "permitopen", sPermitOpen, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -1148,6 +1151,28 @@ parse_flag: *activep = value; break; + case sPermitOpen: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing PermitOpen specification", + filename, linenum); + if (strcmp(arg, "any") == 0) { + if (*activep) + channel_clear_adm_permitted_opens(); + break; + } + p = hpdelim(&arg); + if (p == NULL) + fatal("%s line %d: missing host in PermitOpen", + filename, linenum); + p = cleanhostname(p); + if (arg == NULL || (port = a2port(arg)) == 0) + fatal("%s line %d: bad port number in PermitOpen", + filename, linenum); + if (*activep) + channel_add_adm_permitted_opens(p, port); + break; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); diff --git a/sshd_config.5 b/sshd_config.5 index 4db92814..c9515234 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (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: sshd_config.5,v 1.61 2006/07/12 13:39:55 jmc Exp $ +.\" $OpenBSD: sshd_config.5,v 1.62 2006/07/17 12:06:00 dtucker Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -482,9 +482,10 @@ Only a subset of keywords may be used on the lines following a .Cm Match keyword. Available keywords are -.Cm AllowTcpForwarding +.Cm AllowTcpForwarding , +.Cm GatewayPorts , and -.Cm GatewayPorts . +.Cm PermitOpen . .It Cm MaxAuthTries Specifies the maximum number of authentication attempts permitted per connection. @@ -524,6 +525,35 @@ When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. The default is .Dq no . +.It Cm PermitOpen +Specifies the destinations to which TCP port forwarding is permitted. +The forwarding specification must be one of the following forms: +.Pp +.Bl -item -offset indent -compact +.It +.Cm PermitOpen +.Sm off +.Ar host : port +.Sm on +.It +.Cm PermitOpen +.Sm off +.Ar IPv4_addr : port +.Sm on +.It +.Cm PermitOpen +.Sm off +.Ar \&[ IPv6_addr \&] : port +.Sm on +.El +.Pp +Multiple instances of +.Cm PermitOpen +are permitted. +An argument of +.Dq any +can be used to remove all restrictions and permit any forwarding requests. +By default all port forward requests are permitted. .It Cm PermitRootLogin Specifies whether root can log in using .Xr ssh 1 . |