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 @@ | |||
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 | ||
30 | 20060713 | 41 | 20060713 |
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. */ |
110 | static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; | 110 | static 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. */ |
113 | static ForwardPermission permitted_adm_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; | ||
114 | |||
115 | /* Number of permitted host/port pairs in the array permitted by the user. */ | ||
113 | static int num_permitted_opens = 0; | 116 | static int num_permitted_opens = 0; |
117 | |||
118 | /* Number of permitted host/port pair in the array permitted by the admin. */ | ||
119 | static 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 | ||
2649 | void | 2656 | void |
2657 | channel_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 | |||
2669 | void | ||
2650 | channel_clear_permitted_opens(void) | 2670 | channel_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 | |||
2680 | void | ||
2681 | channel_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) | |||
2734 | int | 2764 | int |
2735 | channel_connect_to(const char *host, u_short port) | 2765 | channel_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); | |||
207 | void channel_set_af(int af); | 207 | void channel_set_af(int af); |
208 | void channel_permit_all_opens(void); | 208 | void channel_permit_all_opens(void); |
209 | void channel_add_permitted_opens(char *, int); | 209 | void channel_add_permitted_opens(char *, int); |
210 | void channel_add_adm_permitted_opens(char *, int); | ||
210 | void channel_clear_permitted_opens(void); | 211 | void channel_clear_permitted_opens(void); |
212 | void channel_clear_adm_permitted_opens(void); | ||
211 | int channel_input_port_forward_request(int, int); | 213 | int channel_input_port_forward_request(int, int); |
212 | int channel_connect_to(const char *, u_short); | 214 | int channel_connect_to(const char *, u_short); |
213 | int channel_connect_by_listen_address(u_short); | 215 | int 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 | ||
35 | static void add_listen_addr(ServerOptions *, char *, u_short); | 36 | static void add_listen_addr(ServerOptions *, char *, u_short); |
36 | static void add_one_listen_addr(ServerOptions *, char *, u_short); | 37 | static 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 |
483 | keyword. | 483 | keyword. |
484 | Available keywords are | 484 | Available keywords are |
485 | .Cm AllowTcpForwarding | 485 | .Cm AllowTcpForwarding , |
486 | .Cm GatewayPorts , | ||
486 | and | 487 | and |
487 | .Cm GatewayPorts . | 488 | .Cm PermitOpen . |
488 | .It Cm MaxAuthTries | 489 | .It Cm MaxAuthTries |
489 | Specifies the maximum number of authentication attempts permitted per | 490 | Specifies the maximum number of authentication attempts permitted per |
490 | connection. | 491 | connection. |
@@ -524,6 +525,35 @@ When password authentication is allowed, it specifies whether the | |||
524 | server allows login to accounts with empty password strings. | 525 | server allows login to accounts with empty password strings. |
525 | The default is | 526 | The default is |
526 | .Dq no . | 527 | .Dq no . |
528 | .It Cm PermitOpen | ||
529 | Specifies the destinations to which TCP port forwarding is permitted. | ||
530 | The 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 | ||
550 | Multiple instances of | ||
551 | .Cm PermitOpen | ||
552 | are permitted. | ||
553 | An argument of | ||
554 | .Dq any | ||
555 | can be used to remove all restrictions and permit any forwarding requests. | ||
556 | By default all port forward requests are permitted. | ||
527 | .It Cm PermitRootLogin | 557 | .It Cm PermitRootLogin |
528 | Specifies whether root can log in using | 558 | Specifies whether root can log in using |
529 | .Xr ssh 1 . | 559 | .Xr ssh 1 . |