From 340a7641e62a2bca99ebf09d29a261e5aadcf017 Mon Sep 17 00:00:00 2001 From: Junyuan Feng Date: Tue, 11 Jan 2022 12:19:17 +0800 Subject: [PATCH] Solve ssh connect slow --- lib/data/provider/server.dart | 11 ++++---- lib/data/res/build_data.dart | 3 ++- lib/data/store/private_key.dart | 5 ++++ lib/view/page/private_key/edit.dart | 39 +++++++++++++++++++++++++++-- pubspec.lock | 2 +- pubspec.yaml | 2 +- 6 files changed, 52 insertions(+), 10 deletions(-) diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index 29ebbf7e..98e8364f 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -17,6 +17,7 @@ import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:toolbox/data/model/server/server_status.dart'; import 'package:toolbox/data/model/server/snippet.dart'; import 'package:toolbox/data/model/server/tcp_status.dart'; +import 'package:toolbox/data/store/private_key.dart'; import 'package:toolbox/data/store/server.dart'; import 'package:toolbox/data/store/setting.dart'; import 'package:toolbox/locator.dart'; @@ -24,8 +25,8 @@ import 'package:toolbox/locator.dart'; /// Must put this func out of any Class. /// Because of this function is called by [compute] in [ServerProvider.genClient]. /// https://stackoverflow.com/questions/51998995/invalid-arguments-illegal-argument-in-isolate-message-object-is-a-closure -List loadIndentity(Map auth) { - return SSHKeyPair.fromPem(auth['privateKey'], auth['passphrase']); +List loadIndentity(String key) { + return SSHKeyPair.fromPem(key); } class ServerProvider extends BusyProvider { @@ -73,14 +74,14 @@ class ServerProvider extends BusyProvider { Future genClient(ServerPrivateInfo spi) async { final socket = await SSHSocket.connect(spi.ip, spi.port); - if (spi.authorization is String) { + if (spi.pubKeyId == null) { return SSHClient(socket, username: spi.user, onPasswordRequest: () => spi.authorization as String); } - final auth = spi.authorization as Map; + final key = locator().get(spi.pubKeyId!); return SSHClient(socket, - username: spi.user, identities: await compute(loadIndentity, auth)); + username: spi.user, identities: await compute(loadIndentity, key.privateKey)); } Future refreshData({int? idx}) async { diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 38bbc329..bee4b8f5 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -3,7 +3,8 @@ class BuildData { static const String name = "ToolBox"; static const int build = 79; - static const String engine = "Flutter 2.8.1 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 77d935af4d (4 weeks ago) • 2021-12-16 08:37:33 -0800\nEngine • revision 890a5fca2e\nTools • Dart 2.15.1\n"; + static const String engine = + "Flutter 2.8.1 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 77d935af4d (4 weeks ago) • 2021-12-16 08:37:33 -0800\nEngine • revision 890a5fca2e\nTools • Dart 2.15.1\n"; static const String buildAt = "2022-01-10 16:04:12.547744"; static const int modifications = 0; } diff --git a/lib/data/store/private_key.dart b/lib/data/store/private_key.dart index bd35daf5..40e1a4e9 100644 --- a/lib/data/store/private_key.dart +++ b/lib/data/store/private_key.dart @@ -15,6 +15,11 @@ class PrivateKeyStore extends PersistentStore { json.decode(box.get('key', defaultValue: '[]')!)); } + PrivateKeyInfo get(String id) { + final ss = fetch(); + return ss.firstWhere((e) => e.id == id); + } + void delete(PrivateKeyInfo s) { final ss = fetch(); ss.removeAt(index(s)); diff --git a/lib/view/page/private_key/edit.dart b/lib/view/page/private_key/edit.dart index ddd7b3c0..9061eb00 100644 --- a/lib/view/page/private_key/edit.dart +++ b/lib/view/page/private_key/edit.dart @@ -1,4 +1,6 @@ import 'package:after_layout/after_layout.dart'; +import 'package:dartssh2/dartssh2.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:toolbox/core/utils.dart'; import 'package:toolbox/data/model/server/private_key_info.dart'; @@ -22,11 +24,13 @@ class _PrivateKeyEditPageState extends State final pwdController = TextEditingController(); late PrivateKeyProvider _provider; + late Widget loading; @override void initState() { super.initState(); _provider = locator(); + loading = const SizedBox(); } @override @@ -66,11 +70,13 @@ class _PrivateKeyEditPageState extends State obscureText: true, decoration: buildDecoration('Password', icon: Icons.password), ), + SizedBox(height: MediaQuery.of(context).size.height * 0.1), + loading ], ), floatingActionButton: FloatingActionButton( - child: const Icon(Icons.send), - onPressed: () { + child: const Icon(Icons.save), + onPressed: () async { final name = nameController.text; final key = keyController.text; final pwd = pwdController.text; @@ -79,7 +85,28 @@ class _PrivateKeyEditPageState extends State context, const Text('Three fields must not be empty.')); return; } + FocusScope.of(context).unfocus(); + setState(() { + loading = const SizedBox( + height: 50, + child: Center( + child: CircularProgressIndicator(), + ), + ); + }); final info = PrivateKeyInfo(name, key, pwd); + bool haveErr = false; + try { + info.privateKey = await compute(decyptPem, [key, pwd]); + } catch (e) { + showSnackBar(context, Text(e.toString())); + haveErr = true; + } finally { + setState(() { + loading = const SizedBox(); + }); + } + if (haveErr) return; if (widget.info != null) { _provider.updateInfo(widget.info!, info); } else { @@ -100,3 +127,11 @@ class _PrivateKeyEditPageState extends State } } } + +/// [args] : [key, pwd] +String decyptPem(List args) { + /// skip when the key is not encrypted, or will throw exception + if (!SSHKeyPair.isEncryptedPem(args[0])) return args[0]; + final sshKey = SSHKeyPair.fromPem(args[0], args[1]); + return sshKey.first.toPem(); +} diff --git a/pubspec.lock b/pubspec.lock index ed076e24..76c7576d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -123,7 +123,7 @@ packages: name: dartssh2 url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-pre" + version: "2.2.0" dio: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index d1f59c4b..b79f8ef1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,7 +42,7 @@ dependencies: git: url: https://github.com/Countly/countly-sdk-flutter-bridge.git ref: master - dartssh2: ^2.1.0-pre + dartssh2: ^2.2.0 logging: ^1.0.2 flutter_material_color_picker: ^1.1.0+2 circle_chart: