summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2006-07-24 14:04:00 +1000
committerDamien Miller <djm@mindrot.org>2006-07-24 14:04:00 +1000
commit9b439df18a9d56683584811ce38dcf72acd4cb20 (patch)
treedc7d64d4ae9ce7c47d52804671e8b5d2aedddae3 /channels.c
parent98299261eb970688a7bad346491cffdf2a7f6072 (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.c50
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. */
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;