- 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.
This commit is contained in:
parent
9189ff89c3
commit
46471c9a81
|
@ -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 $
|
||||
|
|
120
channels.c
120
channels.c
|
@ -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
6
ssh.1
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue