Closed xAffan closed 3 months ago
You're wrong, prove me otherwise.
Run a tor proxy, connect to it. Try to connect to .onion website. Host lookup fails. This indicates a problem with DNS. The same connection succeeds if you use orbot to VPN the entire flutter app.
here's me using the sample of tor plugin
Launching lib\main.dart on Windows in debug mode...
√ Built build\windows\x64\runner\Debug\main.exe.
Connecting to VM Service at ws://127.0.0.1:50397/ZLWv9PAmtXU=/ws
flutter: NOW: 2024-04-24 04:15:19.796316
flutter: Instance of Tor created!
Starting proxy!
flutter: Done awaiting; tor should be running
flutter: Starting tor took 261 seconds. Proxy running on port 43787
flutter: 192.42.116.199
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: SocketException: Failed host lookup: 'duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion' (OS Error: No such host is known.
, errno = 11001)
#0 _NativeSocket.lookup.<anonymous closure> (dart:io-patch/socket_patch.dart:520:9)
<asynchronous suspension>
#1 SocksTCPClient.connect (package:socks5_proxy/src/client/socks_tcp_client.dart:66:18)
<asynchronous suspension>
#2 SocksTCPClient.assignToHttpClientWithSecureOptions.<anonymous closure> (package:socks5_proxy/src/client/socks_tcp_client.dart:46:40)
<asynchronous suspension>
#3 _ConnectionTarget.connect.<anonymous closure> (dart:_http/http_impl.dart:2490:32)
<asynchronous suspension>
#4 _HttpClient._openUrl.<anonymous closure> (dart:_http/http_impl.dart:2787:15)
<asynchronous suspension>
#5 _MyAppState.build.<anonymous closure> (package:main/main.dart:158:45)
<asynchronous suspension>
CHECK THE NEW TOR PLUGIN SAMPLE.
You're wrong, prove me otherwise.
Hello, I believe you need to pass the hostname to the socks proxy rather than doing DNS resolution before. Not sure if it's possible?
Ok I see the issue now, sorry for ignoring you. I will look into it today.
here's me using the sample of tor plugin ... CHECK THE NEW TOR PLUGIN SAMPLE.
I worked on this tor plugin (Foundation-Devices/tor) and made that example. I'm not sure that the arti which that package uses actually supports .onion addresses. You might want to check with an actual Tor proxy--not arti, which hasn't achieved feature-parity with legacy Tor yet.
This is why Stack Wallet's tor plugin (cypherstack/tor) explicitly does not support .onion addresses until The Tor Project officially announces that arti has achieved parity safely.
But that's not to invalidate any of what you said, just a note that if I were you, I wouldn't try my work without verifying it with an outside and verified working Tor proxy.
here's me using the sample of tor plugin ... CHECK THE NEW TOR PLUGIN SAMPLE.
I worked on this tor plugin (Foundation-Devices/tor) and made that example. I'm not sure that the arti which that package uses actually supports .onion addresses. You might want to check with an actual Tor proxy--not arti, which hasn't achieved feature-parity with legacy Tor yet.
This is why Stack Wallet's tor plugin (cypherstack/tor) explicitly does not support .onion addresses until The Tor Project officially announces that arti has achieved parity safely.
But that's not to invalidate any of what you said, just a note that if I were you, I wouldn't try my work without verifying it with an outside and verified working Tor proxy.
When I originally opened the issue, I used the original tor proxy. Therefore, it is most likely an issue here.
I worked on this tor plugin (Foundation-Devices/tor) and made that example. I'm not sure that the arti which that package uses actually supports .onion addresses. You might want to check with an actual Tor proxy--not arti, which hasn't achieved feature-parity with legacy Tor yet.
I asked Copilot "Does arti support TLD .onion?" and it replied:
[1]: https://blog.torproject.org/arti_119_released/ "" [2]: https://blog.torproject.org/arti_116_released/ "" [3]: https://blog.torproject.org/arti_1_2_0_released/ "" [4]: https://forum.torproject.org/t/arti-1-1-9-is-released-assembling-the-onions/9574 ""
Yes, Arti, the next-generation Tor client written in Rust, does support the .onion
top-level domain (TLD). As of the Arti 1.1.6 release, Arti has working client-side onion service support¹[2]. This means that programs can use Arti to connect to onion services on the Tor network¹[2].
However, it's important to note that this feature was initially not as secure as the equivalent feature in the C tor implementation¹[2]. Therefore, it was disabled by default and had to be manually enabled¹[2].
As of the Arti 1.1.9 release, the support for onion services in Arti has been further developed²[1]. The code needed to publish onion service descriptors, keep them up-to-date with changes and introduction points, receive, decrypt, process, and answer introduction requests, and respond to them by delivering traffic to local ports is now available²[1].
In the Arti 1.2.0 release, trying out onion services was expected to be a smoother experience³[3]. Please check the latest documentation for the most up-to-date information.
Source: Conversation with Bing, 4/25/2024 (1) Arti 1.1.6 is released: Now you can connect* to Onion Services!. https://blog.torproject.org/arti_116_released/. (2) Arti 1.1.9 is released: Assembling the onions | Tor Project. https://blog.torproject.org/arti_119_released/. (3) Arti 1.2.0 is released: onion services development | Tor Project. https://blog.torproject.org/arti_1_2_0_released/. (4) Arti 1.1.9 is released: Assembling the onions. https://forum.torproject.org/t/arti-1-1-9-is-released-assembling-the-onions/9574.
1 SocksTCPClient.connect (package:socks5_proxy/src/client/socks_tcp_client.dart:66:18)
2 SocksTCPClient.assignToHttpClientWithSecureOptions. (package:socks5_proxy/src/client/socks_tcp_client.dart:46:40)
3 _ConnectionTarget.connect. (dart:_http/http_impl.dart:2490:32)
4 _HttpClient._openUrl. (dart:_http/http_impl.dart:2787:15)
5 _MyAppState.build. (package:main/main.dart:158:45)
I got stuck in this too. SocksTCPClient.connect
tries to DNS lookup an .onion domain name. It shall let Tor router do it instead of DNS lookup by itself, which is mentioned in Tor Project: FAQ.
Why can't you resolve domain name before SocksTCPClient.connect
?
Can you write some example code so it's easier for me to understand the problem.
Why can't you resolve domain name before
SocksTCPClient.connect
? Can you write some example code so it's easier for me to understand the problem.
Normal DNS servers such as 1.1.1.1/8.8.8.8 or your ISP's DNS servers do not know about any .onion hosts. Therefore, the hostname must be forwarded to the tor proxy so that the proxy itself can resolve those hosts using its own DNS servers.
If you having problem with client I am unable to see there issue can be but if problem is that server can't resolve dns than:
// Listen to all tcp and udp connections
proxy.connections.listen((connection) async {
print('${connection.address.address}:${connection.port} ==> ${connection.desiredAddress.address}:${connection.desiredPort}');
// Resolve ip address manually.
if (connection.desiredAddress.type == InternetAddressType.unix)
connection.desiredAddress = (await InternetAddress.lookup(connection.desiredAddress.host)).first;
// Apply default handler
await connection.forward();
}).onError(print);
Sorry for not understanding you but I really don't see it.
I'll explain this. There is an onion website (for example duckduckgo) whose address is duckduckgo.onion (just an example - not real).
Now, when we attempt to convert this address to an IP address, it fails because such a domain simply does not exist according to the DNS (Domain Name Server).
This is because .onion addresses can only be resolved by tor not a normal DNS.
Therefore, we must directly forward the domain name as is, so the tor proxy itself can then correctly convert it into an IP address and establish a connection.
An option to use the socks proxy for DNS resolution can be added so normal usage will stay unaffected.
The lookup code you sent is problematic, I believe. Maybe, temporarily commenting it out for testing might get us somewhere.
@LacticWhale Thanks for developing package `socks5_proxy'.
In Tor Project: FAQ, it basically says that the applications that use Tor proxy usually make a mistake to DNS lookup .onion domain name and fail. No DNS servers support TLD .onion. The TLD .onion is specific to Tor network.
In ~/.pub-cache/hosted/pub.dev/socks5_proxy-1.0.4/lib/src/client/socks_tcp_client.dart
, the definition of method SocksTCPClient.connect
is:
/// Connects proxy client to given [proxies] with exit point of [host]\:[port].
static Future<SocksSocket> connect(
List<ProxySettings> proxies,
InternetAddress host,
int port,
) async {
final InternetAddress address;
if(host.type == InternetAddressType.unix)
address = (await InternetAddress.lookup(host.address))[0];
else
address = host;
final client = await SocksSocket.initialize(proxies, address, port, SocksConnectionType.connect);
return client.socket;
}
in which the code line address = (await InternetAddress.lookup(host.address))[0];
tries to DNS lookup. In our case of trying to access an onion server, e.g. https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/
, the code definitely will fail because .onion is not a valid TLD for ordinary DNS servers.
The FAQ suggests us to leave the .onion domain name alone, and let Tor proxy deal with it.
The lookup code you sent is problematic, I believe. Maybe, temporarily commenting it out for testing might get us somewhere.
I've tried commenting it out. It will lead to other problems. Normal website, e.g. https://icanhazip.com/ mentioned in the example of package tor-0.0.3, seems to require the DNS lookup, but I don't know why it is required.
The lookup code you sent is problematic, I believe. Maybe, temporarily commenting it out for testing might get us somewhere.
I've tried commenting it out. It will lead to other problems. Normal website, e.g. https://icanhazip.com/ mentioned in the example of package tor-0.0.3, seems to require the DNS lookup, but I don't know why it is required.
So, in a simple sense, normal websites require DNS lookup, and won't work after forwarding it to the tor proxy? Have you verified if .onion sites work? If so, a suboptimal compromise would be to add a condition to see if the address is .onion, and forward it, if an option like forwardOnion: true is enabled?
I check and it seems like that DNS lookup was absolutely necessary. Pushed a small patch 69f23b8
If it doesn't help open this issue again.
@xAffan
So, in a simple sense, normal websites require DNS lookup, and won't work after forwarding it to the tor proxy?
I asked Copilot yesterday about the difference among SOCKS 4, SOCKS 4a and SOCKS 5.
Copilot said SOCKS 4 only accepts IPv4 address. I guess it's why most applications do DNS lookup first by themselves and then pass the IPv4 address they get from DNS servers to SOCKS 4 proxy.
SOCKS 4a accepts both IPv4 address and domain name.
SOCKS 5 accepts IPv4 address, domain name and IPv6 address. Though we are in the era of SOCKS 5, most applications still do DNS lookup themselves, in spite of the fact that a SOCKS 5 proxy, e.g. Tor proxy, is supposed to be able to deal with DNS lookup.
Have you verified if .onion sites work?
I tried the DuckDuckGo .onion mentioned above, and failed because of a RangeError
being thrown. The call stack where it throws is:
ByteReader.readBytes (~/.pub-cache/hosted/pub.dev/socks5_proxy-1.0.4/lib/src/mixin/byte_reader.dart:33)
<asynchronous gap> (Unknown Source:0)
ByteReader.readUint8 (~/.pub-cache/hosted/pub.dev/socks5_proxy-1.0.4/lib/src/mixin/byte_reader.dart:18)
<asynchronous gap> (Unknown Source:0)
SocksSocket._handleCommandResponse (~/.pub-cache/hosted/pub.dev/socks5_proxy-1.0.4/lib/src/client/socks_client.dart:189)
<asynchronous gap> (Unknown Source:0)
SocksSocket.initialize (~/.pub-cache/hosted/pub.dev/socks5_proxy-1.0.4/lib/src/client/socks_client.dart:74)
<asynchronous gap> (Unknown Source:0)
SocksTCPClient.connect (~/.pub-cache/hosted/pub.dev/socks5_proxy-1.0.4/lib/src/client/socks_tcp_client.dart:70)
<asynchronous gap> (Unknown Source:0)
SocksTCPClient.assignToHttpClientWithSecureOptions.<anonymous closure> (~/.pub-cache/hosted/pub.dev/socks5_proxy-1.0.4/lib/src/client/socks_tcp_client.dart:46)
<asynchronous gap> (Unknown Source:0)
_ConnectionTarget.connect.<anonymous closure> (~/.local/packages/flutter/bin/cache/pkg/sky_engine/lib/_http/http_impl.dart:2490)
<asynchronous gap> (Unknown Source:0)
_HttpClient._openUrl.<anonymous closure> (~/.local/packages/flutter/bin/cache/pkg/sky_engine/lib/_http/http_impl.dart:2787)
<asynchronous gap> (Unknown Source:0)
IOClient.send (~/.pub-cache/hosted/pub.dev/http-1.2.1/lib/src/io_client.dart:117)
<asynchronous gap> (Unknown Source:0)
BaseClient._sendUnstreamed (~/.pub-cache/hosted/pub.dev/http-1.2.1/lib/src/base_client.dart:93)
<asynchronous gap> (Unknown Source:0)
The message of the RangeError
is "_readBytes has fewer bytes than expected." It looks like package socks5_proxy
would check the message or something that is about to be sent to proxy, but I'm not sure.
@LacticWhale
I check and it seems like that DNS lookup was absolutely necessary. Pushed a small patch 69f23b8
If it doesn't help open this issue again.
Thess 3 simple functions can be used to test:
import 'package:http/http.dart';
import 'package:http/io_client.dart';
import 'package:tor/tor.dart';
import 'package:socks_dart/socks_client.dart'; // the socks5_proxy 1.0.5+dev.1
Future<Client> createProxyClient() async {
final httpClient = HttpClient()
..badCertificateCallback = ((X509Certificate cert, String host, int port) {
print('Issuer: ${cert.issuer}\nSubject: ${cert.subject}\nPEM: ${cert.pem}\nHost: $host\nPort: $port');
return true;
});
Tor.init();
final DateTime t1 = DateTime.now();
await Tor.instance.start();
print('It took ${DateTime.now().difference(t1).inSeconds} seconds to connect Tor network.');
SocksTCPClient.assignToHttpClient(httpClient, [
ProxySettings(InternetAddress.loopbackIPv4, Tor.instance.port),
]);
return IOClient(httpClient);
}
Future<void> printIpAddressOfExitNode(Client client) async {
final Response response = await client.get(Uri.parse('https://icanhazip.com/'));
print('STATUS: ${response.statusCode}\nRESPONSE: ${response.body}');
}
Future<void> accessHiddenDuckDuckGo(Client client) async {
final Response response = await client.get(Uri.parse('https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/'));
print('STATUS: ${response.statusCode}\nRESPONSE: ${response.body}');
}
They are to be called like:
final Client client = await createProxyClient();
await printIpAddressOfExitNode(client);
await accessHiddenDuckDuckGo(client);
The patch 69f23b8 will have both functions printIpAddressOfExitNode
and accessHiddenDuckDuckGo
fail because of a RangeError
thrown. The message of the RangeError
is _readBytes has fewer bytes than expected.
. The call stack when it throws is:
ByteReader.readBytes (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/mixin/byte_reader.dart:33)
<asynchronous gap> (Unknown Source:0)
ByteReader.readUint8 (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/mixin/byte_reader.dart:18)
<asynchronous gap> (Unknown Source:0)
SocksSocket._handleCommandResponse (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_client.dart:189)
<asynchronous gap> (Unknown Source:0)
SocksSocket.initialize (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_client.dart:74)
<asynchronous gap> (Unknown Source:0)
SocksTCPClient.connect (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_tcp_client.dart:64)
<asynchronous gap> (Unknown Source:0)
SocksTCPClient.assignToHttpClientWithSecureOptions.<anonymous closure> (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_tcp_client.dart:46)
<asynchronous gap> (Unknown Source:0)
_ConnectionTarget.connect.<anonymous closure> (~/.local/packages/flutter/bin/cache/pkg/sky_engine/lib/_http/http_impl.dart:2490)
<asynchronous gap> (Unknown Source:0)
_HttpClient._openUrl.<anonymous closure> (~/.local/packages/flutter/bin/cache/pkg/sky_engine/lib/_http/http_impl.dart:2787)
<asynchronous gap> (Unknown Source:0)
IOClient.send (~/.pub-cache/hosted/pub.dev/http-1.2.1/lib/src/io_client.dart:117)
<asynchronous gap> (Unknown Source:0)
BaseClient._sendUnstreamed (~/.pub-cache/hosted/pub.dev/http-1.2.1/lib/src/base_client.dart:93)
<asynchronous gap> (Unknown Source:0)
printIpAddressOfExitNode (~/codes/experiments/tor/project1/lib/main.dart:53)
<asynchronous gap> (Unknown Source:0)
main (~/codes/experiments/tor/project1/lib/main.dart:13)
<asynchronous gap> (Unknown Source:0)
@LacticWhale
I check and it seems like that DNS lookup was absolutely necessary. Pushed a small patch 69f23b8
If it doesn't help open this issue again.
Thess 3 simple functions can be used to test:
import 'package:http/http.dart'; import 'package:http/io_client.dart'; import 'package:tor/tor.dart'; import 'package:socks_dart/socks_client.dart'; // the socks5_proxy 1.0.5+dev.1 Future<Client> createProxyClient() async { final httpClient = HttpClient() ..badCertificateCallback = ((X509Certificate cert, String host, int port) { print('Issuer: ${cert.issuer}\nSubject: ${cert.subject}\nPEM: ${cert.pem}\nHost: $host\nPort: $port'); return true; }); Tor.init(); final DateTime t1 = DateTime.now(); await Tor.instance.start(); print('It took ${DateTime.now().difference(t1).inSeconds} seconds to connect Tor network.'); SocksTCPClient.assignToHttpClient(httpClient, [ ProxySettings(InternetAddress.loopbackIPv4, Tor.instance.port), ]); return IOClient(httpClient); } Future<void> printIpAddressOfExitNode(Client client) async { final Response response = await client.get(Uri.parse('https://icanhazip.com/')); print('STATUS: ${response.statusCode}\nRESPONSE: ${response.body}'); } Future<void> accessHiddenDuckDuckGo(Client client) async { final Response response = await client.get(Uri.parse('https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/')); print('STATUS: ${response.statusCode}\nRESPONSE: ${response.body}'); }
They are to be called like:
final Client client = await createProxyClient(); await printIpAddressOfExitNode(client); await accessHiddenDuckDuckGo(client);
The patch 69f23b8 will have both functions
printIpAddressOfExitNode
andaccessHiddenDuckDuckGo
fail because of aRangeError
thrown. The message of theRangeError
is_readBytes has fewer bytes than expected.
. The call stack when it throws is:ByteReader.readBytes (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/mixin/byte_reader.dart:33) <asynchronous gap> (Unknown Source:0) ByteReader.readUint8 (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/mixin/byte_reader.dart:18) <asynchronous gap> (Unknown Source:0) SocksSocket._handleCommandResponse (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_client.dart:189) <asynchronous gap> (Unknown Source:0) SocksSocket.initialize (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_client.dart:74) <asynchronous gap> (Unknown Source:0) SocksTCPClient.connect (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_tcp_client.dart:64) <asynchronous gap> (Unknown Source:0) SocksTCPClient.assignToHttpClientWithSecureOptions.<anonymous closure> (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_tcp_client.dart:46) <asynchronous gap> (Unknown Source:0) _ConnectionTarget.connect.<anonymous closure> (~/.local/packages/flutter/bin/cache/pkg/sky_engine/lib/_http/http_impl.dart:2490) <asynchronous gap> (Unknown Source:0) _HttpClient._openUrl.<anonymous closure> (~/.local/packages/flutter/bin/cache/pkg/sky_engine/lib/_http/http_impl.dart:2787) <asynchronous gap> (Unknown Source:0) IOClient.send (~/.pub-cache/hosted/pub.dev/http-1.2.1/lib/src/io_client.dart:117) <asynchronous gap> (Unknown Source:0) BaseClient._sendUnstreamed (~/.pub-cache/hosted/pub.dev/http-1.2.1/lib/src/base_client.dart:93) <asynchronous gap> (Unknown Source:0) printIpAddressOfExitNode (~/codes/experiments/tor/project1/lib/main.dart:53) <asynchronous gap> (Unknown Source:0) main (~/codes/experiments/tor/project1/lib/main.dart:13) <asynchronous gap> (Unknown Source:0)
Perhaps, the issue must be reopened(?) although the host resolution error is resolved, the range error must be investigated in byte_reader.dart(?)
@xAffan
Perhaps, the issue must be reopened(?) although the host resolution error is resolved, the range error must be investigated in byte_reader.dart(?)
Yes, please reopen it. It looks like only the person who created the issue and the author of the Git repository are able to do that. I cannot find any button in this webpage to reopen this issue.
Re-edit: Before applying the patch 69f23b8, the function printIpAddressOfExitNode
above can run without any problem. The IPv4 address of the exit node will be printed on terminal. After applying the patch, the function fails.
@LacticWhale
I check and it seems like that DNS lookup was absolutely necessary. Pushed a small patch 69f23b8
If it doesn't help open this issue again.
Thess 3 simple functions can be used to test:
import 'package:http/http.dart'; import 'package:http/io_client.dart'; import 'package:tor/tor.dart'; import 'package:socks_dart/socks_client.dart'; // the socks5_proxy 1.0.5+dev.1 Future<Client> createProxyClient() async { final httpClient = HttpClient() ..badCertificateCallback = ((X509Certificate cert, String host, int port) { print('Issuer: ${cert.issuer}\nSubject: ${cert.subject}\nPEM: ${cert.pem}\nHost: $host\nPort: $port'); return true; }); Tor.init(); final DateTime t1 = DateTime.now(); await Tor.instance.start(); print('It took ${DateTime.now().difference(t1).inSeconds} seconds to connect Tor network.'); SocksTCPClient.assignToHttpClient(httpClient, [ ProxySettings(InternetAddress.loopbackIPv4, Tor.instance.port), ]); return IOClient(httpClient); } Future<void> printIpAddressOfExitNode(Client client) async { final Response response = await client.get(Uri.parse('https://icanhazip.com/')); print('STATUS: ${response.statusCode}\nRESPONSE: ${response.body}'); } Future<void> accessHiddenDuckDuckGo(Client client) async { final Response response = await client.get(Uri.parse('https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/')); print('STATUS: ${response.statusCode}\nRESPONSE: ${response.body}'); }
They are to be called like:
final Client client = await createProxyClient(); await printIpAddressOfExitNode(client); await accessHiddenDuckDuckGo(client);
The patch 69f23b8 will have both functions
printIpAddressOfExitNode
andaccessHiddenDuckDuckGo
fail because of aRangeError
thrown. The message of theRangeError
is_readBytes has fewer bytes than expected.
. The call stack when it throws is:ByteReader.readBytes (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/mixin/byte_reader.dart:33) <asynchronous gap> (Unknown Source:0) ByteReader.readUint8 (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/mixin/byte_reader.dart:18) <asynchronous gap> (Unknown Source:0) SocksSocket._handleCommandResponse (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_client.dart:189) <asynchronous gap> (Unknown Source:0) SocksSocket.initialize (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_client.dart:74) <asynchronous gap> (Unknown Source:0) SocksTCPClient.connect (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_tcp_client.dart:64) <asynchronous gap> (Unknown Source:0) SocksTCPClient.assignToHttpClientWithSecureOptions.<anonymous closure> (~/.pub-cache/hosted/pub.dev/socks_dart/lib/src/client/socks_tcp_client.dart:46) <asynchronous gap> (Unknown Source:0) _ConnectionTarget.connect.<anonymous closure> (~/.local/packages/flutter/bin/cache/pkg/sky_engine/lib/_http/http_impl.dart:2490) <asynchronous gap> (Unknown Source:0) _HttpClient._openUrl.<anonymous closure> (~/.local/packages/flutter/bin/cache/pkg/sky_engine/lib/_http/http_impl.dart:2787) <asynchronous gap> (Unknown Source:0) IOClient.send (~/.pub-cache/hosted/pub.dev/http-1.2.1/lib/src/io_client.dart:117) <asynchronous gap> (Unknown Source:0) BaseClient._sendUnstreamed (~/.pub-cache/hosted/pub.dev/http-1.2.1/lib/src/base_client.dart:93) <asynchronous gap> (Unknown Source:0) printIpAddressOfExitNode (~/codes/experiments/tor/project1/lib/main.dart:53) <asynchronous gap> (Unknown Source:0) main (~/codes/experiments/tor/project1/lib/main.dart:13) <asynchronous gap> (Unknown Source:0)
Perhaps, the issue must be reopened(?) although the host resolution error is resolved, the range error must be investigated in byte_reader.dart(?)
I thought about this. Since normal websites are now also throwing a range error as indicated by @nns52k . That must mean there is some kind of oversight introduced that affects all the websites not just .onion ones. This might be an urgent issue since you can't connect to any website anymore (?)
@xAffan
Perhaps, the issue must be reopened(?) although the host resolution error is resolved, the range error must be investigated in byte_reader.dart(?)
Yes, please reopen it. It looks like only the person who created the issue and the author of the Git repository are able to do that. I cannot find any button in this webpage to reopen this issue.
Re-edit: Before applying the patch 69f23b8, the function
printIpAddressOfExitNode
above can run without any problem. The IPv4 address of the exit node will be printed on terminal. After applying the patch, the function fails.
I don't find an option to reopen the issue as well. It seems only the author of the repo is able to open the issue again. I suggest you open a brand new issue with the recent findings
@nns52k
Tor.init();
Have you tried to add await
here. I am not able to set up dev environment.
@nns52k
Tor.init();
Have you tried to add
await
here. I am not able to set up dev environment.
Yes, the result is the same.
What does "not able to set up dev environment" mean? Could you be more specific so I probably can help?
Could you be more specific so I probably can help?
Time. Ok I will go look more closely at problem.
@nns52k @xAffan once this is patched we should PR an example of onion address lookups into the Foundation-Devices/tor example. If you don't want to do it, I will. I'm not directly responsible for that but will review it and it should be merged...
You'll notice I had to write https://github.com/Foundation-Devices/tor/blob/main/lib/socks_socket.dart (spun out into its own package as https://github.com/sneurlax/socks_socket) to get SOCKS over sockets working for eg. electrumx and fulcrum nodes. I want to make sure that class can handle onion address lookups etc., too, so we're ready for when Arti announces security parity for hidden services usage.
@nns52k @xAffan once this is patched we should PR an example of onion address lookups into the Foundation-Devices/tor. If you don't want to do it, I will. I'm not directly responsible for that but will review it and it should be merged...
You'll notice I had to write https://github.com/Foundation-Devices/tor/blob/main/lib/socks_socket.dart (spun out into its own package as https://github.com/sneurlax/socks_socket) to get SOCKS over sockets working for eg. electrumx and fulcrum nodes. I want to make sure that class can handle onion address lookups etc., too, so we're ready for when Arti announces security parity for hidden services usage.
I will make a PR once this is resolved, no worries.
@xAffan ok I tested few things.
RangeError
happene because SOCKS server closed conection before sending response signal which is normal behaviour and will be handled properly in next release.
import 'dart:convert';
import 'dart:io';
import 'package:socks5_proxy/socks_client.dart';
void main() async { // Create HttpClient object final client = HttpClient();
// Assign connection factory SocksTCPClient.assignToHttpClient(client, [ ProxySettings(InternetAddress.loopbackIPv4, 27462), ]);
try { // GET request final request = await client.getUrl(Uri.parse('http://example.onion/')); final response = await request.close(); // Print response print(await utf8.decodeStream(response)); // Close client client.close(); } catch (e, stackTrace) { print(e); print(stackTrace); } finally { client.close(); } }
And in terminal I got:
debug1: channel 2: free: direct-tcpip: listening port 27462 for example.onion port 80, connect from 127.0.0.1 port 63526 to 127.0.0.1 port 27462, nchannels 3 debug1: Connection to port 27462 forwarding to socks port 0 requested. debug1: channel 2: new [dynamic-tcpip] channel 2: open failed: connect failed: Name or service not known
That means client send host as is but server wasn't able to resolve it.
For now you can try to catch RangeError (which is not really good).
I wan't able to run tor proxy but if you could send me server logs after running my example above it whould be really helpful.
@LacticWhale, does the https://github.com/Foundation-Devices/tor example run for you? It should work on every platform and should run a tor proxy for you. You don't have to access it via Flutter, either, it's generally accessible at localhost:port for the whole system
@sneurlax it doesn't run without flutter and it doesn't run with flutter either. Maybe I am not doing somethin wrong but it always stuck at "Starting tor..." dialog.
@sneurlax it doesn't run without flutter and it doesn't run with flutter either. Maybe I am not doing somethin wrong but it always stuck at "Starting tor..." dialog.
It takes a long time to start (at least when i tested it for the first time). And currently there are no progress messages so it seems like it is stuck but it does work at the end
@xAffan ok I tested few things.
RangeError
happene because SOCKS server closed conection before sending response signal which is normal behaviour and will be handled properly in next release.- I run following code using ssh SOCKS5 server:
import 'dart:convert'; import 'dart:io';
import 'package:socks5_proxy/socks_client.dart';
void main() async { // Create HttpClient object final client = HttpClient();
// Assign connection factory SocksTCPClient.assignToHttpClient(client, [ ProxySettings(InternetAddress.loopbackIPv4, 27462), ]);
try { // GET request final request = await client.getUrl(Uri.parse('http://example.onion/')); final response = await request.close(); // Print response print(await utf8.decodeStream(response)); // Close client client.close(); } catch (e, stackTrace) { print(e); print(stackTrace); } finally { client.close(); } }
And in terminal I got:
debug1: channel 2: free: direct-tcpip: listening port 27462 for example.onion port 80, connect from 127.0.0.1 port 63526 to 127.0.0.1 port 27462, nchannels 3 debug1: Connection to port 27462 forwarding to socks port 0 requested. debug1: channel 2: new [dynamic-tcpip] channel 2: open failed: connect failed: Name or service not known
That means client send host as is but server wasn't able to resolve it. For now you can try to catch RangeError (which is not really good). I wan't able to run tor proxy but if you could send me server logs after running my example above it whould be really helpful.
Is this the correct output?
$ curl -x socks5h://localhost:9050 -s https://check.torproject.org/api/ip
{"IsTor":true,"IP":"185.220.100.254"}$
$ dart run
Building package executable...
Built tor_test:tor_test.
Exception: Command handling failed. With error: serverError
#0 SocksSocket._handleCommandResponse (package:socks5_proxy/src/client/socks_client.dart:196:7)
<asynchronous suspension>
#1 SocksSocket.initialize (package:socks5_proxy/src/client/socks_client.dart:74:22)
<asynchronous suspension>
#2 SocksTCPClient.connect (package:socks5_proxy/src/client/socks_tcp_client.dart:64:20)
<asynchronous suspension>
#3 _ConnectionTarget.connect.<anonymous closure>.<anonymous closure> (dart:_http/http_impl.dart:2497:32)
<asynchronous suspension>
#4 _HttpClient._openUrl.<anonymous closure> (dart:_http/http_impl.dart:2787:15)
<asynchronous suspension>
#5 main (file:///home/user/TestD/tor_test/bin/tor_test.dart:17:17)
<asynchronous suspension>
$ cat ./bin/tor_test.dart
import 'dart:convert';
import 'dart:io';
import 'package:socks5_proxy/socks_client.dart';
void main() async {
// Create HttpClient object
final client = HttpClient();
// Assign connection factory
SocksTCPClient.assignToHttpClient(client, [
ProxySettings(InternetAddress.loopbackIPv4, 9050),
]);
try {
// GET request
final request = await client.getUrl(Uri.parse('http://example.onion/'));
final response = await request.close();
// Print response
print(await utf8.decodeStream(response));
// Close client
client.close();
} catch (e, stackTrace) {
print(e);
print(stackTrace);
} finally {
client.close();
}
}
If flutter is needed, I can't test right now
@xAffan ok I tested few things.
RangeError
happene because SOCKS server closed conection before sending response signal which is normal behaviour and will be handled properly in next release.- I run following code using ssh SOCKS5 server:
import 'dart:convert'; import 'dart:io';
import 'package:socks5_proxy/socks_client.dart';
void main() async { // Create HttpClient object final client = HttpClient();
// Assign connection factory SocksTCPClient.assignToHttpClient(client, [ ProxySettings(InternetAddress.loopbackIPv4, 27462), ]);
try { // GET request final request = await client.getUrl(Uri.parse('http://example.onion/')); final response = await request.close(); // Print response print(await utf8.decodeStream(response)); // Close client client.close(); } catch (e, stackTrace) { print(e); print(stackTrace); } finally { client.close(); } }
And in terminal I got:
debug1: channel 2: free: direct-tcpip: listening port 27462 for example.onion port 80, connect from 127.0.0.1 port 63526 to 127.0.0.1 port 27462, nchannels 3 debug1: Connection to port 27462 forwarding to socks port 0 requested. debug1: channel 2: new [dynamic-tcpip] channel 2: open failed: connect failed: Name or service not known
That means client send host as is but server wasn't able to resolve it. For now you can try to catch RangeError (which is not really good). I wan't able to run tor proxy but if you could send me server logs after running my example above it whould be really helpful.
Is this the correct output?
$ curl -x socks5h://localhost:9050 -s https://check.torproject.org/api/ip {"IsTor":true,"IP":"185.220.100.254"}$ $ dart run Building package executable... Built tor_test:tor_test. Exception: Command handling failed. With error: serverError #0 SocksSocket._handleCommandResponse (package:socks5_proxy/src/client/socks_client.dart:196:7) <asynchronous suspension> #1 SocksSocket.initialize (package:socks5_proxy/src/client/socks_client.dart:74:22) <asynchronous suspension> #2 SocksTCPClient.connect (package:socks5_proxy/src/client/socks_tcp_client.dart:64:20) <asynchronous suspension> #3 _ConnectionTarget.connect.<anonymous closure>.<anonymous closure> (dart:_http/http_impl.dart:2497:32) <asynchronous suspension> #4 _HttpClient._openUrl.<anonymous closure> (dart:_http/http_impl.dart:2787:15) <asynchronous suspension> #5 main (file:///home/user/TestD/tor_test/bin/tor_test.dart:17:17) <asynchronous suspension> $ cat ./bin/tor_test.dart import 'dart:convert'; import 'dart:io'; import 'package:socks5_proxy/socks_client.dart'; void main() async { // Create HttpClient object final client = HttpClient(); // Assign connection factory SocksTCPClient.assignToHttpClient(client, [ ProxySettings(InternetAddress.loopbackIPv4, 9050), ]); try { // GET request final request = await client.getUrl(Uri.parse('http://example.onion/')); final response = await request.close(); // Print response print(await utf8.decodeStream(response)); // Close client client.close(); } catch (e, stackTrace) { print(e); print(stackTrace); } finally { client.close(); } }
If flutter is needed, I can't test right now
After replacing with a valid onion address. Example https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/
it actually worked!
I believe it is good.
$ dart run
Building package executable...
Built tor_test:tor_test.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<TITLE>Welcome to web-dal-08!</TITLE>
</HEAD>
<BODY>
<H1>Welcome to web-dal-08!</H1>
This is web-dal-08, a system run by and for the <a href="http://www.torproject.org/">Tor Project</a>.
She does stuff.
What kind of stuff and who our kind sponsors are you might learn on
<a href="http://db.torproject.org/machines.cgi?host=web-dal-08">db.torproject.org</a>.
<P>
<HR NOSHADE />
<FONT size="-1">torproject-admin</FONT>
</BODY>
</HTML>
$
Onion address used: http://check.2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion/
Can I close the issue now? I will add proper exception handling later.
@sneurlax @xAffan
If flutter is needed, I can't test right now
Is it possible to remove flutter from dependency list of package tor? If "yes", CLI programs could use package tor too.
@sneurlax @xAffan
If flutter is needed, I can't test right now
Is it possible to remove flutter from dependency list of package tor? If "yes", CLI programs could use package tor too.
I would recommend making an issue at https://github.com/Foundation-Devices/tor asking for/requesting this feature. I'm not sure if the plugin structure requires flutter (it might)
opened by mistake due to an issue on my local system
socks5 client does not do dns resolution over the socks proxy check socks5h vs socks5.