From 7c3c41ae5e3c532f776944c029d241445efaddd8 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Wed, 9 Aug 2023 12:14:37 -0500 Subject: [PATCH] fix v0l/socks5/master/lib/socks5.dart for dart 3 and Android Studio IDE warnings --- lib/networking/socks5.dart | 185 ++++++++++++++++++++----------------- 1 file changed, 100 insertions(+), 85 deletions(-) diff --git a/lib/networking/socks5.dart b/lib/networking/socks5.dart index df4ecee1e..72591f6d0 100644 --- a/lib/networking/socks5.dart +++ b/lib/networking/socks5.dart @@ -1,4 +1,6 @@ -library socks; +// https://github.com/v0l/socks5 https://pub.dev/packages/socks5 for Dart 3 + +// library socks; import 'dart:async'; import 'dart:convert'; @@ -7,42 +9,44 @@ import 'dart:typed_data'; /// https://tools.ietf.org/html/rfc1928 /// https://tools.ietf.org/html/rfc1929 -/// const SOCKSVersion = 0x05; const RFC1929Version = 0x01; class AuthMethods { - static const NoAuth = const AuthMethods._(0x00); - static const GSSApi = const AuthMethods._(0x01); - static const UsernamePassword = const AuthMethods._(0x02); - static const NoAcceptableMethods = const AuthMethods._(0xFF); + static const NoAuth = AuthMethods._(0x00); + static const GSSApi = AuthMethods._(0x01); + static const UsernamePassword = AuthMethods._(0x02); + static const NoAcceptableMethods = AuthMethods._(0xFF); final int _value; const AuthMethods._(this._value); + @override String toString() { return const { - 0x00: 'AuthMethods.NoAuth', - 0x01: 'AuthMethods.GSSApi', - 0x02: 'AuthMethods.UsernamePassword', - 0xFF: 'AuthMethods.NoAcceptableMethods' - }[_value]; + 0x00: 'AuthMethods.NoAuth', + 0x01: 'AuthMethods.GSSApi', + 0x02: 'AuthMethods.UsernamePassword', + 0xFF: 'AuthMethods.NoAcceptableMethods' + }[_value] ?? + 'Unknown AuthMethod'; } } class SOCKSState { - static const Starting = const SOCKSState._(0x00); - static const Auth = const SOCKSState._(0x01); - static const RequestReady = const SOCKSState._(0x02); - static const Connected = const SOCKSState._(0x03); - static const AuthStarted = const SOCKSState._(0x04); + static const Starting = SOCKSState._(0x00); + static const Auth = SOCKSState._(0x01); + static const RequestReady = SOCKSState._(0x02); + static const Connected = SOCKSState._(0x03); + static const AuthStarted = SOCKSState._(0x04); final int _value; const SOCKSState._(this._value); + @override String toString() { return const [ 'SOCKSState.Starting', @@ -55,59 +59,64 @@ class SOCKSState { } class SOCKSAddressType { - static const IPv4 = const SOCKSAddressType._(0x01); - static const Domain = const SOCKSAddressType._(0x03); - static const IPv6 = const SOCKSAddressType._(0x04); + static const IPv4 = SOCKSAddressType._(0x01); + static const Domain = SOCKSAddressType._(0x03); + static const IPv6 = SOCKSAddressType._(0x04); final int _value; const SOCKSAddressType._(this._value); + @override String toString() { return const [ - null, - 'SOCKSAddressType.IPv4', - null, - 'SOCKSAddressType.Domain', - 'SOCKSAddressType.IPv6', - ][_value]; + null, + 'SOCKSAddressType.IPv4', + null, + 'SOCKSAddressType.Domain', + 'SOCKSAddressType.IPv6', + ][_value] ?? + 'Unknown SOCKSAddressType'; } } class SOCKSCommand { - static const Connect = const SOCKSCommand._(0x01); - static const Bind = const SOCKSCommand._(0x02); - static const UDPAssociate = const SOCKSCommand._(0x03); + static const Connect = SOCKSCommand._(0x01); + static const Bind = SOCKSCommand._(0x02); + static const UDPAssociate = SOCKSCommand._(0x03); final int _value; const SOCKSCommand._(this._value); + @override String toString() { return const [ - null, - 'SOCKSCommand.Connect', - 'SOCKSCommand.Bind', - 'SOCKSCommand.UDPAssociate', - ][_value]; + null, + 'SOCKSCommand.Connect', + 'SOCKSCommand.Bind', + 'SOCKSCommand.UDPAssociate', + ][_value] ?? + 'Unknown SOCKSCommand'; } } class SOCKSReply { - static const Success = const SOCKSReply._(0x00); - static const GeneralFailure = const SOCKSReply._(0x01); - static const ConnectionNotAllowedByRuleset = const SOCKSReply._(0x02); - static const NetworkUnreachable = const SOCKSReply._(0x03); - static const HostUnreachable = const SOCKSReply._(0x04); - static const ConnectionRefused = const SOCKSReply._(0x05); - static const TTLExpired = const SOCKSReply._(0x06); - static const CommandNotSupported = const SOCKSReply._(0x07); - static const AddressTypeNotSupported = const SOCKSReply._(0x08); + static const Success = SOCKSReply._(0x00); + static const GeneralFailure = SOCKSReply._(0x01); + static const ConnectionNotAllowedByRuleset = SOCKSReply._(0x02); + static const NetworkUnreachable = SOCKSReply._(0x03); + static const HostUnreachable = SOCKSReply._(0x04); + static const ConnectionRefused = SOCKSReply._(0x05); + static const TTLExpired = SOCKSReply._(0x06); + static const CommandNotSupported = SOCKSReply._(0x07); + static const AddressTypeNotSupported = SOCKSReply._(0x08); final int _value; const SOCKSReply._(this._value); + @override String toString() { return const [ 'SOCKSReply.Success', @@ -130,13 +139,13 @@ class SOCKSRequest { final Uint8List address; final int port; - String getAddressString() { + String? getAddressString() { if (addressType == SOCKSAddressType.Domain) { - return AsciiDecoder().convert(address); + return const AsciiDecoder().convert(address); } else if (addressType == SOCKSAddressType.IPv4) { return address.join("."); } else if (addressType == SOCKSAddressType.IPv6) { - var ret = List(); + var ret = []; for (var x = 0; x < address.length; x += 2) { ret.add( "${address[x].toRadixString(16).padLeft(2, "0")}${address[x + 1].toRadixString(16).padLeft(2, "0")}"); @@ -147,30 +156,30 @@ class SOCKSRequest { } SOCKSRequest({ - this.command, - this.addressType, - this.address, - this.port, + required this.command, + required this.addressType, + required this.address, + required this.port, }); } class SOCKSSocket { - List _auth; - RawSocket _sock; - SOCKSRequest _request; + late List _auth; + late RawSocket _sock; + late SOCKSRequest _request; - StreamSubscription _sockSub; + late StreamSubscription _sockSub; StreamSubscription get subscription => _sockSub; - SOCKSState _state; + late SOCKSState _state; final StreamController _stateStream = StreamController(); SOCKSState get state => _state; - Stream get stateStream => _stateStream?.stream; + Stream get stateStream => _stateStream.stream; /// For username:password auth - final String username; - final String password; + final String? username; + final String? password; /// Waits for state to change to [SOCKSState.Connected] /// If the connection request returns an error from the @@ -198,21 +207,21 @@ class SOCKSSocket { /// Issue connect command to proxy /// - Future connect(String domain) async { + Future connect(String domain) async { final ds = domain.split(':'); assert(ds.length == 2, "Domain must contain port, example.com:80"); _request = SOCKSRequest( command: SOCKSCommand.Connect, addressType: SOCKSAddressType.Domain, - address: AsciiEncoder().convert(ds[0]).sublist(0, ds[0].length), + address: const AsciiEncoder().convert(ds[0]).sublist(0, ds[0].length), port: int.tryParse(ds[1]) ?? 80, ); await _start(); await _waitForConnect; } - Future connectIp(InternetAddress ip, int port) async { + Future connectIp(InternetAddress ip, int port) async { _request = SOCKSRequest( command: SOCKSCommand.Connect, addressType: ip.type == InternetAddressType.IPv4 @@ -225,14 +234,14 @@ class SOCKSSocket { await _waitForConnect; } - Future close({bool keepOpen = true}) async { + Future close({bool keepOpen = true}) async { await _stateStream.close(); if (!keepOpen) { await _sock.close(); } } - Future _start() async { + Future _start() async { // send auth methods _setState(SOCKSState.Auth); //print(">> Version: 5, AuthMethods: $_auth"); @@ -248,7 +257,7 @@ class SOCKSSocket { { final have = _sock.available(); final data = _sock.read(have); - _handleRead(data); + if (data != null) _handleRead(data); break; } case RawSocketEvent.closed: @@ -256,6 +265,12 @@ class SOCKSSocket { _sockSub.cancel(); break; } + case RawSocketEvent.readClosed: + // TODO: Handle this case. + break; + case RawSocketEvent.write: + // TODO: Handle this case. + break; } }); } @@ -268,9 +283,9 @@ class SOCKSSocket { final data = [ RFC1929Version, uname.length, - ...AsciiEncoder().convert(uname), + ...const AsciiEncoder().convert(uname), password.length, - ...AsciiEncoder().convert(password) + ...const AsciiEncoder().convert(password) ]; //print(">> Sending $username:$password"); @@ -280,14 +295,14 @@ class SOCKSSocket { void _handleRead(Uint8List data) async { if (state == SOCKSState.Auth) { if (data.length == 2) { - final version = data[0]; - final auth = AuthMethods._(data[1]); - + // final version = data[0]; //print("<< Version: $version, Auth: $auth"); + final auth = AuthMethods._(data[1]); if (auth._value == AuthMethods.UsernamePassword._value) { _setState(SOCKSState.AuthStarted); - _sendUsernamePassword(username, password); + _sendUsernamePassword(username ?? '', password ?? ''); + // TODO check that passing an empty string is valid (vs. null previously) } else if (auth._value == AuthMethods.NoAuth._value) { _setState(SOCKSState.RequestReady); _writeRequest(_request); @@ -311,26 +326,26 @@ class SOCKSSocket { } } else if (_state == SOCKSState.RequestReady) { if (data.length >= 10) { - final version = data[0]; final reply = SOCKSReply._(data[1]); //data[2] reserved - final addrType = SOCKSAddressType._(data[3]); - Uint8List addr; - var port = 0; - if (addrType == SOCKSAddressType.Domain) { - final len = data[4]; - addr = data.sublist(5, 5 + len); - port = data[5 + len] << 8 | data[6 + len]; - } else if (addrType == SOCKSAddressType.IPv4) { - addr = data.sublist(5, 9); - port = data[9] << 8 | data[10]; - } else if (addrType == SOCKSAddressType.IPv6) { - addr = data.sublist(5, 21); - port = data[21] << 8 | data[22]; - } + // final version = data[0]; + // final addrType = SOCKSAddressType._(data[3]); + // Uint8List addr; + // var port = 0; + // if (addrType == SOCKSAddressType.Domain) { + // final len = data[4]; + // addr = data.sublist(5, 5 + len); + // port = data[5 + len] << 8 | data[6 + len]; + // } else if (addrType == SOCKSAddressType.IPv4) { + // addr = data.sublist(5, 9); + // port = data[9] << 8 | data[10]; + // } else if (addrType == SOCKSAddressType.IPv6) { + // addr = data.sublist(5, 21); + // port = data[21] << 8 | data[22]; + // } + // print("<< Version: $version, Reply: $reply, AddrType: $addrType, Addr: $addr, Port: $port"); - //print("<< Version: $version, Reply: $reply, AddrType: $addrType, Addr: $addr, Port: $port"); if (reply._value == SOCKSReply.Success._value) { _setState(SOCKSState.Connected); } else {