mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
Socks5 with 3 args and option socksport
This commit is contained in:
parent
0454c4fa43
commit
c4f569e367
8 changed files with 64 additions and 29 deletions
3
CHANGES
3
CHANGES
|
@ -60,6 +60,9 @@ Features:
|
||||||
|
|
||||||
Added option ai-all (sets AI_ALL flag of getaddrinfo() resolver)
|
Added option ai-all (sets AI_ALL flag of getaddrinfo() resolver)
|
||||||
|
|
||||||
|
Socks5 now also allows syntax without socks port, and supports option
|
||||||
|
socksport.
|
||||||
|
|
||||||
Porting:
|
Porting:
|
||||||
Changes for building and testing on NetBSD
|
Changes for building and testing on NetBSD
|
||||||
|
|
||||||
|
|
|
@ -1110,6 +1110,7 @@ label(ADDRESS_SOCKS5_CONNECT)dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<socks-port
|
||||||
This address type is experimental.nl()
|
This address type is experimental.nl()
|
||||||
Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(TCP)(GROUP_TCP), link(CHILD)(GROUP_CHILD), link(RETRY)(GROUP_RETRY)nl()
|
Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(TCP)(GROUP_TCP), link(CHILD)(GROUP_CHILD), link(RETRY)(GROUP_RETRY)nl()
|
||||||
Useful options:
|
Useful options:
|
||||||
|
link(socksport)(OPTION_SOCKSPORT),
|
||||||
link(sourceport)(OPTION_SOURCEPORT),
|
link(sourceport)(OPTION_SOURCEPORT),
|
||||||
link(pf)(OPTION_PROTOCOL_FAMILY),
|
link(pf)(OPTION_PROTOCOL_FAMILY),
|
||||||
link(retry)(OPTION_RETRY)nl()
|
link(retry)(OPTION_RETRY)nl()
|
||||||
|
|
13
test.sh
13
test.sh
|
@ -226,7 +226,7 @@ if type ss >/dev/null 2>&1; then
|
||||||
unset SS
|
unset SS
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
[ "$DEFS" ] && echo " NETSTAT=\"$(type netstat)\""
|
[ "$DEFS" ] && echo "NETSTAT=\"$(type netstat 2>/dev/null)\""
|
||||||
|
|
||||||
# for some tests we need a network interface
|
# for some tests we need a network interface
|
||||||
if type ip >/dev/null 2>&1; then
|
if type ip >/dev/null 2>&1; then
|
||||||
|
@ -976,6 +976,8 @@ childprocess () {
|
||||||
|
|
||||||
# return a list of child process pids [killchild]
|
# return a list of child process pids [killchild]
|
||||||
childpids () {
|
childpids () {
|
||||||
|
local recursive i
|
||||||
|
if [ "X$1" = "X-r" ]; then recursive=1; shift; fi
|
||||||
case "$UNAME" in
|
case "$UNAME" in
|
||||||
AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)" |awk '{print($2);}')" ;;
|
AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)" |awk '{print($2);}')" ;;
|
||||||
FreeBSD) l="$(ps -fl |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]*[ ][ ]*$1[ ]" |awk '{print($2);}')" ;;
|
FreeBSD) l="$(ps -fl |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]*[ ][ ]*$1[ ]" |awk '{print($2);}')" ;;
|
||||||
|
@ -992,6 +994,11 @@ childpids () {
|
||||||
if [ -z "$l" ]; then
|
if [ -z "$l" ]; then
|
||||||
return 1;
|
return 1;
|
||||||
fi
|
fi
|
||||||
|
if [ "$recursive" ]; then
|
||||||
|
for i in $l; do
|
||||||
|
l="$l $(childpids -r $i)"
|
||||||
|
done
|
||||||
|
fi
|
||||||
echo "$l"
|
echo "$l"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -18062,7 +18069,9 @@ printf "test $F_n $TEST... " $N
|
||||||
eval $CMD0 >/dev/null 2>"${te}0" &
|
eval $CMD0 >/dev/null 2>"${te}0" &
|
||||||
pid0=$!
|
pid0=$!
|
||||||
sleep 1
|
sleep 1
|
||||||
kill -INT $(childpids $pid0) 2>/dev/null
|
#echo childpids: $(childpids $pid0)
|
||||||
|
#echo childpids -r: $(childpids -r $pid0)
|
||||||
|
kill -INT $(childpids -r $pid0) 2>/dev/null
|
||||||
wait 2>/dev/null
|
wait 2>/dev/null
|
||||||
if grep -q " W waitpid..: child .* exited with status 130" "${te}0"; then
|
if grep -q " W waitpid..: child .* exited with status 130" "${te}0"; then
|
||||||
$PRINTF "$OK\n"
|
$PRINTF "$OK\n"
|
||||||
|
|
49
xio-socks.c
49
xio-socks.c
|
@ -29,12 +29,12 @@ enum {
|
||||||
|
|
||||||
static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
|
static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
|
||||||
|
|
||||||
const struct optdesc opt_socksport = { "socksport", NULL, OPT_SOCKSPORT, GROUP_IP_SOCKS4, PH_LATE, TYPE_STRING, OFUNC_SPEC };
|
const struct optdesc opt_socksport = { "socksport", NULL, OPT_SOCKSPORT, GROUP_IP_SOCKS, PH_LATE, TYPE_STRING, OFUNC_SPEC };
|
||||||
const struct optdesc opt_socksuser = { "socksuser", NULL, OPT_SOCKSUSER, GROUP_IP_SOCKS4, PH_LATE, TYPE_NAME, OFUNC_SPEC };
|
const struct optdesc opt_socksuser = { "socksuser", NULL, OPT_SOCKSUSER, GROUP_IP_SOCKS, PH_LATE, TYPE_NAME, OFUNC_SPEC };
|
||||||
|
|
||||||
const struct addrdesc xioaddr_socks4_connect = { "SOCKS4", 3, xioopen_socks4_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS4|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":<socks-server>:<host>:<port>") };
|
const struct addrdesc xioaddr_socks4_connect = { "SOCKS4", 3, xioopen_socks4_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":<socks-server>:<host>:<port>") };
|
||||||
|
|
||||||
const struct addrdesc xioaddr_socks4a_connect = { "SOCKS4A", 3, xioopen_socks4_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS4|GROUP_CHILD|GROUP_RETRY, 1, 0, 0 HELP(":<socks-server>:<host>:<port>") };
|
const struct addrdesc xioaddr_socks4a_connect = { "SOCKS4A", 3, xioopen_socks4_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, 1, 0, 0 HELP(":<socks-server>:<host>:<port>") };
|
||||||
|
|
||||||
static int xioopen_socks4_connect(
|
static int xioopen_socks4_connect(
|
||||||
int argc,
|
int argc,
|
||||||
|
@ -230,8 +230,31 @@ static int xioopen_socks4_connect(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen) {
|
int _xioopen_opt_socksport(
|
||||||
|
struct opt *opts,
|
||||||
|
char **socksport)
|
||||||
|
{
|
||||||
struct servent *se;
|
struct servent *se;
|
||||||
|
|
||||||
|
if (retropt_string(opts, OPT_SOCKSPORT, socksport) < 0) {
|
||||||
|
if ((se = getservbyname("socks", "tcp")) != NULL) {
|
||||||
|
Debug1("\"socks/tcp\" resolves to %u", ntohs(se->s_port));
|
||||||
|
if ((*socksport = Malloc(6)) == NULL) {
|
||||||
|
return STAT_NORETRY;
|
||||||
|
}
|
||||||
|
sprintf(*socksport, "%u", ntohs(se->s_port));
|
||||||
|
} else {
|
||||||
|
Debug1("cannot resolve service \"socks/tcp\", using %s", SOCKSPORT);
|
||||||
|
if ((*socksport = strdup(SOCKSPORT)) == NULL) {
|
||||||
|
return STAT_NORETRY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen) {
|
||||||
char *userid;
|
char *userid;
|
||||||
|
|
||||||
/* generate socks header - points to final target */
|
/* generate socks header - points to final target */
|
||||||
|
@ -239,20 +262,8 @@ int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **soc
|
||||||
sockhead->action = 1;
|
sockhead->action = 1;
|
||||||
sockhead->port = parseport(targetport, IPPROTO_TCP); /* network byte
|
sockhead->port = parseport(targetport, IPPROTO_TCP); /* network byte
|
||||||
order */
|
order */
|
||||||
|
if (_xioopen_opt_socksport(opts, socksport) < 0) {
|
||||||
if (retropt_string(opts, OPT_SOCKSPORT, socksport) < 0) {
|
return STAT_NORETRY;
|
||||||
if ((se = getservbyname("socks", "tcp")) != NULL) {
|
|
||||||
Debug1("\"socks/tcp\" resolves to %u", ntohs(se->s_port));
|
|
||||||
if ((*socksport = Malloc(6)) == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sprintf(*socksport, "%u", ntohs(se->s_port));
|
|
||||||
} else {
|
|
||||||
Debug1("cannot resolve service \"socks/tcp\", using %s", SOCKSPORT);
|
|
||||||
if ((*socksport = strdup(SOCKSPORT)) == NULL) {
|
|
||||||
errno = ENOMEM; return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retropt_string(opts, OPT_SOCKSUSER, &userid) < 0) {
|
if (retropt_string(opts, OPT_SOCKSUSER, &userid) < 0) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ extern const struct optdesc opt_socksuser;
|
||||||
extern const struct addrdesc xioaddr_socks4_connect;
|
extern const struct addrdesc xioaddr_socks4_connect;
|
||||||
extern const struct addrdesc xioaddr_socks4a_connect;
|
extern const struct addrdesc xioaddr_socks4a_connect;
|
||||||
|
|
||||||
|
extern int _xioopen_opt_socksport(struct opt *opts, char **socksport);
|
||||||
extern int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen);
|
extern int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen);
|
||||||
extern int
|
extern int
|
||||||
_xioopen_socks4_connect0(struct single *xfd,
|
_xioopen_socks4_connect0(struct single *xfd,
|
||||||
|
|
16
xio-socks5.c
16
xio-socks5.c
|
@ -19,6 +19,7 @@
|
||||||
#include "xio-socket.h"
|
#include "xio-socket.h"
|
||||||
#include "xio-ip.h"
|
#include "xio-ip.h"
|
||||||
#include "xio-ipapp.h"
|
#include "xio-ipapp.h"
|
||||||
|
#include "xio-socks.h" /* _xioopen_opt_socksport() */
|
||||||
|
|
||||||
#include "xio-socks5.h"
|
#include "xio-socks5.h"
|
||||||
|
|
||||||
|
@ -50,9 +51,9 @@
|
||||||
|
|
||||||
static int xioopen_socks5(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
|
static int xioopen_socks5(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
|
||||||
|
|
||||||
const struct addrdesc xioaddr_socks5_connect = { "SOCKS5-CONNECT", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_CONNECT, 0, 0 HELP(":<socks-server>:<socks-port>:<target-host>:<target-port>") };
|
const struct addrdesc xioaddr_socks5_connect = { "SOCKS5-CONNECT", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_CONNECT, 0, 0 HELP(":<socks-server>[:<socks-port>]:<target-host>:<target-port>") };
|
||||||
|
|
||||||
const struct addrdesc xioaddr_socks5_listen = { "SOCKS5-LISTEN", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_BIND, 0, 0 HELP(":<socks-server>:<socks-port>:<listen-host>:<listen-port>") };
|
const struct addrdesc xioaddr_socks5_listen = { "SOCKS5-LISTEN", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_BIND, 0, 0 HELP(":<socks-server>[:<socks-port>]:<listen-host>:<listen-port>") };
|
||||||
|
|
||||||
static const char * _xioopen_socks5_strerror(uint8_t r)
|
static const char * _xioopen_socks5_strerror(uint8_t r)
|
||||||
{
|
{
|
||||||
|
@ -521,15 +522,20 @@ static int xioopen_socks5(
|
||||||
Error1("%s: use option --experimental to acknowledge unmature state", argv[0]);
|
Error1("%s: use option --experimental to acknowledge unmature state", argv[0]);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
if (argc != 5) {
|
if (argc < 4 || argc > 5) {
|
||||||
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
|
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
socks_server = argv[1];
|
socks_server = argv[1];
|
||||||
|
if (argc == 5) {
|
||||||
socks_port = argv[2];
|
socks_port = argv[2];
|
||||||
target_name = argv[3];
|
target_name = argv[3];
|
||||||
target_port = argv[4];
|
target_port = argv[4];
|
||||||
|
} else {
|
||||||
|
target_name = argv[2];
|
||||||
|
target_port = argv[3];
|
||||||
|
}
|
||||||
|
|
||||||
if (sfd->howtoend == END_UNSPEC)
|
if (sfd->howtoend == END_UNSPEC)
|
||||||
sfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
|
@ -539,6 +545,10 @@ static int xioopen_socks5(
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
retropt_bool(opts, OPT_FORK, &dofork);
|
retropt_bool(opts, OPT_FORK, &dofork);
|
||||||
|
|
||||||
|
if (_xioopen_opt_socksport(opts, (char **)&socks_port) < 0) {
|
||||||
|
return STAT_NORETRY;
|
||||||
|
}
|
||||||
|
|
||||||
result = _xioopen_ipapp_prepare(opts, &opts0, socks_server, socks_port,
|
result = _xioopen_ipapp_prepare(opts, &opts0, socks_server, socks_port,
|
||||||
&pf, ipproto,
|
&pf, ipproto,
|
||||||
sfd->para.socket.ip.ai_flags,
|
sfd->para.socket.ip.ai_flags,
|
||||||
|
|
|
@ -46,7 +46,7 @@ static const char *addressgroupnames[] = {
|
||||||
"LISTEN", "SHELL", "CHILD", "RETRY",
|
"LISTEN", "SHELL", "CHILD", "RETRY",
|
||||||
"TERMIOS", "RANGE", "PTY", "PARENT",
|
"TERMIOS", "RANGE", "PTY", "PARENT",
|
||||||
"UNIX", "IP4", "IP6", "INTERFACE",
|
"UNIX", "IP4", "IP6", "INTERFACE",
|
||||||
"UDP", "TCP", "SOCKS4", "OPENSSL",
|
"UDP", "TCP", "SOCKS", "OPENSSL",
|
||||||
"PROCESS", "APPL", "HTTP", "undef",
|
"PROCESS", "APPL", "HTTP", "undef",
|
||||||
"POSIXMQ", "SCTP", "DCCP", "UDPLITE"
|
"POSIXMQ", "SCTP", "DCCP", "UDPLITE"
|
||||||
} ;
|
} ;
|
||||||
|
|
|
@ -182,7 +182,7 @@ enum e_func {
|
||||||
|
|
||||||
#define GROUP_IP_UDP 0x01000000 /* not yet used? */
|
#define GROUP_IP_UDP 0x01000000 /* not yet used? */
|
||||||
#define GROUP_IP_TCP 0x02000000
|
#define GROUP_IP_TCP 0x02000000
|
||||||
#define GROUP_IP_SOCKS4 0x04000000
|
#define GROUP_IP_SOCKS 0x04000000 /* for socks4(a), socks5 */
|
||||||
#define GROUP_OPENSSL 0x08000000
|
#define GROUP_OPENSSL 0x08000000
|
||||||
|
|
||||||
#define GROUP_PROCESS 0x10000000 /* a process related option */
|
#define GROUP_PROCESS 0x10000000 /* a process related option */
|
||||||
|
|
Loading…
Reference in a new issue