utopic_tor_onion_proxy 0.4.0 copy "utopic_tor_onion_proxy: ^0.4.0" to clipboard
utopic_tor_onion_proxy: ^0.4.0 copied to clipboard

discontinued
PlatformAndroid

Flutter Plugin for Android, based on Android binary that start Tor Onion Proxy on random local socket.

example/lib/main.dart

import 'dart:convert';
import 'dart:io';
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:utopic_tor_onion_proxy/utopic_tor_onion_proxy.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String? _torLocalPort;
  String? _error;
  String? _responseString;
  Socket? _socket;

  Future<void> _startTor() async {
    String? port;
    try {
      port = (await UtopicTorOnionProxy.startTor()).toString();
    } on Exception catch (e) {
      print(e);
      _error = 'Failed to get port';
    }

    if (!mounted) return;
    setState(() {
      _torLocalPort = port;
    });
  }

  Future<void> _stopTor() async {
    try {
      if (await (UtopicTorOnionProxy.stopTor() as FutureOr<bool>)) {
        if (!mounted) return;
        setState(() {
          _torLocalPort = null;
        });
      }
    } on PlatformException catch (e) {
      print(e.message ?? '');
    }
  }

  Future<void> _sendGetRequest(Uri uri) async {
    if (mounted) {
      setState(() {
        _responseString = null;
      });
    }
    _socket?.destroy();

    _socket = await Socket.connect(
      InternetAddress.loopbackIPv4,
      int.tryParse(_torLocalPort!)!,
      timeout: Duration(seconds: 5),
    );
    _socket!.setOption(SocketOption.tcpNoDelay, true);

    _socksConnectionRequest(uri, _socket!);

    List<int> responseIntList = [];

    void onSocketDone() {
      print('socket done');
      if (mounted) {
        setState(() {
          _responseString = String.fromCharCodes(responseIntList);
        });
      }
    }

    _socket!.listen((event) async {
      if (event.length == 8 && event[0] == 0x00 && event[1] == 0x5A) {
        print('Connection open');

        if (uri.scheme == 'https') {
          _socket = await SecureSocket.secure(
            _socket!,
            host: uri.authority,
          );
          _socket!.listen((event) {
            responseIntList.addAll(event);
          }).onDone(onSocketDone);
        }

        var requestString = 'GET ${uri.path} HTTP/1.1\r\n'
            'Host: ${uri.authority}\r\n\r\n';
        _socket!.write(requestString);
        return;
      }
      responseIntList.addAll(event);
    }).onDone(onSocketDone);
  }

  void _socksConnectionRequest(Uri uri, Socket socket) {
    var uriPortBytes = [(uri.port >> 8) & 0xFF, uri.port & 0xFF];
    var uriAuthorityAscii = ascii.encode(uri.authority);

    socket.add([
      0x04, // SOCKS version
      0x01, // request establish a TCP/IP stream connection
      ...uriPortBytes, // 2 bytes destination port
      0x00, // 4 bytes of destination ip
      0x00, // if socks4a and destination ip equals 0.0.0.NonZero
      0x00, // then we can pass destination domen after first 0x00 byte
      0x01,
      0x00,
      ...uriAuthorityAscii, // destination domen
      0x00,
    ]);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Tor Onion Proxy example'),
        ),
        body: LayoutBuilder(
          builder: (context, constrains) {
            return Scrollbar(
              child: SingleChildScrollView(
                child: Container(
                  constraints: BoxConstraints(minHeight: constrains.maxHeight),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      SizedBox(height: 20),
                      Text(
                          'Tor running on: ${_torLocalPort ?? _error ?? 'Unknown'}'),
                      SizedBox(height: 20),
                      Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 16.0),
                        child: Wrap(
                          runSpacing: 20,
                          spacing: 20,
                          children: <Widget>[
                            OutlinedButton(
                              child: Text('Start Tor Onion Proxy'),
                              onPressed:
                                  _torLocalPort == null ? _startTor : null,
                            ),
                            OutlinedButton(
                              child: Text('Stop Tor Onion Proxy'),
                              onPressed:
                                  _torLocalPort != null ? _stopTor : null,
                            ),
                            OutlinedButton(
                              child:
                                  Text('Send request to check.torproject.org'),
                              onPressed: _torLocalPort != null
                                  ? () => _sendGetRequest(
                                      Uri.https('check.torproject.org', '/'))
                                  : null,
                            ),
                          ],
                        ),
                      ),
                      if (_responseString != null)
                        Padding(
                          padding: const EdgeInsets.all(16.0),
                          child: Text('Response: \n\n$_responseString'),
                        ),
                    ],
                  ),
                ),
              ),
            );
          },
        ),
      ),
    );
  }

  @override
  void dispose() {
    _socket!.close();
    super.dispose();
  }
}
15
likes
160
points
10
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter Plugin for Android, based on Android binary that start Tor Onion Proxy on random local socket.

Repository (GitHub)
View/report issues

License

Apache-2.0 (license)

Dependencies

flutter

More

Packages that depend on utopic_tor_onion_proxy

Packages that implement utopic_tor_onion_proxy