summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-04-08 18:30:26 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-04-08 18:30:26 +0000
commit3bb4f9da7382e62dc08eb72ba8307c28d4ccc566 (patch)
tree543bfbb95923d8b21e28086d1d60641a8d4f8f28
parent3fcf1a22b52ed8e66d2cf548d5d4528f67377af9 (diff)
- markus@cvs.openbsd.org 2001/04/07 08:55:18
[buffer.c channels.c channels.h readconf.c ssh.c] allow the ssh client act as a SOCKS4 proxy (dynamic local portforwarding). work by Dan Kaminsky <dankamin@cisco.com> and me. thanks to Dan for this great patch: use 'ssh -D 1080 host' and make netscape use localhost:1080 as a socks proxy.
-rw-r--r--ChangeLog8
-rw-r--r--buffer.c4
-rw-r--r--channels.c228
-rw-r--r--channels.h5
-rw-r--r--readconf.c17
-rw-r--r--ssh.c13
6 files changed, 220 insertions, 55 deletions
diff --git a/ChangeLog b/ChangeLog
index 943f146b6..c54b07cae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,12 @@
15 do gid/groups-swap in addition to uid-swap, should help if /home/group 15 do gid/groups-swap in addition to uid-swap, should help if /home/group
16 is chmod 750 + chgrp grp /home/group/, work be deraadt and me, thanks 16 is chmod 750 + chgrp grp /home/group/, work be deraadt and me, thanks
17 to olar@openwall.com is comments. we had many requests for this. 17 to olar@openwall.com is comments. we had many requests for this.
18 - markus@cvs.openbsd.org 2001/04/07 08:55:18
19 [buffer.c channels.c channels.h readconf.c ssh.c]
20 allow the ssh client act as a SOCKS4 proxy (dynamic local
21 portforwarding). work by Dan Kaminsky <dankamin@cisco.com> and me.
22 thanks to Dan for this great patch: use 'ssh -D 1080 host' and make
23 netscape use localhost:1080 as a socks proxy.
18 24
1920010408 2520010408
20 - OpenBSD CVS Sync 26 - OpenBSD CVS Sync
@@ -4955,4 +4961,4 @@
4955 - Wrote replacements for strlcpy and mkdtemp 4961 - Wrote replacements for strlcpy and mkdtemp
4956 - Released 1.0pre1 4962 - Released 1.0pre1
4957 4963
4958$Id: ChangeLog,v 1.1083 2001/04/08 18:26:59 mouring Exp $ 4964$Id: ChangeLog,v 1.1084 2001/04/08 18:30:26 mouring Exp $
diff --git a/buffer.c b/buffer.c
index 68696fd3f..377d0c09f 100644
--- a/buffer.c
+++ b/buffer.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: buffer.c,v 1.11 2001/04/05 21:02:46 markus Exp $"); 15RCSID("$OpenBSD: buffer.c,v 1.12 2001/04/07 08:55:15 markus Exp $");
16 16
17#include "xmalloc.h" 17#include "xmalloc.h"
18#include "buffer.h" 18#include "buffer.h"
@@ -156,5 +156,5 @@ buffer_dump(Buffer *buffer)
156 156
157 for (i = buffer->offset; i < buffer->end; i++) 157 for (i = buffer->offset; i < buffer->end; i++)
158 fprintf(stderr, " %02x", ucp[i]); 158 fprintf(stderr, " %02x", ucp[i]);
159 fprintf(stderr, "\n"); 159 fprintf(stderr, "\r\n");
160} 160}
diff --git a/channels.c b/channels.c
index d5526fb83..0e334db88 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.102 2001/04/06 21:00:10 markus Exp $"); 43RCSID("$OpenBSD: channels.c,v 1.103 2001/04/07 08:55:17 markus Exp $");
44 44
45#include <openssl/rsa.h> 45#include <openssl/rsa.h>
46#include <openssl/dsa.h> 46#include <openssl/dsa.h>
@@ -51,6 +51,7 @@ RCSID("$OpenBSD: channels.c,v 1.102 2001/04/06 21:00:10 markus Exp $");
51#include "packet.h" 51#include "packet.h"
52#include "xmalloc.h" 52#include "xmalloc.h"
53#include "buffer.h" 53#include "buffer.h"
54#include "bufaux.h"
54#include "uidswap.h" 55#include "uidswap.h"
55#include "log.h" 56#include "log.h"
56#include "misc.h" 57#include "misc.h"
@@ -133,6 +134,8 @@ static int have_hostname_in_open = 0;
133/* AF_UNSPEC or AF_INET or AF_INET6 */ 134/* AF_UNSPEC or AF_INET or AF_INET6 */
134extern int IPv4or6; 135extern int IPv4or6;
135 136
137void port_open_helper(Channel *c, char *rtype);
138
136/* Sets specific protocol options. */ 139/* Sets specific protocol options. */
137 140
138void 141void
@@ -539,6 +542,89 @@ channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
539 } 542 }
540} 543}
541 544
545#define SSH_SOCKS_HEAD 1+1+2+4
546
547void
548channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
549{
550 u_char *p, *host;
551 int len, i, done, have;
552 char username[256];
553 struct {
554 u_int8_t version;
555 u_int8_t command;
556 u_int16_t dest_port;
557 struct in_addr dest_ip;
558 } s4_req, s4_rsp;
559
560 have = buffer_len(&c->input);
561
562 debug("channel %d: pre_dynamic have: %d", c->self, have);
563 /*buffer_dump(&c->input);*/
564
565 /* Check if the fixed size part of the packet is in buffer. */
566 if (have < SSH_SOCKS_HEAD + 1) {
567 /* need more */
568 FD_SET(c->sock, readset);
569 return;
570 }
571 /* Check for end of username */
572 p = buffer_ptr(&c->input);
573 done = 0;
574 for (i = SSH_SOCKS_HEAD; i < have; i++) {
575 if (p[i] == '\0') {
576 done = 1;
577 break;
578 }
579 }
580 if (!done) {
581 /* need more */
582 FD_SET(c->sock, readset);
583 return;
584 }
585 buffer_get(&c->input, (char *)&s4_req.version, 1);
586 buffer_get(&c->input, (char *)&s4_req.command, 1);
587 buffer_get(&c->input, (char *)&s4_req.dest_port, 2);
588 buffer_get(&c->input, (char *)&s4_req.dest_ip, 4);
589 p = buffer_ptr(&c->input);
590 len = strlen(p);
591 have = buffer_len(&c->input);
592 debug2("channel %d: pre_dynamic user: %s/%d", c->self, p, len);
593 if (len > have)
594 fatal("channel %d: pre_dynamic: len %d > have %d",
595 c->self, len, have);
596 strlcpy(username, p, sizeof(username));
597 buffer_consume(&c->input, len);
598 buffer_consume(&c->input, 1); /* trailing '\0' */
599
600 host = inet_ntoa(s4_req.dest_ip);
601 strlcpy(c->path, host, sizeof(c->path));
602 c->host_port = ntohs(s4_req.dest_port);
603
604 debug("channel %d: dynamic request received: "
605 "socks%x://%s@%s:%u/command?%u",
606 c->self, s4_req.version, username, host, c->host_port,
607 s4_req.command);
608
609 if ((s4_req.version != 4) || (s4_req.command != 1)) {
610 debug("channel %d: cannot handle: socks VN %d CN %d",
611 c->self, s4_req.version, s4_req.command);
612 channel_free(c->self);
613 return;
614 }
615
616 s4_rsp.version = 0; /* VN: version of reply code */
617 s4_rsp.command = 90; /* CD: request granted */
618 s4_rsp.dest_port = 0; /* ignored */
619 s4_rsp.dest_ip.s_addr = INADDR_ANY; /* ignored */
620 buffer_append(&c->output, (char *)&s4_rsp, sizeof(s4_rsp));
621
622 /* switch to next state */
623 c->type = SSH_CHANNEL_OPENING;
624 port_open_helper(c, "direct-tcpip");
625}
626
627
542/* This is our fake X11 server socket. */ 628/* This is our fake X11 server socket. */
543void 629void
544channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) 630channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
@@ -591,73 +677,100 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
591 } 677 }
592} 678}
593 679
680void
681port_open_helper(Channel *c, char *rtype)
682{
683 int direct;
684 char buf[1024];
685 char *remote_ipaddr = get_peer_ipaddr(c->sock);
686 u_short remote_port = get_peer_port(c->sock);
687
688 direct = (strcmp(rtype, "direct-tcpip") == 0);
689
690 snprintf(buf, sizeof buf,
691 "%s: listening port %d for %.100s port %d, "
692 "connect from %.200s port %d",
693 rtype, c->listening_port, c->path, c->host_port,
694 remote_ipaddr, remote_port);
695
696 xfree(c->remote_name);
697 c->remote_name = xstrdup(buf);
698
699 if (compat20) {
700 packet_start(SSH2_MSG_CHANNEL_OPEN);
701 packet_put_cstring(rtype);
702 packet_put_int(c->self);
703 packet_put_int(c->local_window_max);
704 packet_put_int(c->local_maxpacket);
705 if (direct) {
706 /* target host, port */
707 packet_put_cstring(c->path);
708 packet_put_int(c->host_port);
709 } else {
710 /* listen address, port */
711 packet_put_cstring(c->path);
712 packet_put_int(c->listening_port);
713 }
714 /* originator host and port */
715 packet_put_cstring(remote_ipaddr);
716 packet_put_int(remote_port);
717 packet_send();
718 } else {
719 packet_start(SSH_MSG_PORT_OPEN);
720 packet_put_int(c->self);
721 packet_put_cstring(c->path);
722 packet_put_int(c->host_port);
723 if (have_hostname_in_open)
724 packet_put_cstring(c->remote_name);
725 packet_send();
726 }
727 xfree(remote_ipaddr);
728}
729
594/* 730/*
595 * This socket is listening for connections to a forwarded TCP/IP port. 731 * This socket is listening for connections to a forwarded TCP/IP port.
596 */ 732 */
597void 733void
598channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset) 734channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
599{ 735{
736 Channel *nc;
600 struct sockaddr addr; 737 struct sockaddr addr;
601 int newsock, newch; 738 int newsock, newch, nextstate;
602 socklen_t addrlen; 739 socklen_t addrlen;
603 char buf[1024], *remote_ipaddr, *rtype; 740 char *rtype;
604 int remote_port;
605
606 rtype = (c->type == SSH_CHANNEL_RPORT_LISTENER) ?
607 "forwarded-tcpip" : "direct-tcpip";
608 741
609 if (FD_ISSET(c->sock, readset)) { 742 if (FD_ISSET(c->sock, readset)) {
610 debug("Connection to port %d forwarding " 743 debug("Connection to port %d forwarding "
611 "to %.100s port %d requested.", 744 "to %.100s port %d requested.",
612 c->listening_port, c->path, c->host_port); 745 c->listening_port, c->path, c->host_port);
746
747 rtype = (c->type == SSH_CHANNEL_RPORT_LISTENER) ?
748 "forwarded-tcpip" : "direct-tcpip";
749 nextstate = (c->host_port == 0) ? SSH_CHANNEL_DYNAMIC :
750 SSH_CHANNEL_OPENING;
751
613 addrlen = sizeof(addr); 752 addrlen = sizeof(addr);
614 newsock = accept(c->sock, &addr, &addrlen); 753 newsock = accept(c->sock, &addr, &addrlen);
615 if (newsock < 0) { 754 if (newsock < 0) {
616 error("accept: %.100s", strerror(errno)); 755 error("accept: %.100s", strerror(errno));
617 return; 756 return;
618 } 757 }
619 remote_ipaddr = get_peer_ipaddr(newsock);
620 remote_port = get_peer_port(newsock);
621 snprintf(buf, sizeof buf,
622 "listen port %d for %.100s port %d, "
623 "connect from %.200s port %d",
624 c->listening_port, c->path, c->host_port,
625 remote_ipaddr, remote_port);
626
627 newch = channel_new(rtype, 758 newch = channel_new(rtype,
628 SSH_CHANNEL_OPENING, newsock, newsock, -1, 759 nextstate, newsock, newsock, -1,
629 c->local_window_max, c->local_maxpacket, 760 c->local_window_max, c->local_maxpacket,
630 0, xstrdup(buf), 1); 761 0, xstrdup(rtype), 1);
631 if (compat20) { 762
632 packet_start(SSH2_MSG_CHANNEL_OPEN); 763 nc = channel_lookup(newch);
633 packet_put_cstring(rtype); 764 if (nc == NULL) {
634 packet_put_int(newch); 765 error("xxx: no new channel:");
635 packet_put_int(c->local_window_max); 766 return;
636 packet_put_int(c->local_maxpacket);
637 if (c->type == SSH_CHANNEL_RPORT_LISTENER) {
638 /* listen address, port */
639 packet_put_string(c->path, strlen(c->path));
640 packet_put_int(c->listening_port);
641 } else {
642 /* target host, port */
643 packet_put_string(c->path, strlen(c->path));
644 packet_put_int(c->host_port);
645 }
646 /* originator host and port */
647 packet_put_cstring(remote_ipaddr);
648 packet_put_int(remote_port);
649 packet_send();
650 } else {
651 packet_start(SSH_MSG_PORT_OPEN);
652 packet_put_int(newch);
653 packet_put_string(c->path, strlen(c->path));
654 packet_put_int(c->host_port);
655 if (have_hostname_in_open) {
656 packet_put_string(buf, strlen(buf));
657 }
658 packet_send();
659 } 767 }
660 xfree(remote_ipaddr); 768 nc->listening_port = c->listening_port;
769 nc->host_port = c->host_port;
770 strlcpy(nc->path, c->path, sizeof(nc->path));
771
772 if (nextstate != SSH_CHANNEL_DYNAMIC)
773 port_open_helper(nc, rtype);
661 } 774 }
662} 775}
663 776
@@ -733,6 +846,15 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
733 if (len <= 0) { 846 if (len <= 0) {
734 debug("channel %d: read<=0 rfd %d len %d", 847 debug("channel %d: read<=0 rfd %d len %d",
735 c->self, c->rfd, len); 848 c->self, c->rfd, len);
849 if (c->type == SSH_CHANNEL_DYNAMIC) {
850 /*
851 * we are not yet connected to a remote peer,
852 * so the connection-close protocol won't work
853 */
854 debug("channel %d: dynamic: closed", c->self);
855 channel_free(c->self);
856 return -1;
857 }
736 if (compat13) { 858 if (compat13) {
737 buffer_consume(&c->output, buffer_len(&c->output)); 859 buffer_consume(&c->output, buffer_len(&c->output));
738 c->type = SSH_CHANNEL_INPUT_DRAINING; 860 c->type = SSH_CHANNEL_INPUT_DRAINING;
@@ -894,6 +1016,12 @@ channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)
894} 1016}
895 1017
896void 1018void
1019channel_post_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
1020{
1021 channel_handle_rfd(c, readset, writeset);
1022}
1023
1024void
897channel_handler_init_20(void) 1025channel_handler_init_20(void)
898{ 1026{
899 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20; 1027 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20;
@@ -903,6 +1031,7 @@ channel_handler_init_20(void)
903 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; 1031 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
904 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; 1032 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
905 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; 1033 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
1034 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
906 1035
907 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2; 1036 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2;
908 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; 1037 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
@@ -910,6 +1039,7 @@ channel_handler_init_20(void)
910 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; 1039 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
911 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; 1040 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
912 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; 1041 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
1042 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_dynamic;
913} 1043}
914 1044
915void 1045void
@@ -923,6 +1053,7 @@ channel_handler_init_13(void)
923 channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining; 1053 channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining;
924 channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; 1054 channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining;
925 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; 1055 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
1056 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
926 1057
927 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; 1058 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1;
928 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; 1059 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
@@ -930,6 +1061,7 @@ channel_handler_init_13(void)
930 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; 1061 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
931 channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; 1062 channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13;
932 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; 1063 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
1064 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_dynamic;
933} 1065}
934 1066
935void 1067void
@@ -941,12 +1073,14 @@ channel_handler_init_15(void)
941 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; 1073 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
942 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; 1074 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
943 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; 1075 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
1076 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
944 1077
945 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; 1078 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
946 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; 1079 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
947 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; 1080 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
948 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; 1081 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1;
949 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; 1082 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
1083 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_dynamic;
950} 1084}
951 1085
952void 1086void
@@ -1500,6 +1634,7 @@ channel_still_open()
1500 case SSH_CHANNEL_RPORT_LISTENER: 1634 case SSH_CHANNEL_RPORT_LISTENER:
1501 case SSH_CHANNEL_CLOSED: 1635 case SSH_CHANNEL_CLOSED:
1502 case SSH_CHANNEL_AUTH_SOCKET: 1636 case SSH_CHANNEL_AUTH_SOCKET:
1637 case SSH_CHANNEL_DYNAMIC:
1503 case SSH_CHANNEL_CONNECTING: /* XXX ??? */ 1638 case SSH_CHANNEL_CONNECTING: /* XXX ??? */
1504 continue; 1639 continue;
1505 case SSH_CHANNEL_LARVAL: 1640 case SSH_CHANNEL_LARVAL:
@@ -1551,6 +1686,7 @@ channel_open_message()
1551 case SSH_CHANNEL_LARVAL: 1686 case SSH_CHANNEL_LARVAL:
1552 case SSH_CHANNEL_OPENING: 1687 case SSH_CHANNEL_OPENING:
1553 case SSH_CHANNEL_CONNECTING: 1688 case SSH_CHANNEL_CONNECTING:
1689 case SSH_CHANNEL_DYNAMIC:
1554 case SSH_CHANNEL_OPEN: 1690 case SSH_CHANNEL_OPEN:
1555 case SSH_CHANNEL_X11_OPEN: 1691 case SSH_CHANNEL_X11_OPEN:
1556 case SSH_CHANNEL_INPUT_DRAINING: 1692 case SSH_CHANNEL_INPUT_DRAINING:
diff --git a/channels.h b/channels.h
index 2cd82148e..23e6ece83 100644
--- a/channels.h
+++ b/channels.h
@@ -32,7 +32,7 @@
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.29 2001/04/04 20:25:36 markus Exp $"); */ 35/* RCSID("$OpenBSD: channels.h,v 1.30 2001/04/07 08:55:17 markus Exp $"); */
36 36
37#ifndef CHANNELS_H 37#ifndef CHANNELS_H
38#define CHANNELS_H 38#define CHANNELS_H
@@ -53,7 +53,8 @@
53#define SSH_CHANNEL_LARVAL 10 /* larval session */ 53#define SSH_CHANNEL_LARVAL 10 /* larval session */
54#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */ 54#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */
55#define SSH_CHANNEL_CONNECTING 12 55#define SSH_CHANNEL_CONNECTING 12
56#define SSH_CHANNEL_MAX_TYPE 13 56#define SSH_CHANNEL_DYNAMIC 13
57#define SSH_CHANNEL_MAX_TYPE 14
57 58
58/* 59/*
59 * Data structure for channel data. This is iniailized in channel_allocate 60 * Data structure for channel data. This is iniailized in channel_allocate
diff --git a/readconf.c b/readconf.c
index 365f67eb0..007056d4d 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.70 2001/04/02 14:20:23 stevesk Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.71 2001/04/07 08:55:17 markus Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -110,7 +110,7 @@ typedef enum {
110 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 110 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
111 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 111 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
112 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 112 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
113 oPreferredAuthentications 113 oDynamicForward, oPreferredAuthentications
114} OpCodes; 114} OpCodes;
115 115
116/* Textual representations of the tokens. */ 116/* Textual representations of the tokens. */
@@ -172,6 +172,7 @@ static struct {
172 { "keepalive", oKeepAlives }, 172 { "keepalive", oKeepAlives },
173 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 173 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
174 { "loglevel", oLogLevel }, 174 { "loglevel", oLogLevel },
175 { "dynamicforward", oDynamicForward },
175 { "preferredauthentications", oPreferredAuthentications }, 176 { "preferredauthentications", oPreferredAuthentications },
176 { NULL, 0 } 177 { NULL, 0 }
177}; 178};
@@ -583,6 +584,18 @@ parse_int:
583 add_local_forward(options, fwd_port, buf, fwd_host_port); 584 add_local_forward(options, fwd_port, buf, fwd_host_port);
584 break; 585 break;
585 586
587 case oDynamicForward:
588 arg = strdelim(&s);
589 if (!arg || *arg == '\0')
590 fatal("%.200s line %d: Missing port argument.",
591 filename, linenum);
592 if (arg[0] < '0' || arg[0] > '9')
593 fatal("%.200s line %d: Badly formatted port number.",
594 filename, linenum);
595 fwd_port = atoi(arg);
596 add_local_forward(options, fwd_port, "socks4", 0);
597 break;
598
586 case oHost: 599 case oHost:
587 *activep = 0; 600 *activep = 0;
588 while ((arg = strdelim(&s)) != NULL && *arg != '\0') 601 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
diff --git a/ssh.c b/ssh.c
index 294bcf39d..75094a106 100644
--- a/ssh.c
+++ b/ssh.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: ssh.c,v 1.107 2001/04/06 21:00:13 markus Exp $"); 42RCSID("$OpenBSD: ssh.c,v 1.108 2001/04/07 08:55:18 markus Exp $");
43 43
44#include <openssl/evp.h> 44#include <openssl/evp.h>
45#include <openssl/err.h> 45#include <openssl/err.h>
@@ -178,6 +178,9 @@ usage(void)
178 fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n"); 178 fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n");
179 fprintf(stderr, " These cause %s to listen for connections on a port, and\n", __progname); 179 fprintf(stderr, " These cause %s to listen for connections on a port, and\n", __progname);
180 fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); 180 fprintf(stderr, " forward them to the other side by connecting to host:port.\n");
181 fprintf(stderr, " -D port Dynamically forward local port to multiple remote addresses.\n");
182 fprintf(stderr, " Allows SSH to act as an application-layer proxy.\n");
183 fprintf(stderr, " Protocols Supported: SOCKS4\n");
181 fprintf(stderr, " -C Enable compression.\n"); 184 fprintf(stderr, " -C Enable compression.\n");
182 fprintf(stderr, " -N Do not execute a shell or command.\n"); 185 fprintf(stderr, " -N Do not execute a shell or command.\n");
183 fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); 186 fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n");
@@ -314,7 +317,7 @@ main(int ac, char **av)
314 opt = av[optind][1]; 317 opt = av[optind][1];
315 if (!opt) 318 if (!opt)
316 usage(); 319 usage();
317 if (strchr("eilcmpLRo", opt)) { /* options with arguments */ 320 if (strchr("eilcmpLRDo", opt)) { /* options with arguments */
318 optarg = av[optind] + 2; 321 optarg = av[optind] + 2;
319 if (strcmp(optarg, "") == 0) { 322 if (strcmp(optarg, "") == 0) {
320 if (optind >= ac - 1) 323 if (optind >= ac - 1)
@@ -480,6 +483,12 @@ main(int ac, char **av)
480 } 483 }
481 add_local_forward(&options, fwd_port, buf, fwd_host_port); 484 add_local_forward(&options, fwd_port, buf, fwd_host_port);
482 break; 485 break;
486
487 case 'D':
488 fwd_port = atoi(optarg);
489 add_local_forward(&options, fwd_port, "socks4", 0);
490 break;
491
483 case 'C': 492 case 'C':
484 options.compression = 1; 493 options.compression = 1;
485 break; 494 break;