summaryrefslogtreecommitdiff
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 c3069df12..2e28a43f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -26,6 +26,17 @@
26 - dtucker@cvs.openbsd.org 2006/07/17 12:02:24 26 - dtucker@cvs.openbsd.org 2006/07/17 12:02:24
27 [auth-options.c] 27 [auth-options.c]
28 Use '\0' rather than 0 to terminates strings; ok djm@ 28 Use '\0' rather than 0 to terminates strings; ok djm@
29 - dtucker@cvs.openbsd.org 2006/07/17 12:06:00
30 [channels.c channels.h servconf.c sshd_config.5]
31 Add PermitOpen directive to sshd_config which is equivalent to the
32 "permitopen" key option. Allows server admin to allow TCP port
33 forwarding only two specific host/port pairs. Useful when combined
34 with Match.
35 If permitopen is used in both sshd_config and a key option, both
36 must allow a given connection before it will be permitted.
37 Note that users can still use external forwarders such as netcat,
38 so to be those must be controlled too for the limits to be effective.
39 Feedback & ok djm@, man page corrections & ok jmc@.
29 40
3020060713 4120060713
31 - (dtucker) [auth-krb5.c auth-pam.c] Still more errno.h 42 - (dtucker) [auth-krb5.c auth-pam.c] Still more errno.h
@@ -4944,4 +4955,4 @@
4944 - (djm) Trim deprecated options from INSTALL. Mention UsePAM 4955 - (djm) Trim deprecated options from INSTALL. Mention UsePAM
4945 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu 4956 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
4946 4957
4947$Id: ChangeLog,v 1.4414 2006/07/24 04:01:43 djm Exp $ 4958$Id: ChangeLog,v 1.4415 2006/07/24 04:04:00 djm Exp $
diff --git a/channels.c b/channels.c
index fbbae9ed7..9aaf7e9d7 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.256 2006/07/17 01:31:09 stevesk Exp $ */ 1/* $OpenBSD: channels.c,v 1.257 2006/07/17 12:06:00 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -106,11 +106,18 @@ typedef struct {
106 u_short listen_port; /* Remote side should listen port number. */ 106 u_short listen_port; /* Remote side should listen port number. */
107} ForwardPermission; 107} ForwardPermission;
108 108
109/* List of all permitted host/port pairs to connect. */ 109/* List of all permitted host/port pairs to connect by the user. */
110static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; 110static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
111 111
112/* Number of permitted host/port pairs in the array. */ 112/* List of all permitted host/port pairs to connect by the admin. */
113static ForwardPermission permitted_adm_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
114
115/* Number of permitted host/port pairs in the array permitted by the user. */
113static int num_permitted_opens = 0; 116static int num_permitted_opens = 0;
117
118/* Number of permitted host/port pair in the array permitted by the admin. */
119static int num_adm_permitted_opens = 0;
120
114/* 121/*
115 * If this is true, all opens are permitted. This is the case on the server 122 * If this is true, all opens are permitted. This is the case on the server
116 * on which we have to trust the client anyway, and the user could do 123 * 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)
2647} 2654}
2648 2655
2649void 2656void
2657channel_add_adm_permitted_opens(char *host, int port)
2658{
2659 if (num_adm_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
2660 fatal("channel_add_adm_permitted_opens: too many forwards");
2661 debug("allow port forwarding to host %s port %d", host, port);
2662
2663 permitted_adm_opens[num_adm_permitted_opens].host_to_connect
2664 = xstrdup(host);
2665 permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port;
2666 num_adm_permitted_opens++;
2667}
2668
2669void
2650channel_clear_permitted_opens(void) 2670channel_clear_permitted_opens(void)
2651{ 2671{
2652 int i; 2672 int i;
@@ -2655,7 +2675,17 @@ channel_clear_permitted_opens(void)
2655 if (permitted_opens[i].host_to_connect != NULL) 2675 if (permitted_opens[i].host_to_connect != NULL)
2656 xfree(permitted_opens[i].host_to_connect); 2676 xfree(permitted_opens[i].host_to_connect);
2657 num_permitted_opens = 0; 2677 num_permitted_opens = 0;
2678}
2679
2680void
2681channel_clear_adm_permitted_opens(void)
2682{
2683 int i;
2658 2684
2685 for (i = 0; i < num_adm_permitted_opens; i++)
2686 if (permitted_adm_opens[i].host_to_connect != NULL)
2687 xfree(permitted_adm_opens[i].host_to_connect);
2688 num_adm_permitted_opens = 0;
2659} 2689}
2660 2690
2661/* return socket to remote host, port */ 2691/* return socket to remote host, port */
@@ -2734,7 +2764,7 @@ channel_connect_by_listen_address(u_short listen_port)
2734int 2764int
2735channel_connect_to(const char *host, u_short port) 2765channel_connect_to(const char *host, u_short port)
2736{ 2766{
2737 int i, permit; 2767 int i, permit, permit_adm = 1;
2738 2768
2739 permit = all_opens_permitted; 2769 permit = all_opens_permitted;
2740 if (!permit) { 2770 if (!permit) {
@@ -2743,9 +2773,19 @@ channel_connect_to(const char *host, u_short port)
2743 permitted_opens[i].port_to_connect == port && 2773 permitted_opens[i].port_to_connect == port &&
2744 strcmp(permitted_opens[i].host_to_connect, host) == 0) 2774 strcmp(permitted_opens[i].host_to_connect, host) == 0)
2745 permit = 1; 2775 permit = 1;
2776 }
2746 2777
2778 if (num_adm_permitted_opens > 0) {
2779 permit_adm = 0;
2780 for (i = 0; i < num_adm_permitted_opens; i++)
2781 if (permitted_adm_opens[i].host_to_connect != NULL &&
2782 permitted_adm_opens[i].port_to_connect == port &&
2783 strcmp(permitted_adm_opens[i].host_to_connect, host)
2784 == 0)
2785 permit_adm = 1;
2747 } 2786 }
2748 if (!permit) { 2787
2788 if (!permit || !permit_adm) {
2749 logit("Received request to connect to host %.100s port %d, " 2789 logit("Received request to connect to host %.100s port %d, "
2750 "but the request was denied.", host, port); 2790 "but the request was denied.", host, port);
2751 return -1; 2791 return -1;
diff --git a/channels.h b/channels.h
index d21319a2b..c473b730c 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.85 2006/07/11 18:50:47 markus Exp $ */ 1/* $OpenBSD: channels.h,v 1.86 2006/07/17 12:06:00 dtucker Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -207,7 +207,9 @@ int channel_find_open(void);
207void channel_set_af(int af); 207void channel_set_af(int af);
208void channel_permit_all_opens(void); 208void channel_permit_all_opens(void);
209void channel_add_permitted_opens(char *, int); 209void channel_add_permitted_opens(char *, int);
210void channel_add_adm_permitted_opens(char *, int);
210void channel_clear_permitted_opens(void); 211void channel_clear_permitted_opens(void);
212void channel_clear_adm_permitted_opens(void);
211int channel_input_port_forward_request(int, int); 213int channel_input_port_forward_request(int, int);
212int channel_connect_to(const char *, u_short); 214int channel_connect_to(const char *, u_short);
213int channel_connect_by_listen_address(u_short); 215int channel_connect_by_listen_address(u_short);
diff --git a/servconf.c b/servconf.c
index 330e79143..4f5cb19db 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.c,v 1.155 2006/07/17 01:31:09 stevesk Exp $ */ 1/* $OpenBSD: servconf.c,v 1.156 2006/07/17 12:06:00 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved 4 * All rights reserved
@@ -31,6 +31,7 @@
31#include "kex.h" 31#include "kex.h"
32#include "mac.h" 32#include "mac.h"
33#include "match.h" 33#include "match.h"
34#include "channels.h"
34 35
35static void add_listen_addr(ServerOptions *, char *, u_short); 36static void add_listen_addr(ServerOptions *, char *, u_short);
36static void add_one_listen_addr(ServerOptions *, char *, u_short); 37static void add_one_listen_addr(ServerOptions *, char *, u_short);
@@ -281,7 +282,7 @@ typedef enum {
281 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 282 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
282 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, 283 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
283 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, 284 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
284 sMatch, 285 sMatch, sPermitOpen,
285 sUsePrivilegeSeparation, 286 sUsePrivilegeSeparation,
286 sDeprecated, sUnsupported 287 sDeprecated, sUnsupported
287} ServerOpCodes; 288} ServerOpCodes;
@@ -390,6 +391,8 @@ static struct {
390 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL }, 391 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
391 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL }, 392 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
392 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL }, 393 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
394 { "match", sMatch, SSHCFG_ALL },
395 { "permitopen", sPermitOpen, SSHCFG_ALL },
393 { NULL, sBadOption, 0 } 396 { NULL, sBadOption, 0 }
394}; 397};
395 398
@@ -1148,6 +1151,28 @@ parse_flag:
1148 *activep = value; 1151 *activep = value;
1149 break; 1152 break;
1150 1153
1154 case sPermitOpen:
1155 arg = strdelim(&cp);
1156 if (!arg || *arg == '\0')
1157 fatal("%s line %d: missing PermitOpen specification",
1158 filename, linenum);
1159 if (strcmp(arg, "any") == 0) {
1160 if (*activep)
1161 channel_clear_adm_permitted_opens();
1162 break;
1163 }
1164 p = hpdelim(&arg);
1165 if (p == NULL)
1166 fatal("%s line %d: missing host in PermitOpen",
1167 filename, linenum);
1168 p = cleanhostname(p);
1169 if (arg == NULL || (port = a2port(arg)) == 0)
1170 fatal("%s line %d: bad port number in PermitOpen",
1171 filename, linenum);
1172 if (*activep)
1173 channel_add_adm_permitted_opens(p, port);
1174 break;
1175
1151 case sDeprecated: 1176 case sDeprecated:
1152 logit("%s line %d: Deprecated option %s", 1177 logit("%s line %d: Deprecated option %s",
1153 filename, linenum, arg); 1178 filename, linenum, arg);
diff --git a/sshd_config.5 b/sshd_config.5
index 4db92814c..c9515234d 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd_config.5,v 1.61 2006/07/12 13:39:55 jmc Exp $ 37.\" $OpenBSD: sshd_config.5,v 1.62 2006/07/17 12:06:00 dtucker Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSHD_CONFIG 5 39.Dt SSHD_CONFIG 5
40.Os 40.Os
@@ -482,9 +482,10 @@ Only a subset of keywords may be used on the lines following a
482.Cm Match 482.Cm Match
483keyword. 483keyword.
484Available keywords are 484Available keywords are
485.Cm AllowTcpForwarding 485.Cm AllowTcpForwarding ,
486.Cm GatewayPorts ,
486and 487and
487.Cm GatewayPorts . 488.Cm PermitOpen .
488.It Cm MaxAuthTries 489.It Cm MaxAuthTries
489Specifies the maximum number of authentication attempts permitted per 490Specifies the maximum number of authentication attempts permitted per
490connection. 491connection.
@@ -524,6 +525,35 @@ When password authentication is allowed, it specifies whether the
524server allows login to accounts with empty password strings. 525server allows login to accounts with empty password strings.
525The default is 526The default is
526.Dq no . 527.Dq no .
528.It Cm PermitOpen
529Specifies the destinations to which TCP port forwarding is permitted.
530The forwarding specification must be one of the following forms:
531.Pp
532.Bl -item -offset indent -compact
533.It
534.Cm PermitOpen
535.Sm off
536.Ar host : port
537.Sm on
538.It
539.Cm PermitOpen
540.Sm off
541.Ar IPv4_addr : port
542.Sm on
543.It
544.Cm PermitOpen
545.Sm off
546.Ar \&[ IPv6_addr \&] : port
547.Sm on
548.El
549.Pp
550Multiple instances of
551.Cm PermitOpen
552are permitted.
553An argument of
554.Dq any
555can be used to remove all restrictions and permit any forwarding requests.
556By default all port forward requests are permitted.
527.It Cm PermitRootLogin 557.It Cm PermitRootLogin
528Specifies whether root can log in using 558Specifies whether root can log in using
529.Xr ssh 1 . 559.Xr ssh 1 .