socks: support unix sockets for socks proxy

Usage:
  curl -x "socks5h://localhost/run/tor/socks" "https://example.com"

Updated runtests.pl to run a socksd server listening on unix socket

Added tests test1467 test1468

Added documentation for proxy command line option and socks proxy
options

Closes #8668
This commit is contained in:
Balakrishnan Balasubramanian 2022-05-19 15:33:22 +02:00 committed by Daniel Stenberg
parent ee52bead4d
commit dfa84a0450
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
12 changed files with 240 additions and 23 deletions

View file

@ -128,6 +128,7 @@ Available substitute variables include:
- `%HTTPTLS6PORT` - IPv6 port number of the HTTP TLS server
- `%HTTPTLSPORT` - Port number of the HTTP TLS server
- `%HTTPUNIXPATH` - Path to the Unix socket of the HTTP server
- `%SOCKSUNIXPATH` - Absolute Path to the Unix socket of the SOCKS server
- `%IMAP6PORT` - IPv6 port number of the IMAP server
- `%IMAPPORT` - Port number of the IMAP server
- `%MQTTPORT` - Port number of the MQTT server

View file

@ -185,7 +185,7 @@ test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 \
test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 \
test1448 test1449 test1450 test1451 test1452 test1453 test1454 test1455 \
test1456 test1457 test1458 test1459 test1460 test1461 test1462 test1463 \
test1464 test1465 test1466 \
test1464 test1465 test1466 test1467 test1468 \
\
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \

59
tests/data/test1467 Normal file
View file

@ -0,0 +1,59 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
SOCKS5
</keywords>
</info>
#
# Server-side
<reply>
<data>
HTTP/1.1 200 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
</data>
</reply>
#
# Client-side
<client>
<features>
proxy
unix-sockets
</features>
<server>
http
socks5unix
</server>
<name>
HTTP GET via SOCKS5 proxy via unix sockets
</name>
<command>
--socks5 localhost%SOCKSUNIXPATH http://%HOSTIP:%HTTPPORT/%TESTNUMBER
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
</verify>
</testcase>

63
tests/data/test1468 Normal file
View file

@ -0,0 +1,63 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
SOCKS5
SOCKS5h
</keywords>
</info>
#
# Server-side
<reply>
<data>
HTTP/1.1 200 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
</data>
</reply>
#
# Client-side
<client>
<features>
proxy
unix-sockets
</features>
<server>
http
socks5unix
</server>
<name>
HTTP GET with host name using SOCKS5h via unix sockets
</name>
<command>
http://this.is.a.host.name:%HTTPPORT/%TESTNUMBER --proxy socks5h://localhost%SOCKSUNIXPATH
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: this.is.a.host.name:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<socks>
atyp 3 => this.is.a.host.name
</socks>
</verify>
</testcase>

View file

@ -162,6 +162,7 @@ my $SMBPORT=$noport; # SMB server port
my $SMBSPORT=$noport; # SMBS server port
my $TELNETPORT=$noport; # TELNET server port with negotiation
my $HTTPUNIXPATH; # HTTP server Unix domain socket path
my $SOCKSUNIXPATH; # socks server Unix domain socket path
my $use_external_proxy = 0;
my $proxy_address;
@ -1435,6 +1436,7 @@ my %protofunc = ('http' => \&verifyhttp,
'tftp' => \&verifyftp,
'ssh' => \&verifyssh,
'socks' => \&verifysocks,
'socks5unix' => \&verifysocks,
'gopher' => \&verifyhttp,
'httptls' => \&verifyhttptls,
'dict' => \&verifyftp,
@ -2379,7 +2381,7 @@ sub runmqttserver {
# Start the socks server
#
sub runsocksserver {
my ($id, $verbose, $ipv6) = @_;
my ($id, $verbose, $ipv6, $is_unix) = @_;
my $ip=$HOSTIP;
my $proto = 'socks';
my $ipvnum = 4;
@ -2411,12 +2413,21 @@ sub runsocksserver {
$logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
# start our socks server, get commands from the FTP cmd file
my $cmd="server/socksd".exe_ext('SRV').
" --port 0 ".
" --pidfile $pidfile".
" --portfile $portfile".
" --backend $HOSTIP".
" --config $FTPDCMD";
my $cmd="";
if($is_unix) {
$cmd="server/socksd".exe_ext('SRV').
" --pidfile $pidfile".
" --unix-socket $SOCKSUNIXPATH".
" --backend $HOSTIP".
" --config $FTPDCMD";
} else {
$cmd="server/socksd".exe_ext('SRV').
" --port 0 ".
" --pidfile $pidfile".
" --portfile $portfile".
" --backend $HOSTIP".
" --config $FTPDCMD";
}
my ($sockspid, $pid2) = startnew($cmd, $pidfile, 30, 0);
if($sockspid <= 0 || !pidexists($sockspid)) {
@ -3337,6 +3348,7 @@ sub checksystem {
logmsg "* Unix socket paths:\n";
if($http_unix) {
logmsg sprintf("* HTTP-Unix:%s\n", $HTTPUNIXPATH);
logmsg sprintf("* Socks-Unix:%s\n", $SOCKSUNIXPATH);
}
}
}
@ -3397,6 +3409,7 @@ sub subVariables {
# server Unix domain socket paths
$$thing =~ s/${prefix}HTTPUNIXPATH/$HTTPUNIXPATH/g;
$$thing =~ s/${prefix}SOCKSUNIXPATH/$SOCKSUNIXPATH/g;
# client IP addresses
$$thing =~ s/${prefix}CLIENT6IP/$CLIENT6IP/g;
@ -5273,6 +5286,16 @@ sub startservers {
$run{'socks'}="$pid $pid2";
}
}
elsif($what eq "socks5unix") {
if(!$run{'socks5unix'}) {
($pid, $pid2) = runsocksserver("2", $verbose, "", "unix");
if($pid <= 0) {
return "failed starting socks5unix server";
}
printf ("* pid socks5unix => %d %d\n", $pid, $pid2) if($verbose);
$run{'socks5unix'}="$pid $pid2";
}
}
elsif($what eq "mqtt" ) {
if(!$run{'mqtt'}) {
($pid, $pid2) = runmqttserver("", $verbose);
@ -5867,6 +5890,7 @@ if ($gdbthis) {
}
$HTTPUNIXPATH = "http$$.sock"; # HTTP server Unix domain socket path
$SOCKSUNIXPATH = $pwd."/socks$$.sock"; # HTTP server Unix domain socket path, absolute path
#######################################################################
# clear and create logging directory: