summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--channels.c120
-rw-r--r--ssh.16
-rw-r--r--ssh_config.56
4 files changed, 129 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 40cf07d41..9c960f13d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,11 @@
15 - markus@cvs.openbsd.org 2003/07/02 12:56:34 15 - markus@cvs.openbsd.org 2003/07/02 12:56:34
16 [channels.c] 16 [channels.c]
17 deny dynamic forwarding with -R for v1, too; ok djm@ 17 deny dynamic forwarding with -R for v1, too; ok djm@
18 - markus@cvs.openbsd.org 2003/07/02 14:51:16
19 [channels.c ssh.1 ssh_config.5]
20 (re)add socks5 suppport to -D; ok djm@
21 now ssh(1) can act both as a socks 4 and socks 5 server and
22 dynamically forward ports.
18 23
1920030630 2420030630
20 - (djm) Search for support functions necessary to build our 25 - (djm) Search for support functions necessary to build our
@@ -635,4 +640,4 @@
635 - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. 640 - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
636 Report from murple@murple.net, diagnosis from dtucker@zip.com.au 641 Report from murple@murple.net, diagnosis from dtucker@zip.com.au
637 642
638$Id: ChangeLog,v 1.2839 2003/07/03 03:52:04 dtucker Exp $ 643$Id: ChangeLog,v 1.2840 2003/07/03 03:55:19 dtucker Exp $
diff --git a/channels.c b/channels.c
index ce07db5c0..e5b2b8c51 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: channels.c,v 1.192 2003/07/02 12:56:34 markus Exp $"); 42RCSID("$OpenBSD: channels.c,v 1.193 2003/07/02 14:51:16 markus Exp $");
43 43
44#include "ssh.h" 44#include "ssh.h"
45#include "ssh1.h" 45#include "ssh1.h"
@@ -54,7 +54,7 @@ RCSID("$OpenBSD: channels.c,v 1.192 2003/07/02 12:56:34 markus Exp $");
54#include "key.h" 54#include "key.h"
55#include "authfd.h" 55#include "authfd.h"
56#include "pathnames.h" 56#include "pathnames.h"
57 57#include "bufaux.h"
58 58
59/* -- channel core */ 59/* -- channel core */
60 60
@@ -941,6 +941,117 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
941 return 1; 941 return 1;
942} 942}
943 943
944/* try to decode a socks5 header */
945#define SSH_SOCKS5_AUTHDONE 0x1000
946#define SSH_SOCKS5_NOAUTH 0x00
947#define SSH_SOCKS5_IPV4 0x01
948#define SSH_SOCKS5_DOMAIN 0x03
949#define SSH_SOCKS5_IPV6 0x04
950#define SSH_SOCKS5_CONNECT 0x01
951#define SSH_SOCKS5_SUCCESS 0x00
952
953static int
954channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
955{
956 struct {
957 u_int8_t version;
958 u_int8_t command;
959 u_int8_t reserved;
960 u_int8_t atyp;
961 } s5_req, s5_rsp;
962 u_int16_t dest_port;
963 u_char *p, dest_addr[255+1];
964 int i, have, found, nmethods, addrlen, af;
965
966 debug2("channel %d: decode socks5", c->self);
967 p = buffer_ptr(&c->input);
968 if (p[0] != 0x05)
969 return -1;
970 have = buffer_len(&c->input);
971 if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
972 /* format: ver | nmethods | methods */
973 if (have < 2)
974 return 0;
975 nmethods = p[1];
976 if (have < nmethods + 2)
977 return 0;
978 /* look for method: "NO AUTHENTICATION REQUIRED" */
979 for (found = 0, i = 2 ; i < nmethods + 2; i++) {
980 if (p[i] == SSH_SOCKS5_NOAUTH ) {
981 found = 1;
982 break;
983 }
984 }
985 if (!found) {
986 debug("channel %d: method SSH_SOCKS5_NOAUTH not found",
987 c->self);
988 return -1;
989 }
990 buffer_consume(&c->input, nmethods + 2);
991 buffer_put_char(&c->output, 0x05); /* version */
992 buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */
993 FD_SET(c->sock, writeset);
994 c->flags |= SSH_SOCKS5_AUTHDONE;
995 debug2("channel %d: socks5 auth done", c->self);
996 return 0; /* need more */
997 }
998 debug2("channel %d: socks5 post auth", c->self);
999 if (have < sizeof(s5_req)+1)
1000 return 0; /* need more */
1001 memcpy((char *)&s5_req, p, sizeof(s5_req));
1002 if (s5_req.version != 0x05 ||
1003 s5_req.command != SSH_SOCKS5_CONNECT ||
1004 s5_req.reserved != 0x00) {
1005 debug("channel %d: only socks5 connect supported", c->self);
1006 return -1;
1007 }
1008 switch(s5_req.atyp){
1009 case SSH_SOCKS5_IPV4:
1010 addrlen = 4;
1011 af = AF_INET;
1012 break;
1013 case SSH_SOCKS5_DOMAIN:
1014 addrlen = p[sizeof(s5_req)];
1015 af = -1;
1016 break;
1017 case SSH_SOCKS5_IPV6:
1018 addrlen = 16;
1019 af = AF_INET6;
1020 break;
1021 default:
1022 debug("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
1023 return -1;
1024 }
1025 if (have < 4 + addrlen + 2)
1026 return 0;
1027 buffer_consume(&c->input, sizeof(s5_req));
1028 if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
1029 buffer_consume(&c->input, 1); /* host string length */
1030 buffer_get(&c->input, (char *)&dest_addr, addrlen);
1031 buffer_get(&c->input, (char *)&dest_port, 2);
1032 dest_addr[addrlen] = '\0';
1033 if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
1034 strlcpy(c->path, dest_addr, sizeof(c->path));
1035 else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)
1036 return -1;
1037 c->host_port = ntohs(dest_port);
1038
1039 debug("channel %d: dynamic request: socks5 host %s port %u command %u",
1040 c->self, c->path, c->host_port, s5_req.command);
1041
1042 s5_rsp.version = 0x05;
1043 s5_rsp.command = SSH_SOCKS5_SUCCESS;
1044 s5_rsp.reserved = 0; /* ignored */
1045 s5_rsp.atyp = SSH_SOCKS5_IPV4;
1046 ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY;
1047 dest_port = 0; /* ignored */
1048
1049 buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp));
1050 buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr));
1051 buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port));
1052 return 1;
1053}
1054
944/* dynamic port forwarding */ 1055/* dynamic port forwarding */
945static void 1056static void
946channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) 1057channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
@@ -953,7 +1064,7 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
953 debug2("channel %d: pre_dynamic: have %d", c->self, have); 1064 debug2("channel %d: pre_dynamic: have %d", c->self, have);
954 /* buffer_dump(&c->input); */ 1065 /* buffer_dump(&c->input); */
955 /* check if the fixed size part of the packet is in buffer. */ 1066 /* check if the fixed size part of the packet is in buffer. */
956 if (have < 4) { 1067 if (have < 3) {
957 /* need more */ 1068 /* need more */
958 FD_SET(c->sock, readset); 1069 FD_SET(c->sock, readset);
959 return; 1070 return;
@@ -964,6 +1075,9 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
964 case 0x04: 1075 case 0x04:
965 ret = channel_decode_socks4(c, readset, writeset); 1076 ret = channel_decode_socks4(c, readset, writeset);
966 break; 1077 break;
1078 case 0x05:
1079 ret = channel_decode_socks5(c, readset, writeset);
1080 break;
967 default: 1081 default:
968 ret = -1; 1082 ret = -1;
969 break; 1083 break;
diff --git a/ssh.1 b/ssh.1
index defc0e640..8a7d2f428 100644
--- a/ssh.1
+++ b/ssh.1
@@ -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: ssh.1,v 1.173 2003/06/10 09:12:11 jmc Exp $ 37.\" $OpenBSD: ssh.1,v 1.174 2003/07/02 14:51:16 markus Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH 1 39.Dt SSH 1
40.Os 40.Os
@@ -649,9 +649,9 @@ on the local side, and whenever a connection is made to this port, the
649connection is forwarded over the secure channel, and the application 649connection is forwarded over the secure channel, and the application
650protocol is then used to determine where to connect to from the 650protocol is then used to determine where to connect to from the
651remote machine. 651remote machine.
652Currently the SOCKS4 protocol is supported, and 652Currently the SOCKS4 and SOCKS5 protocols are supported, and
653.Nm 653.Nm
654will act as a SOCKS4 server. 654will act as a SOCKS server.
655Only root can forward privileged ports. 655Only root can forward privileged ports.
656Dynamic port forwardings can also be specified in the configuration file. 656Dynamic port forwardings can also be specified in the configuration file.
657.It Fl 1 657.It Fl 1
diff --git a/ssh_config.5 b/ssh_config.5
index 56df3acec..79d05f018 100644
--- a/ssh_config.5
+++ b/ssh_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: ssh_config.5,v 1.14 2003/06/23 09:02:44 markus Exp $ 37.\" $OpenBSD: ssh_config.5,v 1.15 2003/07/02 14:51:16 markus Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH_CONFIG 5 39.Dt SSH_CONFIG 5
40.Os 40.Os
@@ -246,9 +246,9 @@ over the secure channel, and the application
246protocol is then used to determine where to connect to from the 246protocol is then used to determine where to connect to from the
247remote machine. 247remote machine.
248The argument must be a port number. 248The argument must be a port number.
249Currently the SOCKS4 protocol is supported, and 249Currently the SOCKS4 and SOCKS5 protocols are supported, and
250.Nm ssh 250.Nm ssh
251will act as a SOCKS4 server. 251will act as a SOCKS server.
252Multiple forwardings may be specified, and 252Multiple forwardings may be specified, and
253additional forwardings can be given on the command line. 253additional forwardings can be given on the command line.
254Only the superuser can forward privileged ports. 254Only the superuser can forward privileged ports.