summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--auth-options.c62
-rw-r--r--channels.c139
-rw-r--r--channels.h16
-rw-r--r--serverloop.c8
-rw-r--r--session.c11
6 files changed, 159 insertions, 83 deletions
diff --git a/ChangeLog b/ChangeLog
index 18256d037..50cc97d6a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,10 @@
18 - markus@cvs.openbsd.org 2001/03/16 13:44:24 18 - markus@cvs.openbsd.org 2001/03/16 13:44:24
19 [sftp-int.c] 19 [sftp-int.c]
20 discourage strcat/strcpy 20 discourage strcat/strcpy
21 - markus@cvs.openbsd.org 2001/03/16 19:06:30
22 [auth-options.c channels.c channels.h serverloop.c session.c]
23 implement "permitopen" key option, restricts -L style forwarding to
24 to specified host:port pairs. based on work by harlan@genua.de
21 25
2220010315 2620010315
23 - OpenBSD CVS Sync 27 - OpenBSD CVS Sync
@@ -4580,4 +4584,4 @@
4580 - Wrote replacements for strlcpy and mkdtemp 4584 - Wrote replacements for strlcpy and mkdtemp
4581 - Released 1.0pre1 4585 - Released 1.0pre1
4582 4586
4583$Id: ChangeLog,v 1.966 2001/03/17 00:37:31 mouring Exp $ 4587$Id: ChangeLog,v 1.967 2001/03/17 00:47:54 mouring Exp $
diff --git a/auth-options.c b/auth-options.c
index bfb1af86b..7ce1e4b0c 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -10,13 +10,14 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$OpenBSD: auth-options.c,v 1.14 2001/03/13 17:34:42 markus Exp $"); 13RCSID("$OpenBSD: auth-options.c,v 1.15 2001/03/16 19:06:28 markus Exp $");
14 14
15#include "packet.h" 15#include "packet.h"
16#include "xmalloc.h" 16#include "xmalloc.h"
17#include "match.h" 17#include "match.h"
18#include "log.h" 18#include "log.h"
19#include "canohost.h" 19#include "canohost.h"
20#include "channels.h"
20#include "auth-options.h" 21#include "auth-options.h"
21#include "servconf.h" 22#include "servconf.h"
22 23
@@ -51,6 +52,7 @@ auth_clear_options(void)
51 xfree(forced_command); 52 xfree(forced_command);
52 forced_command = NULL; 53 forced_command = NULL;
53 } 54 }
55 channel_clear_permitted_opens();
54} 56}
55 57
56/* 58/*
@@ -61,6 +63,7 @@ int
61auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) 63auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
62{ 64{
63 const char *cp; 65 const char *cp;
66 int i;
64 67
65 /* reset options */ 68 /* reset options */
66 auth_clear_options(); 69 auth_clear_options();
@@ -99,7 +102,6 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
99 } 102 }
100 cp = "command=\""; 103 cp = "command=\"";
101 if (strncasecmp(opts, cp, strlen(cp)) == 0) { 104 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
102 int i;
103 opts += strlen(cp); 105 opts += strlen(cp);
104 forced_command = xmalloc(strlen(opts) + 1); 106 forced_command = xmalloc(strlen(opts) + 1);
105 i = 0; 107 i = 0;
@@ -129,9 +131,9 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
129 } 131 }
130 cp = "environment=\""; 132 cp = "environment=\"";
131 if (strncasecmp(opts, cp, strlen(cp)) == 0) { 133 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
132 int i;
133 char *s; 134 char *s;
134 struct envstring *new_envstring; 135 struct envstring *new_envstring;
136
135 opts += strlen(cp); 137 opts += strlen(cp);
136 s = xmalloc(strlen(opts) + 1); 138 s = xmalloc(strlen(opts) + 1);
137 i = 0; 139 i = 0;
@@ -170,7 +172,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
170 const char *remote_host = get_canonical_hostname( 172 const char *remote_host = get_canonical_hostname(
171 options.reverse_mapping_check); 173 options.reverse_mapping_check);
172 char *patterns = xmalloc(strlen(opts) + 1); 174 char *patterns = xmalloc(strlen(opts) + 1);
173 int i; 175
174 opts += strlen(cp); 176 opts += strlen(cp);
175 i = 0; 177 i = 0;
176 while (*opts) { 178 while (*opts) {
@@ -218,6 +220,58 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
218 /* Host name matches. */ 220 /* Host name matches. */
219 goto next_option; 221 goto next_option;
220 } 222 }
223 cp = "permitopen=\"";
224 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
225 u_short port;
226 char *c, *ep;
227 char *patterns = xmalloc(strlen(opts) + 1);
228
229 opts += strlen(cp);
230 i = 0;
231 while (*opts) {
232 if (*opts == '"')
233 break;
234 if (*opts == '\\' && opts[1] == '"') {
235 opts += 2;
236 patterns[i++] = '"';
237 continue;
238 }
239 patterns[i++] = *opts++;
240 }
241 if (!*opts) {
242 debug("%.100s, line %lu: missing end quote",
243 file, linenum);
244 packet_send_debug("%.100s, line %lu: missing end quote",
245 file, linenum);
246 xfree(patterns);
247 goto bad_option;
248 }
249 patterns[i] = 0;
250 opts++;
251 c = strchr(patterns, ':');
252 if (c == NULL) {
253 debug("%.100s, line %lu: permitopen: missing colon <%.100s>",
254 file, linenum, patterns);
255 packet_send_debug("%.100s, line %lu: missing colon",
256 file, linenum);
257 xfree(patterns);
258 goto bad_option;
259 }
260 *c = 0;
261 c++;
262 port = strtol(c, &ep, 0);
263 if (c == ep) {
264 debug("%.100s, line %lu: permitopen: missing port <%.100s>",
265 file, linenum, patterns);
266 packet_send_debug("%.100s, line %lu: missing port",
267 file, linenum);
268 xfree(patterns);
269 goto bad_option;
270 }
271 channel_add_permitted_opens(patterns, port);
272 xfree(patterns);
273 goto next_option;
274 }
221next_option: 275next_option:
222 /* 276 /*
223 * Skip the comma, and move to the next option 277 * Skip the comma, and move to the next option
diff --git a/channels.c b/channels.c
index bb872dc94..941556ace 100644
--- a/channels.c
+++ b/channels.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: channels.c,v 1.98 2001/03/04 17:42:28 millert Exp $"); 43RCSID("$OpenBSD: channels.c,v 1.99 2001/03/16 19:06:29 markus Exp $");
44 44
45#include <openssl/rsa.h> 45#include <openssl/rsa.h>
46#include <openssl/dsa.h> 46#include <openssl/dsa.h>
@@ -141,18 +141,6 @@ channel_set_options(int hostname_in_open)
141 have_hostname_in_open = hostname_in_open; 141 have_hostname_in_open = hostname_in_open;
142} 142}
143 143
144/*
145 * Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually
146 * called by the server, because the user could connect to any port anyway,
147 * and the server has no way to know but to trust the client anyway.
148 */
149
150void
151channel_permit_all_opens()
152{
153 all_opens_permitted = 1;
154}
155
156/* lookup channel by id */ 144/* lookup channel by id */
157 145
158Channel * 146Channel *
@@ -1791,9 +1779,47 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
1791 xfree(hostname); 1779 xfree(hostname);
1792} 1780}
1793 1781
1794/* XXX move to aux.c */ 1782/*
1783 * Permits opening to any host/port if permitted_opens[] is empty. This is
1784 * usually called by the server, because the user could connect to any port
1785 * anyway, and the server has no way to know but to trust the client anyway.
1786 */
1787void
1788channel_permit_all_opens()
1789{
1790 if (num_permitted_opens == 0)
1791 all_opens_permitted = 1;
1792}
1793
1794void
1795channel_add_permitted_opens(char *host, int port)
1796{
1797 if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
1798 fatal("channel_request_remote_forwarding: too many forwards");
1799 debug("allow port forwarding to host %s port %d", host, port);
1800
1801 permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);
1802 permitted_opens[num_permitted_opens].port_to_connect = port;
1803 num_permitted_opens++;
1804
1805 all_opens_permitted = 0;
1806}
1807
1808void
1809channel_clear_permitted_opens(void)
1810{
1811 int i;
1812
1813 for (i = 0; i < num_permitted_opens; i++)
1814 xfree(permitted_opens[i].host_to_connect);
1815 num_permitted_opens = 0;
1816
1817}
1818
1819
1820/* return socket to remote host, port */
1795int 1821int
1796channel_connect_to(const char *host, u_short host_port) 1822connect_to(const char *host, u_short port)
1797{ 1823{
1798 struct addrinfo hints, *ai, *aitop; 1824 struct addrinfo hints, *ai, *aitop;
1799 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 1825 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
@@ -1803,9 +1829,10 @@ channel_connect_to(const char *host, u_short host_port)
1803 memset(&hints, 0, sizeof(hints)); 1829 memset(&hints, 0, sizeof(hints));
1804 hints.ai_family = IPv4or6; 1830 hints.ai_family = IPv4or6;
1805 hints.ai_socktype = SOCK_STREAM; 1831 hints.ai_socktype = SOCK_STREAM;
1806 snprintf(strport, sizeof strport, "%d", host_port); 1832 snprintf(strport, sizeof strport, "%d", port);
1807 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { 1833 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
1808 error("%.100s: unknown host (%s)", host, gai_strerror(gaierr)); 1834 error("connect_to %.100s: unknown host (%s)", host,
1835 gai_strerror(gaierr));
1809 return -1; 1836 return -1;
1810 } 1837 }
1811 for (ai = aitop; ai; ai = ai->ai_next) { 1838 for (ai = aitop; ai; ai = ai->ai_next) {
@@ -1813,10 +1840,9 @@ channel_connect_to(const char *host, u_short host_port)
1813 continue; 1840 continue;
1814 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), 1841 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
1815 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { 1842 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
1816 error("channel_connect_to: getnameinfo failed"); 1843 error("connect_to: getnameinfo failed");
1817 continue; 1844 continue;
1818 } 1845 }
1819 /* Create the socket. */
1820 sock = socket(ai->ai_family, SOCK_STREAM, 0); 1846 sock = socket(ai->ai_family, SOCK_STREAM, 0);
1821 if (sock < 0) { 1847 if (sock < 0) {
1822 error("socket: %.100s", strerror(errno)); 1848 error("socket: %.100s", strerror(errno));
@@ -1824,10 +1850,9 @@ channel_connect_to(const char *host, u_short host_port)
1824 } 1850 }
1825 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) 1851 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
1826 fatal("connect_to: F_SETFL: %s", strerror(errno)); 1852 fatal("connect_to: F_SETFL: %s", strerror(errno));
1827 /* Connect to the host/port. */
1828 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 && 1853 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 &&
1829 errno != EINPROGRESS) { 1854 errno != EINPROGRESS) {
1830 error("connect %.100s port %s: %.100s", ntop, strport, 1855 error("connect_to %.100s port %s: %.100s", ntop, strport,
1831 strerror(errno)); 1856 strerror(errno));
1832 close(sock); 1857 close(sock);
1833 continue; /* fail -- try next */ 1858 continue; /* fail -- try next */
@@ -1837,19 +1862,21 @@ channel_connect_to(const char *host, u_short host_port)
1837 } 1862 }
1838 freeaddrinfo(aitop); 1863 freeaddrinfo(aitop);
1839 if (!ai) { 1864 if (!ai) {
1840 error("connect %.100s port %d: failed.", host, host_port); 1865 error("connect_to %.100s port %d: failed.", host, port);
1841 return -1; 1866 return -1;
1842 } 1867 }
1843 /* success */ 1868 /* success */
1844 return sock; 1869 return sock;
1845} 1870}
1871
1846int 1872int
1847channel_connect_by_listen_adress(u_short listen_port) 1873channel_connect_by_listen_adress(u_short listen_port)
1848{ 1874{
1849 int i; 1875 int i;
1876
1850 for (i = 0; i < num_permitted_opens; i++) 1877 for (i = 0; i < num_permitted_opens; i++)
1851 if (permitted_opens[i].listen_port == listen_port) 1878 if (permitted_opens[i].listen_port == listen_port)
1852 return channel_connect_to( 1879 return connect_to(
1853 permitted_opens[i].host_to_connect, 1880 permitted_opens[i].host_to_connect,
1854 permitted_opens[i].port_to_connect); 1881 permitted_opens[i].port_to_connect);
1855 error("WARNING: Server requests forwarding for unknown listen_port %d", 1882 error("WARNING: Server requests forwarding for unknown listen_port %d",
@@ -1857,6 +1884,28 @@ channel_connect_by_listen_adress(u_short listen_port)
1857 return -1; 1884 return -1;
1858} 1885}
1859 1886
1887/* Check if connecting to that port is permitted and connect. */
1888int
1889channel_connect_to(const char *host, u_short port)
1890{
1891 int i, permit;
1892
1893 permit = all_opens_permitted;
1894 if (!permit) {
1895 for (i = 0; i < num_permitted_opens; i++)
1896 if (permitted_opens[i].port_to_connect == port &&
1897 strcmp(permitted_opens[i].host_to_connect, host) == 0)
1898 permit = 1;
1899
1900 }
1901 if (!permit) {
1902 log("Received request to connect to host %.100s port %d, "
1903 "but the request was denied.", host, port);
1904 return -1;
1905 }
1906 return connect_to(host, port);
1907}
1908
1860/* 1909/*
1861 * This is called after receiving PORT_OPEN message. This attempts to 1910 * This is called after receiving PORT_OPEN message. This attempts to
1862 * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION 1911 * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION
@@ -1868,55 +1917,25 @@ channel_input_port_open(int type, int plen, void *ctxt)
1868{ 1917{
1869 u_short host_port; 1918 u_short host_port;
1870 char *host, *originator_string; 1919 char *host, *originator_string;
1871 int remote_channel, sock = -1, newch, i, denied; 1920 int remote_channel, sock = -1, newch;
1872 u_int host_len, originator_len;
1873 1921
1874 /* Get remote channel number. */
1875 remote_channel = packet_get_int(); 1922 remote_channel = packet_get_int();
1876 1923 host = packet_get_string(NULL);
1877 /* Get host name to connect to. */
1878 host = packet_get_string(&host_len);
1879
1880 /* Get port to connect to. */
1881 host_port = packet_get_int(); 1924 host_port = packet_get_int();
1882 1925
1883 /* Get remote originator name. */
1884 if (have_hostname_in_open) { 1926 if (have_hostname_in_open) {
1885 originator_string = packet_get_string(&originator_len); 1927 originator_string = packet_get_string(NULL);
1886 originator_len += 4; /* size of packet_int */
1887 } else { 1928 } else {
1888 originator_string = xstrdup("unknown (remote did not supply name)"); 1929 originator_string = xstrdup("unknown (remote did not supply name)");
1889 originator_len = 0; /* no originator supplied */
1890 }
1891
1892 packet_integrity_check(plen,
1893 4 + 4 + host_len + 4 + originator_len, SSH_MSG_PORT_OPEN);
1894
1895 /* Check if opening that port is permitted. */
1896 denied = 0;
1897 if (!all_opens_permitted) {
1898 /* Go trough all permitted ports. */
1899 for (i = 0; i < num_permitted_opens; i++)
1900 if (permitted_opens[i].port_to_connect == host_port &&
1901 strcmp(permitted_opens[i].host_to_connect, host) == 0)
1902 break;
1903
1904 /* Check if we found the requested port among those permitted. */
1905 if (i >= num_permitted_opens) {
1906 /* The port is not permitted. */
1907 log("Received request to connect to %.100s:%d, but the request was denied.",
1908 host, host_port);
1909 denied = 1;
1910 }
1911 } 1930 }
1912 sock = denied ? -1 : channel_connect_to(host, host_port); 1931 packet_done();
1913 if (sock > 0) { 1932 sock = channel_connect_to(host, host_port);
1914 /* Allocate a channel for this connection. */ 1933 if (sock != -1) {
1915 newch = channel_allocate(SSH_CHANNEL_CONNECTING, 1934 newch = channel_allocate(SSH_CHANNEL_CONNECTING,
1916 sock, originator_string); 1935 sock, originator_string);
1917/*XXX delay answer? */
1918 channels[newch].remote_id = remote_channel; 1936 channels[newch].remote_id = remote_channel;
1919 1937
1938 /*XXX delay answer? */
1920 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 1939 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1921 packet_put_int(remote_channel); 1940 packet_put_int(remote_channel);
1922 packet_put_int(newch); 1941 packet_put_int(newch);
diff --git a/channels.h b/channels.h
index f57029a14..493b04aa2 100644
--- a/channels.h
+++ b/channels.h
@@ -32,11 +32,13 @@
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35/* RCSID("$OpenBSD: channels.h,v 1.27 2001/02/15 23:19:59 markus Exp $"); */ 35/* RCSID("$OpenBSD: channels.h,v 1.28 2001/03/16 19:06:29 markus Exp $"); */
36 36
37#ifndef CHANNELS_H 37#ifndef CHANNELS_H
38#define CHANNELS_H 38#define CHANNELS_H
39 39
40#include "buffer.h"
41
40/* Definitions for channel types. */ 42/* Definitions for channel types. */
41#define SSH_CHANNEL_FREE 0 /* This channel is free (unused). */ 43#define SSH_CHANNEL_FREE 0 /* This channel is free (unused). */
42#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */ 44#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */
@@ -226,12 +228,18 @@ channel_request_remote_forwarding(u_short port, const char *host,
226 u_short remote_port); 228 u_short remote_port);
227 229
228/* 230/*
229 * Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually 231 * Permits opening to any host/port if permitted_opens[] is empty. This is
230 * called by the server, because the user could connect to any port anyway, 232 * usually called by the server, because the user could connect to any port
231 * and the server has no way to know but to trust the client anyway. 233 * anyway, and the server has no way to know but to trust the client anyway.
232 */ 234 */
233void channel_permit_all_opens(void); 235void channel_permit_all_opens(void);
234 236
237/* Add host/port to list of allowed targets for port forwarding */
238void channel_add_permitted_opens(char *host, int port);
239
240/* Flush list */
241void channel_clear_permitted_opens(void);
242
235/* 243/*
236 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates 244 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
237 * listening for the port, and sends back a success reply (or disconnect 245 * listening for the port, and sends back a success reply (or disconnect
diff --git a/serverloop.c b/serverloop.c
index 8b1ee9919..66bc52573 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.54 2001/03/04 01:46:30 djm Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.55 2001/03/16 19:06:29 markus Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "packet.h" 41#include "packet.h"
@@ -756,11 +756,6 @@ server_request_direct_tcpip(char *ctype)
756 originator, originator_port, target, target_port); 756 originator, originator_port, target, target_port);
757 757
758 /* XXX check permission */ 758 /* XXX check permission */
759 if (no_port_forwarding_flag || !options.allow_tcp_forwarding) {
760 xfree(target);
761 xfree(originator);
762 return NULL;
763 }
764 sock = channel_connect_to(target, target_port); 759 sock = channel_connect_to(target, target_port);
765 xfree(target); 760 xfree(target);
766 xfree(originator); 761 xfree(originator);
@@ -858,6 +853,7 @@ server_input_global_request(int type, int plen, void *ctxt)
858 want_reply = packet_get_char(); 853 want_reply = packet_get_char();
859 debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply); 854 debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply);
860 855
856 /* -R style forwarding */
861 if (strcmp(rtype, "tcpip-forward") == 0) { 857 if (strcmp(rtype, "tcpip-forward") == 0) {
862 struct passwd *pw; 858 struct passwd *pw;
863 char *listen_address; 859 char *listen_address;
diff --git a/session.c b/session.c
index 5e6926b56..9c4828ac7 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
33 */ 33 */
34 34
35#include "includes.h" 35#include "includes.h"
36RCSID("$OpenBSD: session.c,v 1.60 2001/03/15 22:07:08 markus Exp $"); 36RCSID("$OpenBSD: session.c,v 1.61 2001/03/16 19:06:30 markus Exp $");
37 37
38#include "ssh.h" 38#include "ssh.h"
39#include "ssh1.h" 39#include "ssh1.h"
@@ -228,13 +228,6 @@ do_authenticated(struct passwd * pw)
228 startup_pipe = -1; 228 startup_pipe = -1;
229 } 229 }
230 230
231 /*
232 * Inform the channel mechanism that we are the server side and that
233 * the client may request to connect to any port at all. (The user
234 * could do it anyway, and we wouldn\'t know what is permitted except
235 * by the client telling us, so we can equally well trust the client
236 * not to request anything bogus.)
237 */
238 if (!no_port_forwarding_flag && options.allow_tcp_forwarding) 231 if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
239 channel_permit_all_opens(); 232 channel_permit_all_opens();
240 233
@@ -2037,6 +2030,8 @@ do_authenticated2(Authctxt *authctxt)
2037 close(startup_pipe); 2030 close(startup_pipe);
2038 startup_pipe = -1; 2031 startup_pipe = -1;
2039 } 2032 }
2033 if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
2034 channel_permit_all_opens();
2040#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD) 2035#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD)
2041 if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) { 2036 if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) {
2042 error("unable to get login class"); 2037 error("unable to get login class");