import 'dart:convert'; import 'dart:io'; import 'dart:math'; class SecureSocksSession { static const String inboundTag = 'revolt-secure-socks'; static final Random _random = Random.secure(); final int port; final String username; final String password; final String configJson; const SecureSocksSession._({ required this.port, required this.username, required this.password, required this.configJson, }); static Future create(String baseConfig) async { final decoded = jsonDecode(baseConfig); if (decoded is! Map) { throw const FormatException('VLESS configuration must be a JSON object.'); } final reservation = await ServerSocket.bind( InternetAddress.loopbackIPv4, 0, shared: false, ); final port = reservation.port; await reservation.close(); if (port <= 1024 || port > 65535) { throw StateError('Could not allocate a safe local SOCKS5 port.'); } final username = _token(16); final password = _token(32); // ReVolt owns local ingress. Never accept listeners supplied by a remote // or imported Xray config; the client exposes exactly one authenticated // loopback SOCKS5 listener for the current ephemeral session. decoded['inbounds'] = >[ { 'tag': inboundTag, 'port': port, 'listen': '127.0.0.1', 'protocol': 'socks', 'settings': { 'auth': 'password', 'udp': true, 'ip': '127.0.0.1', 'users': >[ {'user': username, 'pass': password}, ], }, 'sniffing': { 'enabled': true, 'destOverride': ['http', 'tls'], }, }, ]; return SecureSocksSession._( port: port, username: username, password: password, configJson: jsonEncode(decoded), ); } static String _token(int byteCount) { final bytes = List.generate(byteCount, (_) => _random.nextInt(256)); return bytes.map((value) => value.toRadixString(16).padLeft(2, '0')).join(); } }