diff options
author | Damien Miller <djm@mindrot.org> | 2006-07-24 14:04:00 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2006-07-24 14:04:00 +1000 |
commit | 9b439df18a9d56683584811ce38dcf72acd4cb20 (patch) | |
tree | dc7d64d4ae9ce7c47d52804671e8b5d2aedddae3 /channels.c | |
parent | 98299261eb970688a7bad346491cffdf2a7f6072 (diff) |
- 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@.
Diffstat (limited to 'channels.c')
-rw-r--r-- | channels.c | 50 |
1 files changed, 45 insertions, 5 deletions
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; |