Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add encryption support #1

Merged
merged 9 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions flutter_rust_bridge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
rust_input: crate::api
rust_root: rust/
dart_output: lib/app/rust
19 changes: 19 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,27 +1,46 @@
PODS:
- Flutter (1.0.0)
- integration_test (0.0.1):
- Flutter
- network_info_plus (0.0.1):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- rust_lib_lan_mouse_mobile (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS

DEPENDENCIES:
- Flutter (from `Flutter`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- network_info_plus (from `.symlinks/plugins/network_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- rust_lib_lan_mouse_mobile (from `.symlinks/plugins/rust_lib_lan_mouse_mobile/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)

EXTERNAL SOURCES:
Flutter:
:path: Flutter
integration_test:
:path: ".symlinks/plugins/integration_test/ios"
network_info_plus:
:path: ".symlinks/plugins/network_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
rust_lib_lan_mouse_mobile:
:path: ".symlinks/plugins/rust_lib_lan_mouse_mobile/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"

SPEC CHECKSUMS:
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573
network_info_plus: 6613d9d7cdeb0e6f366ed4dbe4b3c51c52d567a9
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
rust_lib_lan_mouse_mobile: fc8afa15f8c195a2159ced883a82be086f09bce8
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78

PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796
Expand Down
4 changes: 2 additions & 2 deletions lib/app/models/client.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:convert';

class Client {
final String host;
final int port;
String host;
int port;

Client({required this.host, required this.port});

Expand Down
1 change: 0 additions & 1 deletion lib/app/modules/home/widgets/home_connections.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class _HomeConnectionsState extends State<HomeConnections> {
}

void connectClient(Client client) async {
lanMouseServer.startServer(ignoreIfAlreadyRunning: true);
Navigator.push(
context,
MaterialPageRoute(
Expand Down
79 changes: 48 additions & 31 deletions lib/app/modules/home/widgets/home_general.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,41 @@ class HomeGeneral extends StatefulWidget {

class _HomeGeneralState extends State<HomeGeneral> {
LanMouseServer lanMouseServer = LanMouseServer.instance;
String fingerprint = "";

var portController = TextEditingController();
var hostnameController = TextEditingController();

@override
void initState() {
super.initState();
loadIp();
portController.text = lanMouseServer.defaultClient.port.toString();
hostnameController.text = lanMouseServer.defaultClient.host;
_refreshData();
}

void loadIp() async {
hostnameController.text = lanMouseServer.host;
portController.text = lanMouseServer.port.toString();
void _refreshData() async {
// Load Ip
try {
NetworkInfo network = NetworkInfo();
hostnameController.text = (await network.getWifiIP()) ?? "127.0.0.1";
} catch (e) {
print("NetworkInfoError: $e");
showSnackbar("NetworkInfoError: $e");
}
_syncHostAndPort();
}

void toggleServer(bool isRunning) async {
_syncHostAndPort();
// Load FingerPrint
try {
if (!isRunning) {
await lanMouseServer.startServer();
String? data = await lanMouseServer.getFingerprint();
if (data != null) {
setState(() {
fingerprint = data;
});
} else {
lanMouseServer.stopServer();
showSnackbar("Failed to get fingerprint");
}
} catch (e) {
showSnackbar(e);
showSnackbar("Failed to get fingerprint: $e");
}
_syncHost();
}

void showSnackbar(message) {
Expand All @@ -55,9 +57,9 @@ class _HomeGeneralState extends State<HomeGeneral> {
}
}

void _syncHostAndPort() {
lanMouseServer.host = hostnameController.text;
lanMouseServer.port = int.parse(portController.text);
void _syncHost() {
lanMouseServer.defaultClient.host = hostnameController.text;
lanMouseServer.defaultClient.port = int.parse(portController.text);
}

@override
Expand All @@ -72,17 +74,9 @@ class _HomeGeneralState extends State<HomeGeneral> {
"General",
style: Theme.of(context).textTheme.titleSmall,
),
ValueListenableBuilder<bool>(
valueListenable: lanMouseServer.isSocketRunning,
builder: (context, isRunning, _) {
return IconButton(
onPressed: () => toggleServer(isRunning),
icon: Icon(
Icons.lan,
color: isRunning ? Colors.green : null,
),
);
},
IconButton(
onPressed: _refreshData,
icon: const Icon(Icons.refresh),
),
],
),
Expand Down Expand Up @@ -133,12 +127,35 @@ class _HomeGeneralState extends State<HomeGeneral> {
),
const SizedBox(width: 2),
InkWell(
onTap: loadIp,
child: const Icon(Icons.refresh),
onTap: () {
Clipboard.setData(
ClipboardData(text: hostnameController.text),
);
},
child: const Icon(Icons.copy),
),
],
),
)
),
const Divider(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: ListTile(
minVerticalPadding: 0,
contentPadding: EdgeInsets.zero,
leading: const Icon(Icons.fingerprint),
title: const Text("Certificate Fingerprint"),
subtitle: Text(
fingerprint,
style: Theme.of(context).textTheme.bodySmall,
),
onTap: () {
Clipboard.setData(ClipboardData(text: fingerprint));
showSnackbar("Fingerprint copied to clipboard");
},
),
),
const SizedBox(height: 15),
],
),
)
Expand Down
21 changes: 9 additions & 12 deletions lib/app/modules/server/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@ class _ServerState extends State<Server> {
setState(() {
waitingForAck = true;
});
bool entered = await lanMouseServer.enterClient(client: widget.client);
await lanMouseServer.enterClient(
client: widget.client,
onError: (String err) {
_showErrorDialog(err);
},
);
setState(() {
waitingForAck = false;
});
if (!entered) _showRefreshDialog();
}

@override
Expand All @@ -42,29 +46,22 @@ class _ServerState extends State<Server> {
lanMouseServer.leaveClient();
}

void _showRefreshDialog() {
void _showErrorDialog(String error) {
if (!context.mounted) return;
showAdaptiveDialog(
context: context,
barrierDismissible: false,
builder: (_) {
return AlertDialog.adaptive(
title: const Text("Error"),
content: const Text("Failed to connect to client, please try again"),
content: Text(error),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
enterClient();
},
child: const Text("Retry"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
child: const Text("Cancel"),
child: const Text("Ok"),
)
],
);
Expand Down
39 changes: 39 additions & 0 deletions lib/app/rust/api/lan_mouse_server.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.6.0.

// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import

import '../frb_generated.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';

// These functions are ignored because they are not marked as `pub`: `get_certificate`

Future<(SenderWrapper, ReceiverWrapper)> createChannel() =>
RustLib.instance.api.crateApiLanMouseServerCreateChannel();

/// Start a UdbSocket and create connection with given Client
Stream<Uint8List> connect(
{required String basePath,
required String ipAddr,
required int port,
required String targetAddr,
required int targetPort,
required ReceiverWrapper rx}) =>
RustLib.instance.api.crateApiLanMouseServerConnect(
basePath: basePath,
ipAddr: ipAddr,
port: port,
targetAddr: targetAddr,
targetPort: targetPort,
rx: rx);

Future<String?> getFingerprint({required String path}) =>
RustLib.instance.api.crateApiLanMouseServerGetFingerprint(path: path);

// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<ReceiverWrapper>>
abstract class ReceiverWrapper implements RustOpaqueInterface {}

// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<SenderWrapper>>
abstract class SenderWrapper implements RustOpaqueInterface {
Future<void> send({required List<int> data});
}
Loading