[channels.c ssh.1 ssh_config.5]
     (re)add socks5 suppport to -D; ok djm@
     now ssh(1) can act both as a socks 4 and socks 5 server and
     dynamically forward ports.
This commit is contained in:
Darren Tucker 2003-07-03 13:55:19 +10:00
parent 9189ff89c3
commit 46471c9a81
4 changed files with 129 additions and 10 deletions

View File

@ -15,6 +15,11 @@
- markus@cvs.openbsd.org 2003/07/02 12:56:34
[channels.c]
deny dynamic forwarding with -R for v1, too; ok djm@
- markus@cvs.openbsd.org 2003/07/02 14:51:16
[channels.c ssh.1 ssh_config.5]
(re)add socks5 suppport to -D; ok djm@
now ssh(1) can act both as a socks 4 and socks 5 server and
dynamically forward ports.
20030630
- (djm) Search for support functions necessary to build our
@ -635,4 +640,4 @@
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
$Id: ChangeLog,v 1.2839 2003/07/03 03:52:04 dtucker Exp $
$Id: ChangeLog,v 1.2840 2003/07/03 03:55:19 dtucker Exp $

View File

@ -39,7 +39,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: channels.c,v 1.192 2003/07/02 12:56:34 markus Exp $");
RCSID("$OpenBSD: channels.c,v 1.193 2003/07/02 14:51:16 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -54,7 +54,7 @@ RCSID("$OpenBSD: channels.c,v 1.192 2003/07/02 12:56:34 markus Exp $");
#include "key.h"
#include "authfd.h"
#include "pathnames.h"
#include "bufaux.h"
/* -- channel core */
@ -941,6 +941,117 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
return 1;
}
/* try to decode a socks5 header */
#define SSH_SOCKS5_AUTHDONE 0x1000
#define SSH_SOCKS5_NOAUTH 0x00
#define SSH_SOCKS5_IPV4 0x01
#define SSH_SOCKS5_DOMAIN 0x03
#define SSH_SOCKS5_IPV6 0x04
#define SSH_SOCKS5_CONNECT 0x01
#define SSH_SOCKS5_SUCCESS 0x00
static int
channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
{
struct {
u_int8_t version;
u_int8_t command;
u_int8_t reserved;
u_int8_t atyp;
} s5_req, s5_rsp;
u_int16_t dest_port;
u_char *p, dest_addr[255+1];
int i, have, found, nmethods, addrlen, af;
debug2("channel %d: decode socks5", c->self);
p = buffer_ptr(&c->input);
if (p[0] != 0x05)
return -1;
have = buffer_len(&c->input);
if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
/* format: ver | nmethods | methods */
if (have < 2)
return 0;
nmethods = p[1];
if (have < nmethods + 2)
return 0;
/* look for method: "NO AUTHENTICATION REQUIRED" */
for (found = 0, i = 2 ; i < nmethods + 2; i++) {
if (p[i] == SSH_SOCKS5_NOAUTH ) {
found = 1;
break;
}
}
if (!found) {
debug("channel %d: method SSH_SOCKS5_NOAUTH not found",
c->self);
return -1;
}
buffer_consume(&c->input, nmethods + 2);
buffer_put_char(&c->output, 0x05); /* version */
buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */
FD_SET(c->sock, writeset);
c->flags |= SSH_SOCKS5_AUTHDONE;
debug2("channel %d: socks5 auth done", c->self);
return 0; /* need more */
}
debug2("channel %d: socks5 post auth", c->self);
if (have < sizeof(s5_req)+1)
return 0; /* need more */
memcpy((char *)&s5_req, p, sizeof(s5_req));
if (s5_req.version != 0x05 ||
s5_req.command != SSH_SOCKS5_CONNECT ||
s5_req.reserved != 0x00) {
debug("channel %d: only socks5 connect supported", c->self);
return -1;
}
switch(s5_req.atyp){
case SSH_SOCKS5_IPV4:
addrlen = 4;
af = AF_INET;
break;
case SSH_SOCKS5_DOMAIN:
addrlen = p[sizeof(s5_req)];
af = -1;
break;
case SSH_SOCKS5_IPV6:
addrlen = 16;
af = AF_INET6;
break;
default:
debug("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
return -1;
}
if (have < 4 + addrlen + 2)
return 0;
buffer_consume(&c->input, sizeof(s5_req));
if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
buffer_consume(&c->input, 1); /* host string length */
buffer_get(&c->input, (char *)&dest_addr, addrlen);
buffer_get(&c->input, (char *)&dest_port, 2);
dest_addr[addrlen] = '\0';
if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
strlcpy(c->path, dest_addr, sizeof(c->path));
else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)
return -1;
c->host_port = ntohs(dest_port);
debug("channel %d: dynamic request: socks5 host %s port %u command %u",
c->self, c->path, c->host_port, s5_req.command);
s5_rsp.version = 0x05;
s5_rsp.command = SSH_SOCKS5_SUCCESS;
s5_rsp.reserved = 0; /* ignored */
s5_rsp.atyp = SSH_SOCKS5_IPV4;
((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY;
dest_port = 0; /* ignored */
buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp));
buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr));
buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port));
return 1;
}
/* dynamic port forwarding */
static void
channel_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)
debug2("channel %d: pre_dynamic: have %d", c->self, have);
/* buffer_dump(&c->input); */
/* check if the fixed size part of the packet is in buffer. */
if (have < 4) {
if (have < 3) {
/* need more */
FD_SET(c->sock, readset);
return;
@ -964,6 +1075,9 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
case 0x04:
ret = channel_decode_socks4(c, readset, writeset);
break;
case 0x05:
ret = channel_decode_socks5(c, readset, writeset);
break;
default:
ret = -1;
break;

6
ssh.1
View File

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh.1,v 1.173 2003/06/10 09:12:11 jmc Exp $
.\" $OpenBSD: ssh.1,v 1.174 2003/07/02 14:51:16 markus Exp $
.Dd September 25, 1999
.Dt SSH 1
.Os
@ -649,9 +649,9 @@ on the local side, and whenever a connection is made to this port, the
connection is forwarded over the secure channel, and the application
protocol is then used to determine where to connect to from the
remote machine.
Currently the SOCKS4 protocol is supported, and
Currently the SOCKS4 and SOCKS5 protocols are supported, and
.Nm
will act as a SOCKS4 server.
will act as a SOCKS server.
Only root can forward privileged ports.
Dynamic port forwardings can also be specified in the configuration file.
.It Fl 1

View File

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh_config.5,v 1.14 2003/06/23 09:02:44 markus Exp $
.\" $OpenBSD: ssh_config.5,v 1.15 2003/07/02 14:51:16 markus Exp $
.Dd September 25, 1999
.Dt SSH_CONFIG 5
.Os
@ -246,9 +246,9 @@ over the secure channel, and the application
protocol is then used to determine where to connect to from the
remote machine.
The argument must be a port number.
Currently the SOCKS4 protocol is supported, and
Currently the SOCKS4 and SOCKS5 protocols are supported, and
.Nm ssh
will act as a SOCKS4 server.
will act as a SOCKS server.
Multiple forwardings may be specified, and
additional forwardings can be given on the command line.
Only the superuser can forward privileged ports.