summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--channels.c50
-rw-r--r--channels.h4
-rw-r--r--servconf.c29
-rw-r--r--sshd_config.536
5 files changed, 120 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index c3069df1..2e28a43f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 $
diff --git a/channels.c b/channels.c
index fbbae9ed..9aaf7e9d 100644
--- a/channels.c
+++ b/channels.c
@@ -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;
diff --git a/channels.h b/channels.h
index d21319a2..c473b730 100644
--- a/channels.h
+++ b/channels.h
@@ -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);
diff --git a/servconf.c b/servconf.c
index 330e7914..4f5cb19d 100644
--- a/servconf.c
+++ b/servconf.c
@@ -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 .